Ffmpeg到OpenGL纹理黑屏

时间:2014-01-22 08:35:54

标签: c++ opengl ffmpeg

我正在尝试从ffmpeg源创建纹理,但是我得到了黑屏。

这是代码

avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,
            &packet);

        // Did we get a video frame?
        if(frameFinished)
        {
         f++;

                pFrameRGB=avcodec_alloc_frame();
                struct SwsContext* swsContext = sws_getContext(pCodecCtx->width, pCodecCtx->height,
                        pCodecCtx->pix_fmt,
                        pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC,
                        NULL, NULL, NULL);
                if (swsContext == NULL) {
                 fprintf(stderr, "Cannot initialize the conversion context!\n");
                  exit(1);
                  };


                sws_scale(swsContext, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
                glGenTextures(1, &VideoTexture);
                glBindTexture(GL_TEXTURE_2D, VideoTexture);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexImage2D(GL_TEXTURE_2D, 0, 3, pCodecCtx->width, pCodecCtx->height, 0, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);
 }
}

// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
if (f>1) break;

奇怪的是,当我画画时我得到黑屏,我的视频不是黑色。

if (VideoTexture != 0)
    {
        glEnable(GL_TEXTURE_2D);
        glPushMatrix();
        glBindTexture(GL_TEXTURE_2D, VideoTexture);
        glBegin(GL_QUADS);
        glTexCoord2i(0, 0); glVertex2i(0, 0);
        glTexCoord2i(1, 0); glVertex2i(Width, 0);
        glTexCoord2i(1, 1); glVertex2i(Width, Height);
        glTexCoord2i(0, 1); glVertex2i(0, Height);
        glEnd();
        glPopMatrix();
        glDisable(GL_TEXTURE_2D);
    }

2 个答案:

答案 0 :(得分:0)

确保首先绘制四边形,尝试更改它的颜色以进行调试。还可以尝试使用glGetError()检查gl错误。

同样,对于使用glTexImage2D,您将3作为内部格式(第3个参数)。这看起来不是一个有效的参数,请尝试将其更改为GL_RGBGL_RGBA

            glTexImage2D(GL_TEXTURE_2D, 0, 3, pCodecCtx->width, pCodecCtx->height, 0, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);

应该是

            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, pCodecCtx->width, pCodecCtx->height, 0, GL_RGB, GL_UNSIGNED_BYTE, pFrameRGB->data[0]);

但是你还有另一个问题:每次解码一个帧时都会创建一个新的纹理对象,如果你不断创建新纹理并复制新数据,程序会在一段时间后崩溃。

我建议您创建一次纹理,然后使用glTexSubImage2D更新它们,而不是每次都创建新纹理。这样每个纹理都将作为缓冲区,从而模拟双缓冲。这对于完美的视频渲染非常重要。

答案 1 :(得分:0)

前段时间我写了一个用FFMPEG解码电影并将它们显示为OpenGL纹理的程序。如果您想查看代码,可以从

下载

http://cs.anu.edu.au/~Hugh.Fisher/2dstuff/GLFFPlay.tar

希望这有帮助。