Qt 使用openGL 渲染YUV420P格式的视频
代码如下
YUV420P_Render.h
#ifndef YUV420P_RENDER_H
#define YUV420P_RENDER_H #include <QObject>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
class YUV420P_Render: protected QOpenGLFunctions
{ public:
YUV420P_Render();
~YUV420P_Render(); //初始化gl
void initialize();
//刷新显示
void render(uchar* py,uchar* pu,uchar* pv,int width,int height,int type);
void render(uchar* ptr,int width,int height,int type); private:
//shader程序
QOpenGLShaderProgram m_program;
//shader中yuv变量地址
GLuint m_textureUniformY, m_textureUniformU , m_textureUniformV;
//创建纹理
GLuint m_idy , m_idu , m_idv; }; #endif // YUV420P_RENDER_H
YUV420P_Render.cpp
#include "YUV420P_Render.h"
#include <QDebug>
#include <QTimer> #define ATTRIB_VERTEX 0
#define ATTRIB_TEXTURE 1 YUV420P_Render::YUV420P_Render()
{
} YUV420P_Render::~YUV420P_Render()
{
} //初始化gl
void YUV420P_Render::initialize()
{
qDebug() << "initializeGL"; //初始化opengl (QOpenGLFunctions继承)函数
initializeOpenGLFunctions(); //顶点shader
const char *vString =
"attribute vec4 vertexPosition;\
attribute vec2 textureCoordinate;\
varying vec2 texture_Out;\
void main(void)\
{\
gl_Position = vertexPosition;\
texture_Out = textureCoordinate;\
}";
//片元shader
const char *tString =
"varying vec2 texture_Out;\
uniform sampler2D tex_y;\
uniform sampler2D tex_u;\
uniform sampler2D tex_v;\
void main(void)\
{\
vec3 YUV;\
vec3 RGB;\
YUV.x = texture2D(tex_y, texture_Out).r;\
YUV.y = texture2D(tex_u, texture_Out).r - 0.5;\
YUV.z = texture2D(tex_v, texture_Out).r - 0.5;\
RGB = mat3(1.0, 1.0, 1.0,\
0.0, -0.39465, 2.03211,\
1.13983, -0.58060, 0.0) * YUV;\
gl_FragColor = vec4(RGB, 1.0);\
}"; //m_program加载shader(顶点和片元)脚本
//片元(像素)
qDebug()<<m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, tString);
//顶点shader
qDebug() << m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vString); //设置顶点位置
m_program.bindAttributeLocation("vertexPosition",ATTRIB_VERTEX);
//设置纹理位置
m_program.bindAttributeLocation("textureCoordinate",ATTRIB_TEXTURE); //编译shader
qDebug() << "m_program.link() = " << m_program.link(); qDebug() << "m_program.bind() = " << m_program.bind(); //传递顶点和纹理坐标
//顶点
static const GLfloat ver[] = {
-1.0f,-1.0f,
1.0f,-1.0f,
-1.0f, 1.0f,
1.0f,1.0f
// -1.0f,-1.0f,
// 0.9f,-1.0f,
// -1.0f, 1.0f,
// 0.9f,1.0f
};
//纹理
static const GLfloat tex[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
}; //设置顶点,纹理数组并启用
glVertexAttribPointer(ATTRIB_VERTEX, , GL_FLOAT, , , ver);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTURE, , GL_FLOAT, , , tex);
glEnableVertexAttribArray(ATTRIB_TEXTURE); //从shader获取地址
m_textureUniformY = m_program.uniformLocation("tex_y");
m_textureUniformU = m_program.uniformLocation("tex_u");
m_textureUniformV = m_program.uniformLocation("tex_v"); //创建纹理
glGenTextures(, &m_idy);
//Y
glBindTexture(GL_TEXTURE_2D, m_idy);
//放大过滤,线性插值 GL_NEAREST(效率高,但马赛克严重)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //U
glGenTextures(, &m_idu);
glBindTexture(GL_TEXTURE_2D, m_idu);
//放大过滤,线性插值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //V
glGenTextures(, &m_idv);
glBindTexture(GL_TEXTURE_2D, m_idv);
//放大过滤,线性插值
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT); } //刷新显示
void YUV420P_Render::render(uchar* py,uchar* pu,uchar* pv,int width,int height,int type)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_idy);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width, height, , GL_RED, GL_UNSIGNED_BYTE,py);
//与shader 关联
glUniform1i(m_textureUniformY, ); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idu);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, pu);
//与shader 关联
glUniform1i(m_textureUniformU,); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idv);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, pv);
//与shader 关联
glUniform1i(m_textureUniformV, ); glDrawArrays(GL_TRIANGLE_STRIP,,);
qDebug() << "paintGL";
} void YUV420P_Render::render(uchar* ptr,int width,int height,int type)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_idy);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width, height, , GL_RED, GL_UNSIGNED_BYTE,ptr);
//与shader 关联
glUniform1i(m_textureUniformY, ); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idu);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, ptr+width*height);
//与shader 关联
glUniform1i(m_textureUniformU,); glActiveTexture(GL_TEXTURE0+);
glBindTexture(GL_TEXTURE_2D, m_idv);
//修改纹理内容(复制内存内容)
glTexImage2D(GL_TEXTURE_2D, , GL_RED, width/, height/, , GL_RED, GL_UNSIGNED_BYTE, ptr+width*height*/);
//与shader 关联
glUniform1i(m_textureUniformV, ); glDrawArrays(GL_TRIANGLE_STRIP,,);
qDebug() << "paintGL";
}
最后写一个窗口类继承 QOpenGLWidget
重写两个函数
void initializeGL(); //调用上面渲染类的初始化函数
void paintGL();//调用上面渲染类的渲染函数
Qt 使用openGL 渲染YUV420P格式的视频的更多相关文章
- Qt 使用openGL 渲染NV12格式的视频
直接上代码 Nv12Render.h #ifndef NV12RENDER_H #define NV12RENDER_H #include <QOpenGLFunctions> #incl ...
- 视频和音频播放的演示最简单的例子6:OpenGL广播YUV420P(T经exture,采用Shader)
===================================================== 最简单的视频和音频播放的演示样品系列列表: 最简单的视音频播放演示样例1:总述 最简单的视音 ...
- 关于QT Graphics View开启OpenGL渲染后复选框、微调框等无法正常显示的问题
之前学习QT Graphics View框架,除了基本的图元外,还可以通过QGraphicsProxyWidget类添加QT的基本Widget(如按钮.复选框.单选框等),常使用的场景类接口如下: Q ...
- Qt Examples - Boxes (在Qt场景视图中结合OpenGL渲染)
QT自带例程Boxes使用QT Graphics View框架实现了2D图形和3D图形的混合渲染,综合性比较强,整合知识较多,值得学习. 可以使用鼠标通过以下方式控制演示中的元素: 按住鼠标左键的同时 ...
- 最简单的视音频播放示例6:OpenGL播放YUV420P(通过Texture,使用Shader)
本文记录OpenGL播放视频的技术.上一篇文章中,介绍了一种简单的使用OpenGL显示视频的方式.但是那还不是OpenGL显示视频技术的精髓.和Direct3D一样,OpenGL更好的显示视频的方式也 ...
- D3D三层Texture纹理经像素着色器实现渲染YUV420P
简单记录一下这两天用Texture实现渲染YUV420P的一些要点. 在视频播放的过程中,有的时候解码出来的数据是YUV420P的.表面(surface)通过设置参数是可以渲染YUV420P的,但Te ...
- 初始化glew,创建OpenGL渲染上下文
void RegisterWinDowClass(HINSTANCE hInstance,std::string className,WNDPROC proc) { WNDCLASS wndClass ...
- 使用X264编码yuv格式的视频帧使用ffmpeg解码h264视频帧
前面一篇博客介绍在centos上搭建点击打开链接ffmpeg及x264开发环境.以下就来问个样例: 1.利用x264库将YUV格式视频文件编码为h264格式视频文件 2.利用ffmpeh库将h264格 ...
- Qt Quick + OpenGL + Bullet初次測试
Qt Quick + OpenGL + Bullet初次測试 眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...
随机推荐
- Jenkins集成openshift容器中进行代码扫描
1.Dockerfile sonarDockerfile: (基础slave镜像参考上篇博文) FROM registry.it.com/openshift/jenkins-slave:latest ...
- python调用数据返回字典dict数据的现象2
python调用数据返回字典dict数据的现象2 思考: 话题1连接:https://www.cnblogs.com/zwgbk/p/10248479.html在打印和添加时候加上内存地址id(),可 ...
- Docker资源限制与Cgroups
一.Linux control groups 简介 Linux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如 ...
- 记一次Dubbo服务注册异常
公司项目重构,把dubbo版本从2.5.8升级为2.6.2.升级后在本地运行一点问题都没有:可是通过公司自研的发布系统将项目发布到测试环境的linux服务器下面后,出现了dubbo服务 ...
- nrf2401 - 最廉价的2.4G无线通信方案
所有的使用Arduino 的朋友大多都会知道大名鼎鼎的XBee 这个土豪级的ZigBee 的通信模块.我们是做产品开发的,对于XBee这个产品可谓是又爱又恨,不得不承认他确实是一个好货,从做工到功能都 ...
- webpack打包经验——处理打包文件体积过大的问题
前言 最近对一个比较老的公司项目做了一次优化,处理的主要是webpack打包文件体积过大的问题. 这里就写一下对于webpack打包优化的一些经验. 主要分为以下几个方面: 去掉开发环境下的配置 Ex ...
- immutability因React官方出镜之使用总结分享!
作者:首席填坑官∙苏南 公众号:honeyBadger8,群:912594095,本文原创,著作权归作者所有,转载请注明原链接及出处. 引言 之前项目中遇到数据拷贝.引用之间数据层级嵌套过深,拷贝的值 ...
- RabbitMQ总结
消息队列 三个业务场景:解耦.异步.削峰 带来问题 系统可用性降低:外部依赖越多,越容易挂掉. 系统复杂性提高:重复消费,消息丢失,消息传递的顺序性 一致性问题: 一.如何保证消息的可靠性传输(如何处 ...
- springmvc的@ResponseBody报错
错误:差不多就是下面的格式 原因:你可能返回的类型是这样的List<School>而school类中可能包含Class类或者Teacher类,就是包含对象. 这样的话jackson是不能帮 ...
- Linux登录MySQL时出现 Can't connect to local MySQL server through socket '/tmp/mysql.sock'解决方法
在Linux上登录MySQL时出现如下提示,如下图: 通过查找资料了解到: MySQL有两种连接方式: (1)TCP/IP (2)socket 对mysql.sock来说,其作用是程序与mysqlse ...