【问题标题】:How to display RGB24 video frame using opengl如何使用opengl显示RGB24视频帧
【发布时间】:2013-10-14 14:25:53
【问题描述】:

我的任务是使用 openGL's glut 库渲染一组 50 个 RGB 帧。

我试过了: 在 3D 立方体旋转中,我有一组顶点用于将其渲染到窗口。但是,在渲染 RGB 帧的情况下应该怎么做呢?下面是我用来渲染 3d 立方体的代码:

#include <glut.h>

GLfloat vertices[24]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0};
GLfloat colors[24]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0};
GLubyte cubeIndices[24]={0,3,2,1,2,3,7,6,0,4,7,3,1,2,6,5,4,5,6,7,0,1,5,4};
static GLfloat theta[3]={0,0,0};
static GLint axis=2;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();
    glRotatef(theta[0],1.0,0.0,0.0);
    glRotatef(theta[1],0.0,1.0,0.0);
    glRotatef(theta[2],0.0,0.0,1.0);

    glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,cubeIndices);

    glutSwapBuffers();
    glFlush();
}

void spinCude()
{
    theta[axis]+=2.0;
    if(theta[axis]>360.0)
        theta[axis]-=360.0;
    display();
}
void init()
{
    glMatrixMode(GL_PROJECTION);
    glOrtho(-2.0,2.0,-2.0,2.0,-10.0,10.0);
    glMatrixMode(GL_MODELVIEW);
}

void mouse(int btn,int state, int x,int y)
{
    if(btn==GLUT_LEFT_BUTTON&& state==GLUT_DOWN) axis=0;
    if(btn==GLUT_MIDDLE_BUTTON&& state==GLUT_DOWN) axis=1;
    if(btn==GLUT_RIGHT_BUTTON&& state==GLUT_DOWN) axis=2;
}

void main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);

    glutInitWindowSize(500,500);
    glutCreateWindow("Simple YUV Player");
    init();
    glutDisplayFunc(display);

    glutIdleFunc(spinCude);
    glutMouseFunc(mouse);
    glEnable(GL_DEPTH_TEST);

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3,GL_FLOAT,0,vertices);

    //glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3,GL_FLOAT,0,colors);

    glutMainLoop();

}

谁能给我一些示例或教程,以便我可以修改上面的代码以显示 RGB 帧。

【问题讨论】:

    标签: opengl rendering rgb rgba


    【解决方案1】:

    一旦您将 RGB 帧作为内存中的原始数据,事情就非常简单了。使用glGenTextures 创建纹理,使用glBindTexture 绑定它并通过glTexImage2DglTexSubImage2D 上传数据。然后用该纹理渲染一个全屏四边形或任何你喜欢的东西。这样做的好处是,您可以在场景中渲染多个“虚拟”电视,只需渲染具有相同纹理的多个四边形,想象一个电视商店,其中相同的视频在十几台电视上运行。 glDrawPixels 也可能有用,但它的通用性要低得多。

    我不知道通过纹理上传是否可行(硬件加速电影播放程序如 VLC 很可能会做一些更高级的事情),但这应该是一个好的开始。

    【讨论】:

    • 感谢您的回复。它真的是一个很好的信息。但我需要一个简单的示例或涉及上述说明的代码 sn-p。请建议一些链接或一些代码,我会接受你的回答。请帮忙。
    • 任何基本的纹理教程都可以使用。网上有很多,例如nehe.gamedev.net/tutorial/texture_mapping/12038
    【解决方案2】:

    正如 Marius 已经建议的那样,首先实现纹理映射。任何纹理映射教程都可以做到这一点。

    使用 OpenGL 渲染帧并不是最好的,你应该尽量避免它们,因为它可能涉及客户端 -> 主机内存副本,这真的很昂贵(需要太多时间)或者只是占用太多很多内存。无论如何,如果你真的必须这样做,只需使用 glGenTextures 生成尽可能多的纹理,通过 glTexImage2D 将纹理加载到它们中,然后在每一帧中用一个简单的循环来翻转帧。

    附:从您的应用程序名称“YUV Player”来看,您可能还需要转换输入数据,因为 OpenGL 主要使用 RGB 而不是 YUV。

    【讨论】:

    • 客户端 -> 主机内存传输不一定成本太高。 PCIe 是多年以来的标准,您可以轻松地每帧传输几十兆像素,并且仍然以 60fps 为目标。请注意,如果输入数据是带有色度二次采样的 YUV(这对于数字视频来说并非不可能),则可以通过使用 YUV 数据并在 GPU 上转换为 RGB 来进一步降低带宽。按照您的建议提前生成 50 个纹理(或使用 3D 纹理或纹理数组)可能会消耗大量内存(取决于图像分辨率)。
    • 考虑到这个应用程序可能是一个测试应用程序,你是对的,尽管如果这应该是一个实时应用程序,你可能希望避免实时传输帧,即使 PCIe 速度很快,它也有限制也是。是的,我忘记了那些 3D 纹理!
    • @derhass,什么是更快的解决方案?假设我使用硬件解码器 api 解码了 h264 流 - 我有 uint_8 的向量 - 接下来我应该做什么来显示帧而不将其复制到主机内存?我对这个主题相当陌生。谢谢!
    • @OleksandrPapchenko 我不知道你为什么问这个,在一些评论中是写给我的。即使作为一个真正的问题发布,我也会将其视为“过于宽泛”(至少在被问到的非特定级别上)。如果你想使用 GL 来显示视频,你必须先学习 GL,而关于 stackoverflow 的文章不能教,也不是有意的。
    猜你喜欢
    • 2019-03-10
    • 2012-11-09
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多