c++ - ffmpeg转OpenGL纹理黑屏

标签 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);
    }

最佳答案

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

也用于使用 glTexImage2D你正在通过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]);

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

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

关于c++ - ffmpeg转OpenGL纹理黑屏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21277885/

相关文章:

c++ - arb 的静态 ctor/dtor 观察器。 C++类

c++ - QtCreator 项目上的 "Symbol(s) not found for architecture x86_64"

tensorflow - 安装 tensorflow 时包 'ffmpeg' 没有安装候选

python - 使用 Python MoviePY 连接视频太慢

c++ - 如何在 GNU Makefile 中只获取没有扩展名的文件名?

c++ - C++单例中的指针和非指针实例

c++ - 使用顶点着色器时如何获得平坦的非插值颜色

c++ - OpenGL 深度不工作,三角形消失

opengl - 从缓冲区读取 - OpenGL

symfony - 避免在 web 文件夹中缓存文件