确定opengl方案

This commit is contained in:
Barry 2018-10-28 12:41:46 +08:00
parent ff10e0e376
commit 2f17c8416c
5 changed files with 1 additions and 279 deletions

View file

@ -32,7 +32,6 @@ SOURCES += \
decoder.cpp \
server.cpp \
convert.cpp \
glyuvwidget.cpp \
frames.cpp \
yuvglwidget.cpp
@ -42,7 +41,6 @@ HEADERS += \
decoder.h \
server.h \
convert.h \
glyuvwidget.h \
frames.h \
yuvglwidget.h

View file

@ -4,12 +4,8 @@
#include "dialog.h"
#include "ui_dialog.h"
#include "adbprocess.h"
#include "glyuvwidget.h"
#include "yuvglwidget.h"
#define OPENGL_PLAN2
void saveAVFrame_YUV_ToTempFile(const AVFrame *pFrame)
{
int t_frameWidth = pFrame->width;
@ -49,16 +45,9 @@ Dialog::Dialog(QWidget *parent) :
{
ui->setupUi(this);
#ifdef OPENGL_PLAN2
w2 = new YUVGLWidget(this);
w2->resize(ui->imgLabel->size());
w2->move(230, 20);
#else
w = new GLYuvWidget(this);
w->resize(ui->imgLabel->size());
w->move(230, 20);
#endif
Decoder::init();
@ -84,23 +73,11 @@ Dialog::Dialog(QWidget *parent) :
frames.lock();
const AVFrame *frame = frames.consumeRenderedFrame();
//saveAVFrame_YUV_ToTempFile(frame);
#ifdef OPENGL_PLAN2
w2->setFrameSize(frame->width, frame->height);
w2->setYPixels(frame->data[0], frame->linesize[0]);
w2->setUPixels(frame->data[1], frame->linesize[1]);
w2->setVPixels(frame->data[2], frame->linesize[2]);
//w2->update();
w2->repaint();
#else
w->setVideoSize(frame->width, frame->height);
/*
if (!prepare_for_frame(screen, new_frame_size)) {
mutex_unlock(frames->mutex);
return SDL_FALSE;
}
*/
w->updateTexture(frame->data[0], frame->data[1], frame->data[2], frame->linesize[0], frame->linesize[1], frame->linesize[2]);
#endif
w2->update();
frames.unLock();
},Qt::QueuedConnection);

View file

@ -11,7 +11,6 @@ namespace Ui {
class Dialog;
}
class GLYuvWidget;
class YUVGLWidget;
class Dialog : public QDialog
{
@ -33,7 +32,6 @@ private:
Server* server;
Decoder decoder;
Frames frames;
GLYuvWidget* w;
YUVGLWidget* w2;
};

View file

