mirror of
https://github.com/barry-ran/QtScrcpy.git
synced 2025-08-03 14:18:45 +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 \
|
decoder.cpp \
|
||||||
server.cpp \
|
server.cpp \
|
||||||
convert.cpp \
|
convert.cpp \
|
||||||
glyuvwidget.cpp \
|
|
||||||
frames.cpp \
|
frames.cpp \
|
||||||
yuvglwidget.cpp
|
yuvglwidget.cpp
|
||||||
|
|
||||||
|
@ -42,7 +41,6 @@ HEADERS += \
|
||||||
decoder.h \
|
decoder.h \
|
||||||
server.h \
|
server.h \
|
||||||
convert.h \
|
convert.h \
|
||||||
glyuvwidget.h \
|
|
||||||
frames.h \
|
frames.h \
|
||||||
yuvglwidget.h
|
yuvglwidget.h
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,8 @@
|
||||||
#include "dialog.h"
|
#include "dialog.h"
|
||||||
#include "ui_dialog.h"
|
#include "ui_dialog.h"
|
||||||
#include "adbprocess.h"
|
#include "adbprocess.h"
|
||||||
|
|
||||||
#include "glyuvwidget.h"
|
|
||||||
#include "yuvglwidget.h"
|
#include "yuvglwidget.h"
|
||||||
|
|
||||||
#define OPENGL_PLAN2
|
|
||||||
|
|
||||||
void saveAVFrame_YUV_ToTempFile(const AVFrame *pFrame)
|
void saveAVFrame_YUV_ToTempFile(const AVFrame *pFrame)
|
||||||
{
|
{
|
||||||
int t_frameWidth = pFrame->width;
|
int t_frameWidth = pFrame->width;
|
||||||
|
@ -49,16 +45,9 @@ Dialog::Dialog(QWidget *parent) :
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
#ifdef OPENGL_PLAN2
|
|
||||||
w2 = new YUVGLWidget(this);
|
w2 = new YUVGLWidget(this);
|
||||||
w2->resize(ui->imgLabel->size());
|
w2->resize(ui->imgLabel->size());
|
||||||
w2->move(230, 20);
|
w2->move(230, 20);
|
||||||
#else
|
|
||||||
w = new GLYuvWidget(this);
|
|
||||||
w->resize(ui->imgLabel->size());
|
|
||||||
w->move(230, 20);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Decoder::init();
|
Decoder::init();
|
||||||
|
|
||||||
|
@ -84,23 +73,11 @@ Dialog::Dialog(QWidget *parent) :
|
||||||
frames.lock();
|
frames.lock();
|
||||||
const AVFrame *frame = frames.consumeRenderedFrame();
|
const AVFrame *frame = frames.consumeRenderedFrame();
|
||||||
//saveAVFrame_YUV_ToTempFile(frame);
|
//saveAVFrame_YUV_ToTempFile(frame);
|
||||||
#ifdef OPENGL_PLAN2
|
|
||||||
w2->setFrameSize(frame->width, frame->height);
|
w2->setFrameSize(frame->width, frame->height);
|
||||||
w2->setYPixels(frame->data[0], frame->linesize[0]);
|
w2->setYPixels(frame->data[0], frame->linesize[0]);
|
||||||
w2->setUPixels(frame->data[1], frame->linesize[1]);
|
w2->setUPixels(frame->data[1], frame->linesize[1]);
|
||||||
w2->setVPixels(frame->data[2], frame->linesize[2]);
|
w2->setVPixels(frame->data[2], frame->linesize[2]);
|
||||||
//w2->update();
|
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
|
|
||||||
|
|
||||||
frames.unLock();
|
frames.unLock();
|
||||||
},Qt::QueuedConnection);
|
},Qt::QueuedConnection);
|
||||||
|
|
|
@ -11,7 +11,6 @@ namespace Ui {
|
||||||
class Dialog;
|
class Dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GLYuvWidget;
|
|
||||||
class YUVGLWidget;
|
class YUVGLWidget;
|
||||||
class Dialog : public QDialog
|
class Dialog : public QDialog
|
||||||
{
|
{
|
||||||
|
@ -33,7 +32,6 @@ private:
|
||||||
Server* server;
|
Server* server;
|
||||||
Decoder decoder;
|
Decoder decoder;
|
||||||
Frames frames;
|
Frames frames;
|
||||||
GLYuvWidget* w;
|
|
||||||
YUVGLWidget* w2;
|
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
Add a link
Reference in a new issue