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. ...
随机推荐
- LDAP2-创建OU创建用户
创建OU创建用户 1.创建OU 选择Organisational unit 组织单元 输入OU名称 提交信息 结果创建成功 2.创建员工 选择ou选择新建子条目 选择默认模板 选择inetorgper ...
- 【转】强化学习(一)Deep Q-Network
原文地址:https://www.hhyz.me/2018/08/05/2018-08-05-RL/ 1. 前言 虽然将深度学习和增强学习结合的想法在几年前就有人尝试,但真正成功的开端就是DeepMi ...
- ASP.NET Core MVC四种枚举绑定方式
前言 本节我们来讲讲在ASP.NET Core MVC又为我们提供了哪些方便,之前我们探讨过在ASP.NET MVC中下拉框绑定方式,这节我们来再来重点看看枚举绑定的方式,充分实现你所能想到的场景,满 ...
- Python之Flask笔记
在这里先说一下最开始所经历的一些错误app=Flask(_name_),当初拼写的时候怎么都报错后来发现此处是两个'_' 配置文件 app.config.from_object(__name__) 在 ...
- Django Rest framework基础使用之Request/Response
1.Request restframework提供了一个Request对象(rest_framework.request.Request) Request对象继承了Django默认的HttpReque ...
- P1525 关押罪犯
基础并查集-- #include<iostream> #include<string.h> #include<algorithm> #include<stdi ...
- Python类与对象的理解
注意python的类对象与实例对象的区分 类对象与实例对象是相对的,例如:a=1,那么a就是int的一个实例对象,这里的a相对于int来说,a是实例对象,int是类对象.但是int同时又是type的实 ...
- 网络编程-TCP/IP
TCP/IP五层模型讲解(2分) 我们将应用层,表示层,会话层并作应用层,从tcp/ip五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议 就理解了整个互联网通信的原理. 首先,用户感知到的 ...
- Effective java 43返回零长度的数组或者集合而不是null
- 三次握手复习TCP
临近下班,突然想起三次握手的概念有点模糊. 大学时候的<计算机网络>是英语版的,那时候学习迷迷糊糊的.大概记得一个模型罢了. 幸好,大学基本所有的书都卖了,就是计算机网络没卖.待会回去看看 ...