@ -1,191 +0,0 @@
#include "glyuvwidget.h"
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <QDebug>
#include <QTime>
#define VERTEXIN 0
#define TEXTUREIN 1
GLYuvWidget::GLYuvWidget(QWidget *parent):
QOpenGLWidget(parent)
{
}
GLYuvWidget::~GLYuvWidget()
{
makeCurrent();
m_vbo.destroy();
m_textureY->destroy();
m_textureU->destroy();
m_textureV->destroy();
doneCurrent();
}
void GLYuvWidget::setVideoSize(quint32 videoWidth, quint32 videoHeight)
{
m_videoWidth = videoWidth;
m_videoHeight = videoHeight;
}
void GLYuvWidget::updateTexture(quint8* bufferY, quint8* bufferU, quint8* bufferV, quint32 linesizeY, quint32 linesizeU, quint32 linesizeV)
{
qDebug() << "slotShowYuv";
m_bufferY = bufferY;
m_bufferU = bufferU;
m_bufferV = bufferV;
m_linesizeY = linesizeY;
m_linesizeU = linesizeU;
m_linesizeV = linesizeV;
//update(); // 不实时
//repaint(); // 同上
paintEvent(nullptr);// 最实时的方案
update();
}
void GLYuvWidget::initializeGL()
{
initializeOpenGLFunctions();
glDisable(GL_DEPTH_TEST); // 关闭深度缓冲测试对于2D图形来说没用
static const GLfloat vertices[]{
// 顶点坐标(-1.0,1.0)
-1.0f,-1.0f,
-1.0f,+1.0f,
+1.0f,+1.0f,
+1.0f,-1.0f,
// 纹理坐标(0.0,1.0)
0.0f,1.0f,
0.0f,0.0f,
1.0f,0.0f,
1.0f,1.0f,
};
// 初始化顶点缓冲
m_vbo.create();
m_vbo.bind();
m_vbo.allocate(vertices,sizeof(vertices));
// 顶点着色器
QOpenGLShader *vShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
// 顶点着色器源码
const char *vertexSrc =
"attribute vec4 vertexIn; \
attribute vec2 textureIn; \
varying vec2 textureOut; \
void main(void) \
{ \
gl_Position = vertexIn; \
textureOut = textureIn; \
}";
vShader->compileSourceCode(vertexSrc);
// 片段着色器
QOpenGLShader *fShader = new QOpenGLShader(QOpenGLShader::Fragment, this);
// 片段着色器源码
const char *fragmentSrc =
"varying vec2 textureOut; \
uniform sampler2D tex_y; \
uniform sampler2D tex_u; \
uniform sampler2D tex_v; \
void main(void) \
{ \
vec3 yuv; \
vec3 rgb; \
yuv.x = texture2D(tex_y, textureOut).r; \
yuv.y = texture2D(tex_u, textureOut).r - 0.5; \
yuv.z = texture2D(tex_v, textureOut).r - 0.5; \
rgb = mat3( 1, 1, 1, \
0, -0.39465, 2.03211, \
1.13983, -0.58060, 0) * yuv; \
gl_FragColor = vec4(rgb, 1); \
}";
fShader->compileSourceCode(fragmentSrc);
// 着色器程序
m_shaderProgram = new QOpenGLShaderProgram(this);
// 添加着色器
m_shaderProgram->addShader(vShader);
m_shaderProgram->addShader(fShader);
m_shaderProgram->bindAttributeLocation("vertexIn",VERTEXIN);
m_shaderProgram->bindAttributeLocation("textureIn",TEXTUREIN);
// 链接着色器
m_shaderProgram->link();
m_shaderProgram->bind();
m_shaderProgram->enableAttributeArray(VERTEXIN);
m_shaderProgram->enableAttributeArray(TEXTUREIN);
m_shaderProgram->setAttributeBuffer(VERTEXIN, GL_FLOAT, 0, 2, 2*sizeof(GLfloat));
m_shaderProgram->setAttributeBuffer(TEXTUREIN, GL_FLOAT, 8*sizeof(GLfloat), 2, 2*sizeof(GLfloat));
// 着色器程序中取得yuv纹理位置
m_textureUniformY = m_shaderProgram->uniformLocation("tex_y");
m_textureUniformU = m_shaderProgram->uniformLocation("tex_u");
m_textureUniformV = m_shaderProgram->uniformLocation("tex_v");
m_textureY = new QOpenGLTexture(QOpenGLTexture::Target2D);
m_textureU = new QOpenGLTexture(QOpenGLTexture::Target2D);
m_textureV = new QOpenGLTexture(QOpenGLTexture::Target2D);
m_textureY->create();
m_textureU->create();
m_textureV->create();
m_idY = m_textureY->textureId();
m_idU = m_textureU->textureId();
m_idV = m_textureV->textureId();
glClearColor(0.0,0.0,0.0,0.0);
}
void GLYuvWidget::inittexture()
{
//QMatrix4x4 m;
//m.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f );//透视矩阵随距离的变化,图形跟着变化。屏幕平面中心就是视点(摄像头),需要将图形移向屏幕里面一定距离。
//近裁剪平面是一个矩形,矩形左下角点三维空间坐标是left,bottom,-near,右上角点是right,top,-near所以此处为负表示z轴最大为10
//远裁剪平面也是一个矩形,左下角点空间坐标是left,bottom,-far,右上角点是right,top,-far所以此处为正表示z轴最小为-10
//此时坐标中心还是在屏幕水平面中间,只是前后左右的距离已限制。
//m.ortho(-2,+2,-2,+2,-10,10);
glActiveTexture(GL_TEXTURE0); //激活纹理单元GL_TEXTURE0,系统里面的
glBindTexture(GL_TEXTURE_2D, m_idY); //绑定y分量纹理对象id到激活的纹理单元
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_linesizeY);
//使用内存中的数据创建真正的y分量纹理数据
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_videoWidth, m_videoHeight, 0, GL_RED, GL_UNSIGNED_BYTE, m_bufferY);
//https://blog.csdn.net/xipiaoyouzi/article/details/53584798 纹理参数解析
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE1); //激活纹理单元GL_TEXTURE1
glBindTexture(GL_TEXTURE1, m_idU);
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_linesizeU);
//使用内存中的数据创建真正的u分量纹理数据
glTexImage2D(GL_TEXTURE_2D,0,GL_RED, m_videoWidth >> 1, m_videoHeight >> 1, 0, GL_RED, GL_UNSIGNED_BYTE, m_bufferU);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE2); //激活纹理单元GL_TEXTURE2
glBindTexture(GL_TEXTURE_2D, m_idV);
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_linesizeV);
//使用内存中的数据创建真正的v分量纹理数据
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, m_videoWidth >> 1, m_videoHeight >> 1, 0, GL_RED, GL_UNSIGNED_BYTE, m_bufferV);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
void GLYuvWidget::paintGL()
{
qDebug() << "paintGL()";
inittexture();
//指定y纹理要使用新值
glUniform1i(m_textureUniformY, 0);
//指定u纹理要使用新值
glUniform1i(m_textureUniformU, 1);
//指定v纹理要使用新值
glUniform1i(m_textureUniformV, 2);
//使用顶点数组方式绘制图形
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

View file

@ -1,60 +0,0 @@
#ifndef GLYUVWIDGET_H
#define GLYUVWIDGET_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QTimer>
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
class GLYuvWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
GLYuvWidget(QWidget *parent = 0);
~GLYuvWidget();
public:
void setVideoSize(quint32 videoWidth, quint32 videoHeight);
//显示一帧Yuv图像
void updateTexture(quint8* bufferY, quint8* bufferU, quint8* bufferV, quint32 linesizeY, quint32 linesizeU, quint32 linesizeV);
protected:
void initializeGL() Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
void inittexture();
private:
QOpenGLShaderProgram *m_shaderProgram = Q_NULLPTR; // 着色器程序
QOpenGLBuffer m_vbo; // 顶点缓冲对象
//opengl中yuv纹理位置
GLuint m_textureUniformY = 0;
GLuint m_textureUniformU = 0;
GLuint m_textureUniformV = 0;
// yuv纹理对象
QOpenGLTexture *m_textureY = Q_NULLPTR;
QOpenGLTexture *m_textureU = Q_NULLPTR;
QOpenGLTexture *m_textureV = Q_NULLPTR;
// 纹理对象ID
GLuint m_idY = 0;
GLuint m_idU = 0;
GLuint m_idV = 0;
// 视频宽高
quint32 m_videoWidth = 2160;
quint32 m_videoHeight = 1080;
quint8* m_bufferY = Q_NULLPTR;
quint8* m_bufferU = Q_NULLPTR;
quint8* m_bufferV = Q_NULLPTR;
quint32 m_linesizeY = 0;
quint32 m_linesizeU = 0;
quint32 m_linesizeV = 0;
};
#endif // GLYUVWIDGET_H