mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-04-19 19:15:07 +00:00
确定opengl方案
This commit is contained in:
parent
ff10e0e376
commit
2f17c8416c
5 changed files with 1 additions and 279 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
Loading…
Add table
Reference in a new issue