1220 lines
28 KiB
C++
1220 lines
28 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
|
** Contact: http://www.qt-project.org/legal
|
|
**
|
|
** This file is part of the examples of the Qt Toolkit.
|
|
**
|
|
** $QT_BEGIN_LICENSE:BSD$
|
|
** You may use this file under the terms of the BSD license as follows:
|
|
**
|
|
** "Redistribution and use in source and binary forms, with or without
|
|
** modification, are permitted provided that the following conditions are
|
|
** met:
|
|
** * Redistributions of source code must retain the above copyright
|
|
** notice, this list of conditions and the following disclaimer.
|
|
** * Redistributions in binary form must reproduce the above copyright
|
|
** notice, this list of conditions and the following disclaimer in
|
|
** the documentation and/or other materials provided with the
|
|
** distribution.
|
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
|
** of its contributors may be used to endorse or promote products derived
|
|
** from this software without specific prior written permission.
|
|
**
|
|
**
|
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include "qvideowidget.h"
|
|
#include <QPainter>
|
|
#include <QPaintEngine>
|
|
#include <QOpenGLShaderProgram>
|
|
#include <QOpenGLTexture>
|
|
#include <QCoreApplication>
|
|
#include <math.h>
|
|
#include <QPainterPath>
|
|
|
|
#include <QOpenGLPixelTransferOptions>
|
|
#include <QFrame>
|
|
|
|
#include "mainwindow.h"
|
|
|
|
|
|
#include "qvideoshader.h"
|
|
|
|
#include "qgstreamerplayer.h"
|
|
|
|
|
|
QVideoWidget::QVideoWidget(QWidget* parent, Qt::WindowFlags f):QOpenGLWidget(parent, f),
|
|
m_bCheckFrameUpdateCount(true),
|
|
m_nUpdateFrameCount(0),
|
|
m_transparent(false),
|
|
m_btn(0),
|
|
m_hasButton(NULL),
|
|
m_background(QColor(0, 0, 0))
|
|
{
|
|
setMinimumSize(320, 180);
|
|
|
|
// m_listRectObject.push_back(QRect(100, 100, 200, 200));
|
|
|
|
m_nCountQueue = 5;
|
|
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
int nVideoWidth = pCommonData->GetVideoWidth();
|
|
int nVideoHeight = pCommonData->GetVideoHeight();
|
|
|
|
int i=0;
|
|
for(i=0 ; i<m_nCountQueue ; i++)
|
|
{
|
|
uint8_t* pData = new uint8_t[nVideoWidth*nVideoHeight*4];
|
|
m_QueueData.push_back(pData);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//m_bViewThumbnail = false;
|
|
|
|
|
|
m_nTextureWidth = nVideoWidth;
|
|
m_nTextureHeight = nVideoHeight;
|
|
|
|
|
|
m_bTestSaveMode = false;
|
|
m_pidChild = 0;
|
|
m_pData = new uint8_t[m_nTextureWidth*m_nTextureHeight*4];
|
|
m_bChange = false;
|
|
|
|
m_pVideoShader = NULL;
|
|
|
|
m_bFullScreen = false;
|
|
|
|
|
|
Init();
|
|
|
|
//m_pThreadThumbnail = new QThreadThumbnail;
|
|
//m_pThreadThumbnail->start();
|
|
//QObject::connect(m_pThreadThumbnail, SIGNAL(CreatedThumbnail(QString)), this, SLOT(CreatedThumbnail(QString)));
|
|
|
|
}
|
|
|
|
QVideoWidget::~QVideoWidget()
|
|
{
|
|
// And now release all OpenGL resources.
|
|
makeCurrent();
|
|
|
|
if(m_pVideoShader!=NULL)
|
|
{
|
|
delete m_pVideoShader;
|
|
m_pVideoShader = NULL;
|
|
}
|
|
|
|
ResetThumbnailTexture();
|
|
|
|
|
|
m_VBOVideo.destroy();
|
|
doneCurrent();
|
|
|
|
SAFE_ARRAY_DELETE(m_pData);
|
|
|
|
int i=0;
|
|
for(i=0 ; i<m_QueueData.size() ; i++)
|
|
{
|
|
uint8_t* pData = m_QueueData[i];
|
|
SAFE_ARRAY_DELETE(pData);
|
|
}
|
|
m_QueueData.clear();
|
|
}
|
|
|
|
void QVideoWidget::SetButton(QPushButton* pButton)
|
|
{
|
|
m_btn = pButton;
|
|
}
|
|
|
|
void QVideoWidget::CreatedThumbnail(QString strFilenameThumbnail)
|
|
{
|
|
/*
|
|
m_pThumbnail->AddThumbnail(strFilenameThumbnail);
|
|
|
|
m_bCapturing = false;
|
|
m_pMenu->SetCapture(m_bCapturing);
|
|
*/
|
|
}
|
|
|
|
void QVideoWidget::ReceivedSaveBitmap()
|
|
{
|
|
SendSaveBitmap();
|
|
}
|
|
|
|
void QVideoWidget::ReceivedRecord(bool bRecord)
|
|
{
|
|
SendRecord(bRecord);
|
|
}
|
|
|
|
void QVideoWidget::ReceivedViewThumbnail(bool bView)
|
|
{
|
|
/*
|
|
if(bView==true && m_bViewThumbnail==false)
|
|
{
|
|
m_StartTime = QTime::currentTime();
|
|
m_StartTime.start();
|
|
|
|
m_pThumbnail->StartAnimation();
|
|
}
|
|
else if(bView==false && m_bViewThumbnail==true)
|
|
{
|
|
m_StartTime = QTime::currentTime();
|
|
m_StartTime.start();
|
|
}
|
|
|
|
m_bViewThumbnail = bView;
|
|
*/
|
|
}
|
|
|
|
void QVideoWidget::paintTexturedCube()
|
|
{
|
|
|
|
if(m_pData!=NULL)
|
|
{
|
|
bool bInit = m_bInitDisplay;
|
|
UpdateTexture();
|
|
if(bInit==false)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_pVideoShader->EnableAttributeArray();
|
|
|
|
m_VBOVideo.bind();
|
|
// In the buffer we first have 36 vertices (3 floats for each), then 36 texture
|
|
// coordinates (2 floats for each), then 36 normals (3 floats for each).
|
|
m_pVideoShader->SetAttributeBuffer();
|
|
|
|
|
|
|
|
|
|
m_pVideoShader->BindTexture();
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
|
|
|
|
m_pVideoShader->ReleaseTexture();
|
|
|
|
m_VBOVideo.release();
|
|
|
|
|
|
m_pVideoShader->DisableAttributeArray();
|
|
|
|
}
|
|
|
|
void QVideoWidget::initializeGL()
|
|
{
|
|
int i=0;
|
|
QOpenGLContext * pCurrent = QOpenGLContext::currentContext();
|
|
|
|
if(pCurrent!=NULL)
|
|
{
|
|
if(pCurrent->isOpenGLES())
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
initializeOpenGLFunctions();
|
|
|
|
setUpdateBehavior(QOpenGLWidget::NoPartialUpdate);
|
|
|
|
GLuint nFrameBufferObject = defaultFramebufferObject();
|
|
|
|
for(i=0 ; i<18 ; i++)
|
|
{
|
|
m_fNormalRect[i] = -1;
|
|
}
|
|
|
|
GLfloat afTexCoord[] = {
|
|
0.0f,1.0f, 1.0f,1.0f, 0.0f,0.0f,
|
|
1.0f,0.0f, 0.0f,0.0f, 1.0f,1.0f
|
|
};
|
|
|
|
memcpy(m_fNormalRectTexture, afTexCoord, sizeof(GLfloat)*2*6);
|
|
|
|
m_nTmpDisplayType = 0;
|
|
|
|
QSize nSize = size();
|
|
m_nTextureWidth = nSize.width();
|
|
m_nTextureHeight = nSize.height();
|
|
|
|
int nWidth = m_nTextureWidth;
|
|
int nHeight = m_nTextureHeight;
|
|
|
|
|
|
|
|
m_pVideoShader = new QVideoShader;
|
|
//m_pVideoShader->CreateTexture(nWidth, nHeight, QOpenGLTexture::Target2D, QOpenGLTexture::RGB8_UNorm);
|
|
//m_pVideoShader->CreateTexture(nWidth, nHeight, QOpenGLTexture::Target2D, QOpenGLTexture::RG8_UNorm);
|
|
m_pVideoShader->CreateTexture(nWidth*2, nHeight, QOpenGLTexture::Target2D, QOpenGLTexture::R8_UNorm);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//m_pThumbnailTexture = new QOpenGLTexture(image);
|
|
|
|
|
|
char *pSrcVertex =
|
|
"#version 300 es\n"
|
|
"attribute highp vec4 vertex;\n"
|
|
"attribute highp vec4 texCoord;\n"
|
|
"uniform mediump mat4 matrix;\n"
|
|
"varying highp vec4 texc;\n"
|
|
"void main(void)\n"
|
|
"{\n"
|
|
" gl_Position = matrix * vertex;\n"
|
|
" texc = texCoord;\n"
|
|
"}\n";
|
|
|
|
|
|
char *pSrcFragmentCaptureEnvent =
|
|
"#version 300 es\n"
|
|
"in highp vec4 texc;\n"
|
|
"uniform sampler2D tex;\n"
|
|
"out lowp vec4 FragColor;\n"
|
|
"uniform lowp int nImageWidth;\n"
|
|
"uniform lowp int nImageHeight;\n"
|
|
"void main(void)\n"
|
|
"{\n"
|
|
" int nX=0;\n"
|
|
" int nY=0;\n"
|
|
" int nIndex=0;\n"
|
|
" highp float fX = 0.0;\n"
|
|
" highp float fY = 0.0;\n"
|
|
" int nInternalIndex = 0;\n"
|
|
" highp float fImageWidth = float(nImageWidth);\n"
|
|
" highp float fImageHeight = float(nImageHeight);\n"
|
|
" fX = floor(texc.s*(fImageWidth));\n"
|
|
" fY = floor(texc.t*fImageHeight);\n"
|
|
" nX = int(fX);\n"
|
|
" nY = int(fY);\n"
|
|
" int nStartX = int((int(nX/4)) * 4);\n"
|
|
" int nIndexY = nStartX + 1 + int(mod(float(nX/2), 2.0)) * 2;\n"
|
|
" int nIndexU = nStartX+0;\n"
|
|
" int nIndexV = nStartX+2;\n"
|
|
//" if(nX<4) { FragColor = vec4(0.0, 0.0, 0.0, 1.0); return; }\n"
|
|
" fX = float((nX/2)*2+1)/(fImageWidth);\n"
|
|
" fY = float(nY)/(fImageHeight);\n"
|
|
" highp vec4 colorY = texture2D(tex, vec2(float(nIndexY)/(fImageWidth)+0.5/fImageWidth,fY+0.5/fImageHeight));\n"
|
|
" highp vec4 colorU = texture2D(tex, vec2(float(nIndexU)/(fImageWidth)+0.5/fImageWidth,fY+0.5/fImageHeight));\n"
|
|
" highp vec4 colorV = texture2D(tex, vec2(float(nIndexV)/(fImageWidth)+0.5/fImageWidth,fY+0.5/fImageHeight));\n"
|
|
" highp float fColorY = colorY.r;\n"
|
|
" highp float fColorU = colorU.r;\n"
|
|
" highp float fColorV = colorV.r;\n"
|
|
//" FragColor = vec4(fColorY, fColorU, fColorV, 1.0); return;\n"
|
|
|
|
|
|
" highp float fR = fColorY;\n"
|
|
" highp float fG = fColorY;\n"
|
|
" highp float fB = fColorY;\n"
|
|
|
|
" fColorY=1.1643*(fColorY-0.0625);"
|
|
" fColorU=fColorU-0.5;"
|
|
" fColorV=fColorV-0.5;"
|
|
|
|
" fR=clamp(fColorY+1.5958*fColorV, 0.0, 1.0);"
|
|
" fG=clamp(fColorY-0.39173*fColorU-0.81290*fColorV, 0.0, 1.0);"
|
|
" fB=clamp(fColorY+2.017*fColorU, 0.0, 1.0);"
|
|
|
|
" FragColor = vec4(fR, fG, fB, 1.0);\n"
|
|
" highp float fTmpColor = colorU\.r;\n"
|
|
//" FragColor = vec4(fTmpColor, fTmpColor, fTmpColor, 1.0);\n"
|
|
|
|
"}\n";
|
|
|
|
m_pVideoShader->CreateShader((const char*)pSrcVertex, (const char*)pSrcFragmentCaptureEnvent);
|
|
m_pVideoShader->CreateGeometry();
|
|
|
|
if (!m_VBOVideo.isCreated()) {
|
|
//float fRatioWidth = 1572.0f/1920.0f;
|
|
float fRatioWidth = 1.0;
|
|
GLfloat afVertices[] = {
|
|
-1, -fRatioWidth, -1,
|
|
1,-fRatioWidth,-1,
|
|
|
|
-1,fRatioWidth,-1,
|
|
1, fRatioWidth,-1,
|
|
|
|
-1,fRatioWidth,-1,
|
|
1,-fRatioWidth,-1
|
|
};
|
|
|
|
GLfloat afTexCoord[] = {
|
|
0.0f,1.0f, 1.0f,1.0f, 0.0f,0.0f,
|
|
1.0f,0.0f, 0.0f,0.0f, 1.0f,1.0f
|
|
};
|
|
|
|
m_VBOVideo.create();
|
|
m_VBOVideo.bind();
|
|
|
|
m_VBOVideo.allocate(6 * 5 * sizeof(GLfloat));
|
|
m_VBOVideo.write(0, afVertices, 6*3*sizeof(GLfloat));
|
|
m_VBOVideo.write(6*3*sizeof(GLfloat), afTexCoord, 6*2*sizeof(GLfloat));
|
|
|
|
m_VBOVideo.release();
|
|
}
|
|
|
|
/*
|
|
GLfloat afVertices[] = {
|
|
-1,1, -1, -0.767,1,-1, -1,-1,-1,
|
|
-0.767, -1,-1, -1,-1,-1, -0.767,1,-1
|
|
};
|
|
|
|
|
|
|
|
QImage image("desk_blue.jpg");
|
|
//QImage image("desk_blue.png");
|
|
int nImageWidth = image.width();
|
|
int nImageHeight = image.height();
|
|
|
|
QImage image2 = image.convertToFormat(QImage::Format_RGB888);
|
|
|
|
int nBytes = image2.byteCount();
|
|
uint8_t* pImageData = (uint8_t*)image2.bits();
|
|
|
|
memcpy(m_pData, pImageData, nBytes);
|
|
m_bChange = true;
|
|
*/
|
|
UpdateTexture();
|
|
}
|
|
|
|
void QVideoWidget::leaveEvent(QEvent *pEvent)
|
|
{
|
|
|
|
|
|
InitState();
|
|
}
|
|
|
|
void QVideoWidget::mouseDoubleClickEvent(QMouseEvent *)
|
|
{
|
|
return;
|
|
m_bFullScreen = !m_bFullScreen;
|
|
|
|
|
|
QSize sizeParent = ((QFrame*)parent())->size();
|
|
|
|
|
|
|
|
if(m_bFullScreen==true)
|
|
{
|
|
m_rectSmallDisplay = QRect(39, 155, 1103, 621);
|
|
//setGeometry(0, 0, sizeParent.height()*1280.0/1024.0, sizeParent.height());
|
|
setGeometry(0, 0, sizeParent.width(), sizeParent.height());
|
|
}
|
|
else
|
|
{
|
|
setGeometry(m_rectSmallDisplay);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void QVideoWidget::mouseMoveEvent(QMouseEvent *pEvent)
|
|
{
|
|
int nX = pEvent->x();
|
|
int nY = pEvent->y();
|
|
|
|
/*
|
|
if(m_bFullScreen==false)
|
|
{
|
|
m_pThumbnail->CheckRegionSmall(nX, nY);
|
|
}
|
|
else
|
|
{
|
|
m_pThumbnail->CheckRegion(nX, nY);
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
void QVideoWidget::mousePressEvent(QMouseEvent *pEvent)
|
|
{
|
|
int nX = pEvent->x();
|
|
int nY = pEvent->y();
|
|
|
|
if(m_bFullScreen==false)
|
|
{
|
|
//m_pMenu->CheckRegionSmall(nX, nY);
|
|
}
|
|
else
|
|
{
|
|
//m_pMenu->CheckRegion(nX, nY);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
void QVideoWidget::paintGL()
|
|
{
|
|
|
|
bool bChangeTexture = false;
|
|
|
|
m_Lock.lock();
|
|
bChangeTexture = m_bChange;
|
|
m_Lock.unlock();
|
|
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
int nVideoWidth = pCommonData->GetVideoWidth();
|
|
int nVideoHeight = pCommonData->GetVideoHeight();
|
|
|
|
if(bChangeTexture==false)
|
|
{
|
|
//update();
|
|
//usleep(5*1000);
|
|
return;
|
|
//m_pThumbnail->PaintBuffer();
|
|
}
|
|
|
|
//m_MutexPaint.lock();
|
|
|
|
QSize nScreenSize = size();
|
|
|
|
makeCurrent();
|
|
{
|
|
|
|
glViewport(0, 0, nScreenSize.width(), nScreenSize.height()+1);
|
|
QPainter painter;
|
|
//
|
|
painter.begin(this);
|
|
|
|
painter.beginNativePainting();
|
|
|
|
m_transparent = false;
|
|
|
|
glClearColor(m_background.redF(), m_background.greenF(), m_background.blueF(), m_transparent ? 0.0f : 1.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
|
|
|
|
|
m_pVideoShader->Bind();
|
|
m_pVideoShader->SetUniformValue();
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
paintTexturedCube();
|
|
m_pVideoShader->Release();
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glFlush();
|
|
painter.endNativePainting();
|
|
|
|
painter.setRenderHint( QPainter::Antialiasing );
|
|
|
|
QTime dt = QTime::currentTime();
|
|
int nHour = dt.hour();
|
|
int nMinute = dt.minute();
|
|
int nSec = dt.second();
|
|
|
|
|
|
QString strTime = QString("%1:%2:%3").arg(QString::number(nHour, 10).rightJustified(2, '0'))
|
|
.arg(QString::number(nMinute, 10).rightJustified(2, '0'))
|
|
.arg(QString::number(nSec, 10).rightJustified(2, '0'));
|
|
|
|
//painter.setFont(QFont("Roboto", 32, QFont::Bold));
|
|
//painter.setBrush(QBrush(QColor(255, 255, 255, 255)));
|
|
//painter.drawText(nScreenSize.width()-200, 10, 180, 70, (Qt::AlignVCenter | Qt::AlignLeft), strTime);
|
|
|
|
|
|
QPainterPath path;
|
|
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
|
|
if(pCommonData->GetCropMode()==false)
|
|
{
|
|
path.addText(nScreenSize.width()-250, 50, QFont("Roboto", 36), strTime);
|
|
}
|
|
else
|
|
{
|
|
path.addText(nScreenSize.width()-250, 50, QFont("Roboto", 36), strTime);
|
|
}
|
|
|
|
painter.strokePath(path, QPen(Qt::black, 4));
|
|
painter.setPen( Qt::NoPen );
|
|
painter.setBrush( QBrush(QColor(255, 255, 255)) );
|
|
painter.drawPath( path );
|
|
|
|
|
|
/*
|
|
QPainterPath path;
|
|
QPainterPath rawPath;
|
|
rawPath.addEllipse(QRect(0, 0, 200, 200));
|
|
|
|
double const step = 1.0 / double(strTime.length());
|
|
double percent = 0.0;
|
|
for(QChar const& c: strTime)
|
|
{
|
|
double angle = rawPath.angleAtPercent(percent);
|
|
QPointF point = rawPath.pointAtPercent(percent);
|
|
|
|
QTransform mat;
|
|
mat.rotate(-angle);
|
|
QPainterPath p2;
|
|
p2.addText(0, 0, font(), c);
|
|
p2 = mat.map(p2);
|
|
path.addPath(p2.translated(point));
|
|
percent += step;
|
|
}
|
|
painter.drawPath(path.translated(100, 100));
|
|
*/
|
|
|
|
|
|
if(m_listRectObject.size()>0)
|
|
{
|
|
int i=0;
|
|
for(i=0 ; i<m_listRectObject.size() ; i++)
|
|
{
|
|
QRect rectObject = m_listRectObject[i];
|
|
QPen pen;
|
|
float fRatioX = (float)nScreenSize.width() / (float)nVideoWidth;
|
|
float fRatioY = (float)nScreenSize.height() / (float)nVideoHeight;
|
|
|
|
float fX = (float)rectObject.x() * fRatioX;
|
|
float fY = (float)rectObject.y() * fRatioY;
|
|
float fWidth = (float)rectObject.width() *fRatioX;
|
|
float fHeight = (float)rectObject.height() *fRatioY;
|
|
|
|
QRect rectDisplay = QRect(round(fX), round(fY), round(fWidth), round(fHeight));
|
|
|
|
pen.setColor(Qt::green);
|
|
pen.setWidth(4);
|
|
painter.setPen(pen);
|
|
painter.drawRect(rectDisplay);
|
|
|
|
}
|
|
}
|
|
|
|
painter.end();
|
|
|
|
usleep(10);
|
|
|
|
//update();
|
|
}
|
|
|
|
//m_MutexPaint.unlock();
|
|
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
void QVideoWidget::createGeometry()
|
|
{
|
|
m_vertices.clear();
|
|
m_normals.clear();
|
|
|
|
qreal x1 = +0.06f;
|
|
qreal y1 = -0.14f;
|
|
qreal x2 = +0.14f;
|
|
qreal y2 = -0.06f;
|
|
qreal x3 = +0.08f;
|
|
qreal y3 = +0.00f;
|
|
qreal x4 = +0.30f;
|
|
qreal y4 = +0.22f;
|
|
|
|
quad(x1, y1, x2, y2, y2, x2, y1, x1);
|
|
quad(x3, y3, x4, y4, y4, x4, y3, x3);
|
|
|
|
extrude(x1, y1, x2, y2);
|
|
extrude(x2, y2, y2, x2);
|
|
extrude(y2, x2, y1, x1);
|
|
extrude(y1, x1, x1, y1);
|
|
extrude(x3, y3, x4, y4);
|
|
extrude(x4, y4, y4, x4);
|
|
extrude(y4, x4, y3, x3);
|
|
|
|
const qreal Pi = 3.14159f;
|
|
const int NumSectors = 100;
|
|
|
|
for (int i = 0; i < NumSectors; ++i) {
|
|
qreal angle1 = (i * 2 * Pi) / NumSectors;
|
|
qreal x5 = 0.30 * sin(angle1);
|
|
qreal y5 = 0.30 * cos(angle1);
|
|
qreal x6 = 0.20 * sin(angle1);
|
|
qreal y6 = 0.20 * cos(angle1);
|
|
|
|
qreal angle2 = ((i + 1) * 2 * Pi) / NumSectors;
|
|
qreal x7 = 0.20 * sin(angle2);
|
|
qreal y7 = 0.20 * cos(angle2);
|
|
qreal x8 = 0.30 * sin(angle2);
|
|
qreal y8 = 0.30 * cos(angle2);
|
|
|
|
quad(x5, y5, x6, y6, x7, y7, x8, y8);
|
|
|
|
extrude(x6, y6, x7, y7);
|
|
extrude(x8, y8, x5, y5);
|
|
}
|
|
|
|
for (int i = 0;i < m_vertices.size();i++)
|
|
m_vertices[i] *= 2.0f;
|
|
}
|
|
|
|
void QVideoWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
|
|
{
|
|
m_vertices << QVector3D(x1, y1, -0.05f);
|
|
m_vertices << QVector3D(x2, y2, -0.05f);
|
|
m_vertices << QVector3D(x4, y4, -0.05f);
|
|
|
|
m_vertices << QVector3D(x3, y3, -0.05f);
|
|
m_vertices << QVector3D(x4, y4, -0.05f);
|
|
m_vertices << QVector3D(x2, y2, -0.05f);
|
|
|
|
QVector3D n = QVector3D::normal
|
|
(QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
|
|
|
|
m_normals << n;
|
|
m_normals << n;
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
m_normals << n;
|
|
m_normals << n;
|
|
|
|
m_vertices << QVector3D(x4, y4, 0.05f);
|
|
m_vertices << QVector3D(x2, y2, 0.05f);
|
|
m_vertices << QVector3D(x1, y1, 0.05f);
|
|
|
|
m_vertices << QVector3D(x2, y2, 0.05f);
|
|
m_vertices << QVector3D(x4, y4, 0.05f);
|
|
m_vertices << QVector3D(x3, y3, 0.05f);
|
|
|
|
n = QVector3D::normal
|
|
(QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
|
|
|
|
m_normals << n;
|
|
m_normals << n;
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
m_normals << n;
|
|
m_normals << n;
|
|
}
|
|
|
|
void QVideoWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
|
|
{
|
|
m_vertices << QVector3D(x1, y1, +0.05f);
|
|
m_vertices << QVector3D(x2, y2, +0.05f);
|
|
m_vertices << QVector3D(x1, y1, -0.05f);
|
|
|
|
m_vertices << QVector3D(x2, y2, -0.05f);
|
|
m_vertices << QVector3D(x1, y1, -0.05f);
|
|
m_vertices << QVector3D(x2, y2, +0.05f);
|
|
|
|
QVector3D n = QVector3D::normal
|
|
(QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
|
|
|
|
m_normals << n;
|
|
m_normals << n;
|
|
m_normals << n;
|
|
|
|
m_normals << n;
|
|
m_normals << n;
|
|
m_normals << n;
|
|
}
|
|
*/
|
|
|
|
void QVideoWidget::setTransparent(bool transparent)
|
|
{
|
|
setAttribute(Qt::WA_AlwaysStackOnTop, transparent);
|
|
m_transparent = transparent;
|
|
// Call update() on the top-level window after toggling AlwayStackOnTop to make sure
|
|
// the entire backingstore is updated accordingly.
|
|
window()->update();
|
|
}
|
|
|
|
void QVideoWidget::resizeGL(int w, int h)
|
|
{
|
|
QOpenGLWidget::resizeGL(w, h);
|
|
|
|
glViewport(0, 0, w, h);
|
|
}
|
|
|
|
|
|
|
|
void QVideoWidget::UpdateTexture()
|
|
{
|
|
|
|
|
|
if(m_bChange==false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(m_Lock.tryLock(500)==false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_bInitDisplay = true;
|
|
|
|
QOpenGLPixelTransferOptions uploadOptions;
|
|
uploadOptions.setAlignment(1);
|
|
if(m_pData!=NULL)
|
|
{
|
|
QOpenGLTexture* pTexture = m_pVideoShader->GetTexture();
|
|
pTexture->bind();
|
|
if(m_nIndexCurrent>=0)
|
|
{
|
|
if(m_nIndexCurrent>m_nIndexDisplay)
|
|
{
|
|
m_nIndexDisplay++;
|
|
|
|
pTexture->setData(0, QOpenGLTexture::Red, QOpenGLTexture::UInt8, (void*)m_QueueData[m_nIndexDisplay%m_nCountQueue], &uploadOptions);
|
|
|
|
pTexture->generateMipMaps();
|
|
pTexture->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::LinearMipMapLinear);
|
|
|
|
if(m_nIndexCurrent-2>m_nIndexDisplay)
|
|
{
|
|
m_nIndexDisplay = m_nIndexCurrent-1;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
{
|
|
m_bChange = false;
|
|
}
|
|
pTexture->release();
|
|
|
|
if(m_bCheckFrameUpdateCount==true)
|
|
{
|
|
m_nUpdateFrameCount++;
|
|
if(m_TimerFPS.elapsed()>1000)
|
|
{
|
|
//qDebug() << "FPS: " << m_nUpdateFrameCount;
|
|
m_nUpdateFrameCount = 0;
|
|
m_TimerFPS.restart();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
m_Lock.unlock();
|
|
}
|
|
|
|
|
|
QMutex* QVideoWidget::GetMutex()
|
|
{
|
|
return &m_Lock;
|
|
}
|
|
|
|
|
|
void QVideoWidget::SetTextureData(uint8_t* pData, int nSize)
|
|
{
|
|
m_Lock.lock();
|
|
|
|
m_StartTime.restart();
|
|
|
|
|
|
int nQueue = (m_nIndexCurrent+1)%m_nCountQueue;
|
|
|
|
uint8_t* pDataQueue = m_QueueData[nQueue];
|
|
memcpy(pDataQueue, pData, nSize);
|
|
m_nIndexCurrent++;
|
|
|
|
|
|
//YOLOv5 Dataset copy
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
int nVideoWidth = pCommonData->GetVideoWidth();
|
|
int nVideoHeight = pCommonData->GetVideoHeight();
|
|
|
|
if(pCommonData->IsActiveDetect()==true)
|
|
{
|
|
pCommonData->GetThreadCaptureImage()->SetImageDetect(pDataQueue, nVideoWidth, nVideoHeight);
|
|
}
|
|
|
|
|
|
|
|
|
|
m_bChange = true;
|
|
|
|
|
|
|
|
m_Lock.unlock();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
uint8_t* QVideoWidget::GetDataPtr()
|
|
{
|
|
return m_pData;
|
|
}
|
|
|
|
int QVideoWidget::GetTextureWidth()
|
|
{
|
|
return m_nTextureWidth;
|
|
}
|
|
|
|
int QVideoWidget::GetTextureHeight()
|
|
{
|
|
return m_nTextureHeight;
|
|
}
|
|
|
|
void QVideoWidget::SetTextureSize(int nWidth, int nHeight)
|
|
{
|
|
return;
|
|
/*
|
|
if(m_nTextureWidth!=nWidth || m_nTextureHeight!=nHeight)
|
|
{
|
|
m_nTextureWidth = nWidth;
|
|
m_nTextureHeight = nHeight;
|
|
|
|
if(m_pVideoTexture->isStorageAllocated()==true)
|
|
{
|
|
delete m_pVideoTexture;
|
|
//m_pVideoTexture->destroy();
|
|
}
|
|
|
|
m_pVideoTexture->create();
|
|
m_pVideoTexture->setFormat(QOpenGLTexture::R8_UNorm);
|
|
m_pVideoTexture->setSize(nWidth, nHeight*1.5);
|
|
m_pVideoTexture->allocateStorage();
|
|
}
|
|
*/
|
|
}
|
|
|
|
void QVideoWidget::SetSmallDisplay(int nX, int nY, int nWidth, int nHeight)
|
|
{
|
|
m_rectSmallDisplay = QRect(nX, nY, nWidth, nHeight);
|
|
}
|
|
|
|
void QVideoWidget::ResetThumbnailTexture()
|
|
{
|
|
//m_pThumbnail->ResetThumbnailTexture();
|
|
}
|
|
|
|
void QVideoWidget::SaveBitmap(QString strFilename)
|
|
{
|
|
//m_bCapturing = true;
|
|
//m_pMenu->SetCapture(m_bCapturing);
|
|
|
|
//m_pThreadThumbnail->AddThumbnail(m_pData, 1920, 1080, strFilename);
|
|
}
|
|
|
|
float QVideoWidget::MakeNormalize(int nPos, int nRange)
|
|
{
|
|
float fData = 0.0f;
|
|
|
|
//fData = (float)(nPos-nRange/2.0)/(float)(nRange/2.0);
|
|
|
|
fData = (float)nPos/(float)(nRange/2) - 1.0f;
|
|
return fData;
|
|
}
|
|
|
|
void QVideoWidget::MakeRectNormal(const QRect& rect, QSize rectSize)
|
|
{
|
|
float fLeft = MakeNormalize(rect.left(), rectSize.width());
|
|
float fTop = MakeNormalize(rect.top(), rectSize.height()) * -1.0f;
|
|
float fRight = MakeNormalize(rect.right(), rectSize.width());
|
|
float fBottom = MakeNormalize(rect.bottom(), rectSize.height()) * -1.0f;
|
|
//lefttop
|
|
m_fNormalRect[0] = fLeft;
|
|
m_fNormalRect[1] = fBottom;
|
|
|
|
//righttop
|
|
m_fNormalRect[3] = fRight;
|
|
m_fNormalRect[4] = fBottom;
|
|
|
|
//leftbottom
|
|
m_fNormalRect[6] = fLeft;
|
|
m_fNormalRect[7] = fTop;
|
|
|
|
//rightbottom
|
|
m_fNormalRect[9] = fRight;
|
|
m_fNormalRect[10] = fTop;
|
|
|
|
//leftbottom
|
|
m_fNormalRect[12] = fLeft;
|
|
m_fNormalRect[13] = fTop;
|
|
|
|
//righttop
|
|
m_fNormalRect[15] = fRight;
|
|
m_fNormalRect[16] = fBottom;
|
|
}
|
|
|
|
void QVideoWidget::InitState()
|
|
{
|
|
//m_pThumbnail->InitState();
|
|
}
|
|
|
|
void QVideoWidget::DrawRecord()
|
|
{
|
|
/*
|
|
QOpenGLTexture* pTexture = NULL;
|
|
m_pShaderThumbnail->Bind();
|
|
m_pShaderThumbnail->SetUniformValue();
|
|
m_pShaderThumbnail->EnableAttributeArray();
|
|
|
|
|
|
m_VBORecord.bind();
|
|
m_pShaderThumbnail->SetAttributeBuffer();
|
|
m_VBORecord.release();
|
|
|
|
if(m_bRecording==false)
|
|
{
|
|
pTexture = m_pButtonRecord->GetTextureNormal();
|
|
}
|
|
else
|
|
{
|
|
pTexture = m_pButtonRecord->GetTextureClicked();
|
|
}
|
|
|
|
pTexture->bind();
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
pTexture->release();
|
|
|
|
m_pShaderThumbnail->DisableAttributeArray();
|
|
|
|
m_pShaderThumbnail->Release();
|
|
*/
|
|
}
|
|
|
|
void QVideoWidget::DrawCapture()
|
|
{
|
|
/*
|
|
QOpenGLTexture* pTexture = NULL;
|
|
m_pShaderThumbnail->Bind();
|
|
m_pShaderThumbnail->SetUniformValue();
|
|
m_pShaderThumbnail->EnableAttributeArray();
|
|
|
|
|
|
m_VBOCapture.bind();
|
|
m_pShaderThumbnail->SetAttributeBuffer();
|
|
m_VBOCapture.release();
|
|
|
|
if(m_bCapturing==false)
|
|
{
|
|
pTexture = m_pButtonCapture->GetTextureNormal();
|
|
}
|
|
else
|
|
{
|
|
pTexture = m_pButtonCapture->GetTextureClicked();
|
|
}
|
|
|
|
pTexture->bind();
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
pTexture->release();
|
|
|
|
m_pShaderThumbnail->DisableAttributeArray();
|
|
|
|
m_pShaderThumbnail->Release();
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
void QVideoWidget::SetCapturing()
|
|
{
|
|
m_bCapturing = true;
|
|
}
|
|
|
|
uint8_t* QVideoWidget::GetCaptureImage()
|
|
{
|
|
uint8_t* pData = m_QueueData[m_nIndexCurrent%m_nCountQueue];
|
|
return pData;
|
|
}
|
|
|
|
void QVideoWidget::Reset()
|
|
{
|
|
m_nIndexCurrent = 0;
|
|
m_nIndexDisplay = 0;
|
|
|
|
m_bRecording = false;
|
|
m_bCapturing = false;
|
|
|
|
m_bFullScreen = false;
|
|
}
|
|
|
|
void QVideoWidget::SetChangeTexture(bool bUpdate)
|
|
{
|
|
m_bChange = bUpdate;
|
|
m_nIndexCurrent = 0;
|
|
m_nIndexDisplay = 0;
|
|
}
|
|
|
|
void QVideoWidget::Init()
|
|
{
|
|
ClearQueueData();
|
|
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
int nVideoWidth = pCommonData->GetVideoWidth();
|
|
int nVideoHeight = pCommonData->GetVideoHeight();
|
|
|
|
m_nIndexCurrent = 0;
|
|
m_nIndexDisplay = 0;
|
|
|
|
m_bRecording = false;
|
|
m_bCapturing = false;
|
|
|
|
m_bFullScreen = false;
|
|
|
|
memset(m_pData, 0, sizeof(uint8_t)*nVideoWidth*nVideoHeight*4);
|
|
//m_bChange = true;
|
|
|
|
m_bInitDisplay = false;
|
|
|
|
connect(&m_Timer, SIGNAL(timeout()), this, SLOT(Update()));
|
|
|
|
m_StartTime.restart();
|
|
|
|
m_Timer.start(8);
|
|
|
|
m_TimerFPS.restart();
|
|
m_nUpdateFrameCount = 0;
|
|
|
|
|
|
}
|
|
|
|
void QVideoWidget::Exit()
|
|
{
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
int nVideoWidth = pCommonData->GetVideoWidth();
|
|
int nVideoHeight = pCommonData->GetVideoHeight();
|
|
|
|
ClearQueueData();
|
|
|
|
m_nIndexCurrent = 0;
|
|
m_nIndexDisplay = 0;
|
|
|
|
m_bRecording = false;
|
|
m_bCapturing = false;
|
|
|
|
m_bFullScreen = false;
|
|
|
|
memset(m_pData, 0, sizeof(uint8_t)*nVideoWidth*nVideoHeight*4);
|
|
m_bChange = true;
|
|
|
|
m_bInitDisplay = false;
|
|
|
|
disconnect(&m_Timer, SIGNAL(timeout()), this, SLOT(Update()));
|
|
m_Timer.stop();
|
|
}
|
|
|
|
void QVideoWidget::Update()
|
|
{
|
|
update();
|
|
|
|
QGstreamerPlayer* pPlayer = NULL;
|
|
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
|
|
|
|
bool bIsStart = false;
|
|
if(bIsStart==false)
|
|
{
|
|
|
|
pPlayer = pCommonData->GetThreadRTSP()->GetGstreamerPlayer();
|
|
|
|
if(pPlayer==NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(pPlayer->IsPipeStart()==true)
|
|
{
|
|
int nUpdateTextureTime = m_StartTime.elapsed();
|
|
|
|
|
|
if(nUpdateTextureTime>2100)
|
|
{
|
|
int a=0;
|
|
//pPlayer->Alram();
|
|
//pCommonData->GetThreadRTSP()->Restart();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_StartTime.restart();
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void QVideoWidget::UpdateObjectDisplay(vector<QRect>& listRectDisplay)
|
|
{
|
|
m_listRectObject = listRectDisplay;
|
|
}
|
|
|
|
|
|
|
|
bool QVideoWidget::Lock()
|
|
{
|
|
//m_Lock.lock();
|
|
bool bLock = m_Lock.tryLock(100);
|
|
|
|
if(bLock==false)
|
|
{
|
|
int a=0;
|
|
}
|
|
|
|
|
|
return bLock;
|
|
}
|
|
|
|
void QVideoWidget::Unlock()
|
|
{
|
|
m_Lock.unlock();
|
|
}
|
|
|
|
|
|
void QVideoWidget::ClearQueueData()
|
|
{
|
|
CommonData* pCommonData = MainWindow::GetCommonData();
|
|
int nVideoWidth = pCommonData->GetVideoWidth();
|
|
int nVideoHeight = pCommonData->GetVideoHeight();
|
|
|
|
int i=0;
|
|
for(i=0 ; i<m_QueueData.size() ; i++)
|
|
{
|
|
uint8_t* pData = m_QueueData[i];
|
|
memset(pData, 0, sizeof(uint8_t)*nVideoWidth*nVideoHeight*4);
|
|
}
|
|
}
|