适合美工的设计网站,沈阳网站企业,网站建qq群,保定制作公司网站一般的在arm嵌入式平台#xff0c;大多数板子都要硬解码硬件渲染的框架#xff0c;使用即可。
在x86下比较麻烦了。 优化的思路一共有以下几个方面#xff0c;
1. 软解码变成硬解码
2. 将YUV转QImage的操作转移到GPU
3. QWidget渲染QImage变成opengGL渲染AVFrame
这三点…一般的在arm嵌入式平台大多数板子都要硬解码硬件渲染的框架使用即可。
在x86下比较麻烦了。 优化的思路一共有以下几个方面
1. 软解码变成硬解码
2. 将YUV转QImage的操作转移到GPU
3. QWidget渲染QImage变成opengGL渲染AVFrame
这三点优化来说2与3是优化的效率是非常显著的。
1的优化效果往往需要将硬解码的数据copy至CPU再使用2-3的优化。
这样一来解码效率提升了但是数据copy时候CPU使用率会上升。如果两者抵消后CPU使用率还是上升那就得不偿失。如果能实现硬解码的数据不经过CPU直接打到GPU进行渲染那就是最完美的方案。这个在x86下需要研究opengl渲染硬件类型数据难度未知理论如果用的是比较新的框架资料会多一些。 本文主要是基于2-3的优化在qt5.1下面基于opengl实现了这个方案在多路1080P的使用场景下CPU使用率下降非常明显。 #include opengl_yuv_shader.h
#include QDebug
#include iostream
#include GL/gl.h
#include QGLShaderopengl_yuv_shader::opengl_yuv_shader(QWidget *parent) : QGLWidget(parent), useVBO(false),vboId(0),yuv420p_shaderProgram(0),yuvj422p_shaderProgram(0)
{textures[0]0;textures[1]0;textures[2]0;av_frame nullptr;connect(this,SIGNAL(render_frame()),this,SLOT(slot_render_frame()),Qt::QueuedConnection);//5 lu 60% cpu
}opengl_yuv_shader::~opengl_yuv_shader() {makeCurrent();glDeleteTextures(3, textures);if (yuv420p_shaderProgram) {glDeleteProgram(yuv420p_shaderProgram);}if (yuvj422p_shaderProgram) {glDeleteProgram(yuvj422p_shaderProgram);}doneCurrent();
}void opengl_yuv_shader::initTextures()
{glGenTextures(3, textures);for (int i 0; i 3; i) {glBindTexture(GL_TEXTURE_2D, textures[i]);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);glBindTexture(GL_TEXTURE_2D, 0);}
}void opengl_yuv_shader::initShaders()
{QGLShader *vshader new QGLShader(QGLShader::Vertex, this);const char *vsrc attribute vec4 vertex;\nattribute vec2 texCoord;\nvarying vec2 texc;\nvoid main(void)\n{\n gl_Position vertex;\n texc texCoord;\n}\n;vshader-compileSourceCode(vsrc);//编译顶点着色器代码QGLShader *fshader new QGLShader(QGLShader::Fragment, this);//vec4(1.0,0,0,1.0);const char *fsrc uniform sampler2D texture;\nvarying vec2 texc;\nvoid main(void)\n{\n gl_FragColor texture2D(texture,texc);\n}\n;//本方案的核心点在于这个片段着色器在GPU上完成YUV转RGB的浮点运算。//由于测试的摄像机是基于YUV J420P转换的所以算法上与YUV420P略有差别。// 实际使用需要根据具体的AVFrame格式进行转换。可初始化多个SHADER管理器、// 渲染时根据像素格式选择shader渲染const char* fragmentShaderSource R(varying vec2 texc;uniform sampler2D textureY;uniform sampler2D textureU;uniform sampler2D textureV;void main(){float y texture2D(textureY, texc).r;float u texture2D(textureU, texc).r;float v texture2D(textureV, texc).r;float r y 1.402 * (v - 0.5);float g y - 0.344136 * (u - 0.5) - 0.714136 * (v - 0.5);float b y 1.772 * (u - 0.5);// 确保 RGB 值在 0-1 范围内r clamp(r, 0.0, 1.0);g clamp(g, 0.0, 1.0);b clamp(b, 0.0, 1.0);gl_FragColor vec4(r, g, b, 1.0);});fshader-compileSourceCode(fragmentShaderSource); //编译纹理着色器代码program.addShader(vshader);//添加顶点着色器program.addShader(fshader);//添加纹理碎片着色器program.bindAttributeLocation(vertex, 0);//绑定顶点属性位置program.bindAttributeLocation(texCoord, 1);//绑定纹理属性位置// 链接着色器管道if (!program.link()){close();qDebug()program.link() errorendl;}// 绑定着色器管道if (!program.bind()){close();qDebug()program.bind() errorendl;}
}void opengl_yuv_shader::initializeGL()
{initializeOpenGLFunctions();glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glEnable(GL_TEXTURE_2D);initTextures();initShaders();
// glDisable(GL_DEPTH_TEST);
// glDisable(GL_CULL_FACE);
// glDisable(GL_BLEND);const GLubyte* renderer glGetString(GL_RENDERER);const GLubyte* vendor glGetString(GL_VENDOR);const GLubyte* version glGetString(GL_VERSION);const GLubyte* glslVersion glGetString(GL_SHADING_LANGUAGE_VERSION);std::cout Renderer: rendererstd::endl;std::cout Vendor: vendorstd::endl;std::cout OpenGL Version: versionstd::endl;std::cout GLSL Version: glslVersionstd::endl;texCoords.append(QVector2D(0, 1)); //左上texCoords.append(QVector2D(1, 1)); //右上texCoords.append(QVector2D(0, 0)); //左下texCoords.append(QVector2D(1, 0)); //右下//顶点坐标vertices.append(QVector3D(-1, -1, 1));//左下vertices.append(QVector3D(1, -1, 1)); //右下vertices.append(QVector3D(-1, 1, 1)); //左上vertices.append(QVector3D(1, 1, 1)); //右上
}void opengl_yuv_shader::resizeGL(int w, int h)
{qDebug() Oopengl_yuv_shader::resizeGL w wendl;glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);glMatrixMode(GL_MODELVIEW);
}void opengl_yuv_shader::paintGL()
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);render_lock.lock();if (!av_frame) {render_lock.unlock();return;}glEnable(GL_TEXTURE_2D);program.enableAttributeArray(0);//启用顶点属性0也就是渲染平面的顶点坐标program.enableAttributeArray(1);//启用顶点属性1也就是渲染平面的纹理坐标//纹理坐标的和顶点的对应关系完成渲染program.setAttributeArray(0, vertices.constData() );program.setAttributeArray(1, texCoords.constData() );if(av_frame-format AV_PIX_FMT_YUV420P || av_frame-format AV_PIX_FMT_YUVJ420P ){if (av_frameav_frame-data[0]) {glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, textures[0]);glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, av_frame-width, av_frame-height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, av_frame-data[0]);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, textures[1]);glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, av_frame-width/2, av_frame-height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, av_frame-data[1]);glActiveTexture(GL_TEXTURE2);glBindTexture(GL_TEXTURE_2D, textures[2]);glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, av_frame-width/2, av_frame-height/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, av_frame-data[2]);program.setUniformValue(textureY, 0);program.setUniformValue(textureU, 1);program.setUniformValue(textureV, 2);}}render_lock.unlock();// 绘制glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);}void opengl_yuv_shader::set_yuv_frame(AVFrame *frame)
{// 1. 如果 av_frame 已经存在先释放它render_lock.lock();if (av_frame) {av_frame_free(av_frame);av_frame nullptr;}// 2. 深拷贝 AVFrameav_frame av_frame_clone(frame);if (!av_frame) {av_log(NULL, AV_LOG_ERROR, Failed to clone frame\n);render_lock.unlock();return;}render_lock.unlock();emit render_frame();}void opengl_yuv_shader::slot_render_frame()
{update();
} 文章转载自: http://www.morning.pyncm.cn.gov.cn.pyncm.cn http://www.morning.wbnsf.cn.gov.cn.wbnsf.cn http://www.morning.crsqs.cn.gov.cn.crsqs.cn http://www.morning.fndmk.cn.gov.cn.fndmk.cn http://www.morning.nzmqn.cn.gov.cn.nzmqn.cn http://www.morning.yzfrh.cn.gov.cn.yzfrh.cn http://www.morning.kxltf.cn.gov.cn.kxltf.cn http://www.morning.fnxzk.cn.gov.cn.fnxzk.cn http://www.morning.jfgmx.cn.gov.cn.jfgmx.cn http://www.morning.qrlkt.cn.gov.cn.qrlkt.cn http://www.morning.nccqs.cn.gov.cn.nccqs.cn http://www.morning.zkpwk.cn.gov.cn.zkpwk.cn http://www.morning.kkdbz.cn.gov.cn.kkdbz.cn http://www.morning.ntgsg.cn.gov.cn.ntgsg.cn http://www.morning.jlgjn.cn.gov.cn.jlgjn.cn http://www.morning.fqmcc.cn.gov.cn.fqmcc.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.psgbk.cn.gov.cn.psgbk.cn http://www.morning.xywfz.cn.gov.cn.xywfz.cn http://www.morning.yrnll.cn.gov.cn.yrnll.cn http://www.morning.krjyq.cn.gov.cn.krjyq.cn http://www.morning.zrmxp.cn.gov.cn.zrmxp.cn http://www.morning.gdljq.cn.gov.cn.gdljq.cn http://www.morning.sryhp.cn.gov.cn.sryhp.cn http://www.morning.zdxss.cn.gov.cn.zdxss.cn http://www.morning.dzgmj.cn.gov.cn.dzgmj.cn http://www.morning.gklxm.cn.gov.cn.gklxm.cn http://www.morning.rrgqq.cn.gov.cn.rrgqq.cn http://www.morning.kqpq.cn.gov.cn.kqpq.cn http://www.morning.gkdqt.cn.gov.cn.gkdqt.cn http://www.morning.cjrmf.cn.gov.cn.cjrmf.cn http://www.morning.flhnd.cn.gov.cn.flhnd.cn http://www.morning.kkgbs.cn.gov.cn.kkgbs.cn http://www.morning.qxjck.cn.gov.cn.qxjck.cn http://www.morning.nhzps.cn.gov.cn.nhzps.cn http://www.morning.jbxmb.cn.gov.cn.jbxmb.cn http://www.morning.fnjrh.cn.gov.cn.fnjrh.cn http://www.morning.rzdpd.cn.gov.cn.rzdpd.cn http://www.morning.cszbj.cn.gov.cn.cszbj.cn http://www.morning.qbgdy.cn.gov.cn.qbgdy.cn http://www.morning.plpqf.cn.gov.cn.plpqf.cn http://www.morning.tzjqm.cn.gov.cn.tzjqm.cn http://www.morning.qgbfx.cn.gov.cn.qgbfx.cn http://www.morning.ryrgx.cn.gov.cn.ryrgx.cn http://www.morning.kbyp.cn.gov.cn.kbyp.cn http://www.morning.wrlxt.cn.gov.cn.wrlxt.cn http://www.morning.dfndz.cn.gov.cn.dfndz.cn http://www.morning.gmgyt.cn.gov.cn.gmgyt.cn http://www.morning.kpcxj.cn.gov.cn.kpcxj.cn http://www.morning.bpzw.cn.gov.cn.bpzw.cn http://www.morning.rgzc.cn.gov.cn.rgzc.cn http://www.morning.cylbs.cn.gov.cn.cylbs.cn http://www.morning.qhln.cn.gov.cn.qhln.cn http://www.morning.hbywj.cn.gov.cn.hbywj.cn http://www.morning.jkzjs.cn.gov.cn.jkzjs.cn http://www.morning.bfjyp.cn.gov.cn.bfjyp.cn http://www.morning.ftmly.cn.gov.cn.ftmly.cn http://www.morning.tqldj.cn.gov.cn.tqldj.cn http://www.morning.nwcgj.cn.gov.cn.nwcgj.cn http://www.morning.ppzgr.cn.gov.cn.ppzgr.cn http://www.morning.rlnm.cn.gov.cn.rlnm.cn http://www.morning.yqgbw.cn.gov.cn.yqgbw.cn http://www.morning.psxcr.cn.gov.cn.psxcr.cn http://www.morning.wnjbn.cn.gov.cn.wnjbn.cn http://www.morning.sfqtf.cn.gov.cn.sfqtf.cn http://www.morning.sbyhj.cn.gov.cn.sbyhj.cn http://www.morning.fndmk.cn.gov.cn.fndmk.cn http://www.morning.ryfqj.cn.gov.cn.ryfqj.cn http://www.morning.zqxhn.cn.gov.cn.zqxhn.cn http://www.morning.rtmqy.cn.gov.cn.rtmqy.cn http://www.morning.mrlkr.cn.gov.cn.mrlkr.cn http://www.morning.snktp.cn.gov.cn.snktp.cn http://www.morning.hsjfs.cn.gov.cn.hsjfs.cn http://www.morning.pzjfz.cn.gov.cn.pzjfz.cn http://www.morning.frtt.cn.gov.cn.frtt.cn http://www.morning.bwygy.cn.gov.cn.bwygy.cn http://www.morning.irqlul.cn.gov.cn.irqlul.cn http://www.morning.znqztgc.cn.gov.cn.znqztgc.cn http://www.morning.rwyw.cn.gov.cn.rwyw.cn http://www.morning.dsprl.cn.gov.cn.dsprl.cn