zoukankan      html  css  js  c++  java
  • 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;
    "
                "uniform sampler2D textureY;
    "
                "uniform sampler2D textureUV;
    "
                "void main(void)
    "
                "{
    "
                "vec3 yuv; 
    "
                "vec3 rgb; 
    "
                "yuv.x = texture2D(textureY, textureOut.st).r - 0.0625; 
    "
                "yuv.y = texture2D(textureUV, textureOut.st).r - 0.5; 
    "
                "yuv.z = texture2D(textureUV, textureOut.st).g - 0.5; 
    "
                "rgb = mat3( 1,       1,         1, 
    "
                            "0,       -0.39465,  2.03211, 
    "
                            "1.13983, -0.58060,  0) * yuv; 
    "
                "gl_FragColor = vec4(rgb, 1); 
    "
                "}
    ";
        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[2];
        glGenTextures(2,ids);
        idY = ids[0];
        idUV = ids[1];
        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, 0, 2, 2*sizeof(GLfloat));
        program.setAttributeBuffer("textureIn",GL_FLOAT,2 * 4 * sizeof(GLfloat),2,2*sizeof(GLfloat));
    
        glActiveTexture(GL_TEXTURE0 + 1);
        glBindTexture(GL_TEXTURE_2D,idY);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RED,w,h,0,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 + 0);
        glBindTexture(GL_TEXTURE_2D,idUV);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RG,w >> 1,h >> 1,0,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",0);
        program.setUniformValue("textureY",1);
        glDrawArrays(GL_QUADS,0,4);
        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, 0, 2, 2*sizeof(GLfloat));
        program.setAttributeBuffer("textureIn",GL_FLOAT,2 * 4 * sizeof(GLfloat),2,2*sizeof(GLfloat));
    
        glActiveTexture(GL_TEXTURE0 + 1);
        glBindTexture(GL_TEXTURE_2D,idY);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RED,w,h,0,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 + 0);
        glBindTexture(GL_TEXTURE_2D,idUV);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RG,w >> 1,h >> 1,0,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",0);
        program.setUniformValue("textureY",1);
        glDrawArrays(GL_QUADS,0,4);
        program.disableAttributeArray("vertexIn");
        program.disableAttributeArray("textureIn");
        program.release();
    }
    最后写一个窗口类继承 QOpenGLWidget
    重写两个函数
    void initializeGL(); //调用上面渲染类的初始化函数
    void paintGL();//调用上面渲染类的渲染函数
    
    
    
  • 相关阅读:
    DAL层中根据ID删除方法(常用)
    DAL层联合查询及条件查询方法(常用)
    WPF中DataGrid在没有数据的时候也可以显示水平滚动条
    C#使用SharpZipLib创建压缩文件,并指定压缩文件夹路径(解决SharpZipLib压缩长路径显示问题)
    WPF的DataGrid的某个列绑定数据的三种方法(Binding、Converter、DataTrigger)
    WPF实现背景透明磨砂,并通过HandyControl组件实现弹出等待框
    C#使用FileSystemWatcher来监控指定文件夹,并使用TCP/IP协议通过Socket发送到另外指定文件夹
    C#使用Parallel处理数据同步写入Datatable并使用BulkInsert批量导入数据库
    C#编写运行在Linux环境下的采用Mediainfo来获取多媒体文件信息的代码
    C#使用iTextSharp+ZXing.Net+FreeSpire.PDF生成和打印pdf文档
  • 原文地址:https://www.cnblogs.com/nanqiang/p/10224867.html
Copyright © 2011-2022 走看看