Qt 使用openGL 渲染NV12格式的视频
直接上代码
Nv12Render.h
#ifndef NV12RENDER_H
#define NV12RENDER_H
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer> class Nv12Render : public QOpenGLFunctions
{
public:
Nv12Render() = default;
Nv12Render(const Nv12Render&) = delete;
~Nv12Render(); void initialize();
void render(uchar* m_py,uchar* m_pu,int width,int height);
void render(uchar *nv12Ptr, int w, int h); private:
QOpenGLShaderProgram program;
GLuint idY,idUV;
QOpenGLBuffer vbo;
}; #endif // NV12RENDER_H
Nv12Render.cpp
#include "NV12_Render.h"
#include <QOpenGLTexture>
#include <QDebug> Nv12Render::~Nv12Render()
{ } void Nv12Render::initialize()
{
initializeOpenGLFunctions();
const char *vsrc =
"attribute vec4 vertexIn; \
attribute vec4 textureIn; \
varying vec4 textureOut; \
void main(void) \
{ \
gl_Position = vertexIn; \
textureOut = textureIn; \
}"; const char *fsrc =
"varying mediump vec4 textureOut;\n"
"uniform sampler2D textureY;\n"
"uniform sampler2D textureUV;\n"
"void main(void)\n"
"{\n"
"vec3 yuv; \n"
"vec3 rgb; \n"
"yuv.x = texture2D(textureY, textureOut.st).r - 0.0625; \n"
"yuv.y = texture2D(textureUV, textureOut.st).r - 0.5; \n"
"yuv.z = texture2D(textureUV, textureOut.st).g - 0.5; \n"
"rgb = mat3( 1, 1, 1, \n"
"0, -0.39465, 2.03211, \n"
"1.13983, -0.58060, 0) * yuv; \n"
"gl_FragColor = vec4(rgb, 1); \n"
"}\n";
program.addShaderFromSourceCode(QOpenGLShader::Vertex,vsrc);
program.addShaderFromSourceCode(QOpenGLShader::Fragment,fsrc);
program.link(); GLfloat points[]{
-1.0f, 1.0f,
1.0f, 1.0f,
1.0f, -1.0f,
-1.0f, -1.0f, 0.0f,0.0f,
1.0f,0.0f,
1.0f,1.0f,
0.0f,1.0f
};
vbo.create();
vbo.bind();
vbo.allocate(points,sizeof(points)); GLuint ids[];
glGenTextures(,ids);
idY = ids[];
idUV = ids[];
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
} void Nv12Render::render(uchar* py,uchar* puv, int w, int h)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST); program.bind();
vbo.bind();
program.enableAttributeArray("vertexIn");
program.enableAttributeArray("textureIn");
program.setAttributeBuffer("vertexIn",GL_FLOAT, , , *sizeof(GLfloat));
program.setAttributeBuffer("textureIn",GL_FLOAT, * * sizeof(GLfloat),,*sizeof(GLfloat)); glActiveTexture(GL_TEXTURE0 + );
glBindTexture(GL_TEXTURE_2D,idY);
glTexImage2D(GL_TEXTURE_2D,,GL_RED,w,h,,GL_RED,GL_UNSIGNED_BYTE,py);
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_TEXTURE0 + );
glBindTexture(GL_TEXTURE_2D,idUV);
glTexImage2D(GL_TEXTURE_2D,,GL_RG,w >> ,h >> ,,GL_RG,GL_UNSIGNED_BYTE,puv);
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); program.setUniformValue("textureUV",);
program.setUniformValue("textureY",);
glDrawArrays(GL_QUADS,,);
program.disableAttributeArray("vertexIn");
program.disableAttributeArray("textureIn");
program.release();
} void Nv12Render::render(uchar *nv12Ptr, int w, int h)
{
if(!nv12Ptr)return; glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_DEPTH_TEST); program.bind();
vbo.bind();
program.enableAttributeArray("vertexIn");
program.enableAttributeArray("textureIn");
program.setAttributeBuffer("vertexIn",GL_FLOAT, , , *sizeof(GLfloat));
program.setAttributeBuffer("textureIn",GL_FLOAT, * * sizeof(GLfloat),,*sizeof(GLfloat)); glActiveTexture(GL_TEXTURE0 + );
glBindTexture(GL_TEXTURE_2D,idY);
glTexImage2D(GL_TEXTURE_2D,,GL_RED,w,h,,GL_RED,GL_UNSIGNED_BYTE,nv12Ptr);
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_TEXTURE0 + );
glBindTexture(GL_TEXTURE_2D,idUV);
glTexImage2D(GL_TEXTURE_2D,,GL_RG,w >> ,h >> ,,GL_RG,GL_UNSIGNED_BYTE,nv12Ptr + w*h);
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); program.setUniformValue("textureUV",);
program.setUniformValue("textureY",);
glDrawArrays(GL_QUADS,,);
program.disableAttributeArray("vertexIn");
program.disableAttributeArray("textureIn");
program.release();
}
最后写一个窗口类继承 QOpenGLWidget
重写两个函数
void initializeGL(); //调用上面渲染类的初始化函数
void paintGL();//调用上面渲染类的渲染函数
Qt 使用openGL 渲染NV12格式的视频的更多相关文章
- Qt 使用openGL 渲染YUV420P格式的视频
代码如下 YUV420P_Render.h #ifndef YUV420P_RENDER_H #define YUV420P_RENDER_H #include <QObject> #in ...
- 关于QT Graphics View开启OpenGL渲染后复选框、微调框等无法正常显示的问题
之前学习QT Graphics View框架,除了基本的图元外,还可以通过QGraphicsProxyWidget类添加QT的基本Widget(如按钮.复选框.单选框等),常使用的场景类接口如下: Q ...
- Qt Examples - Boxes (在Qt场景视图中结合OpenGL渲染)
QT自带例程Boxes使用QT Graphics View框架实现了2D图形和3D图形的混合渲染,综合性比较强,整合知识较多,值得学习. 可以使用鼠标通过以下方式控制演示中的元素: 按住鼠标左键的同时 ...
- 初始化glew,创建OpenGL渲染上下文
void RegisterWinDowClass(HINSTANCE hInstance,std::string className,WNDPROC proc) { WNDCLASS wndClass ...
- Qt Quick + OpenGL + Bullet初次測试
Qt Quick + OpenGL + Bullet初次測试 眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...
- CSharpGL(31)[译]OpenGL渲染管道那些事
CSharpGL(31)[译]OpenGL渲染管道那些事 +BIT祝威+悄悄在此留下版了个权的信息说: 开始 自认为对OpenGL的掌握到了一个小瓶颈,现在回头细细地捋一遍OpenGL渲染管道应当是一 ...
- OpenGL渲染流程
一.什么是openGL OpenGL被定义为“图形硬件的一种软件接口”.从本质上说,它是一个3D图形和模型库,具有高度的可移植性,具有非常快的速度. 二.管线 管线这个术语描述了opengl渲染的整个 ...
- 解决:信息中插入avi格式的视频时,提示“unsupported video format”
[测试步骤]:新建信息,添加AVI格式的视频 [测试结果]:添加时弹出提示"unsupported video format" 该问题主要提现在手机彩信视频附件不支持该AVI格式的 ...
- CentOS 6.4 播放avi格式的视频文件
1. 需要先进行相关的yum源的导入: rpm -Uhv http://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/rpmforge-release-0. ...
随机推荐
- 比起Windows,怎样解读Linux的文件系统与目录结构?
比起Windows,怎样解读Linux的文件系统与目录结构? Linux 和Windows的文件系统有些不同,在学习使用 Linux 之前,若能够了解这些不同,会有助于后续学习. 本文先对Window ...
- .net core实践系列之短信服务-架构优化
前言 通过前面的几篇文章,讲解了一个短信服务的架构设计与实现.然而初始方案并非100%完美的,我们仍可以对该架构做一些优化与调整. 同时我也希望通过这篇文章与大家分享一下,我的架构设计理念. 源码地址 ...
- HDU - 4027 线段树减枝
这题太坑了...满满的都是坑点 1号坑点:给定左右区间有可能是反的...因为题目上说x,y之间,但是没有说明x,y的大小关系(害我一直RE到怀疑人生) 2号坑点:开根号的和不等于和开根号(还好避开了) ...
- 网络编程-C/S架构
什么是C/S架构 C指的是client(客户端软件),S指的是Server(服务端软件),本章的重点就是教大家写一个C/S架构的软件,实现服务端软件与客户端软件基于网络通信. 计算机基础知识 作为应用 ...
- Python学习第十一篇——for 的本质及如何正确修改列表
假如现在有一个列表:magicians_list = ['mole','jack','lucy'],现在想通过一个函数来实现,在列表的每个元素前面加上“the Great”的字样.现在通过一个函数来实 ...
- javascript与php与python的函数写法区别与联系
1.javascript函数写法种类: (一).第一种 function test(param){ return 111; } (二).第二种 var test = function(param){ ...
- 了解sso原理
- python os模块详解
一.Python os模块(Linux环境) 1.1 执行shell命令 os.system('cmd') 执行命令不保存结果 os.popen('command') 执行后返回结果,使用.read( ...
- dynamo与cassandra区别
虽说cassandra是dynamo的开源版本,但两者还是有很大区别的. coordinator的选取: 在dynamo论文中,一般是preference list中N个副本的第一个 为什么叫“一般” ...
- Django之用户上传文件的参数配置
Django之用户上传文件的参数配置 models.py文件 class Xxoo(models.Model): title = models.CharField(max_length=128) # ...