如何使用openGL创建视频播放器

时间:2013-10-23 09:54:15

标签: opengl video rendering video-player

我有一个自定义视频解码器。对于这个解码器,每当我提供一个H.264文件(只有视频元素而不是音频)作为输入时,我得到一组YUV帧作为我的输出。然后,我将此YUV帧转换为RGB24帧并将其呈现在OpenGL中。这种转换和渲染同时发生,即逐帧发生,从而看起来就像我正在观看视频一样。

完成上述操作后,我的下一个任务是实现其他功能,如播放,暂停,后退,前进等。

目前我只是渲染帧以及如何解码并转换为RGB。那就是帧率约为60-70 fps。现在如果我必须实现这个播放/暂停功能,那我该怎么办呢。也就是说,如果按下暂停,解码器应该等到我按下播放按钮。

为此提供一些解决方案。

1 个答案:

答案 0 :(得分:0)

有点奇怪的是,你设法做了这么多,并且在项目的这一点上陷入困​​境。如果您运行OpenGL程序,我假设您有一些无限循环,您可以捕获所有事件(鼠标,键)以及从文件中读取图像并将它们渲染到屏幕(使用OpenGL)。这种应用程序通常在多线程环境中运行,特别是读取文件。你可能想要一些缓冲区,你总是存储类似下一秒动画的东西(或更多),当你执行事件循环时你从那个缓冲区读取。同时,当你从缓冲区读取东西时,从磁盘读取数据的线程需要用新信息填充缓冲区。

这可能是使用生产者 - 消费者算法。请注意,您不需要在多线程环境中执行此操作,但如果您的系统无法以30 fps的速度运行,则可能会出现连续性问题。在事件循环中,您可以读取接下来的20帧或10或其他内容,然后从缓冲区,渲染等中读取下一个图像。

在此循环中,如果查看者已按下暂停键(比如空格),则只需将文件和渲染的读取传递给循环中的屏幕任务。或者,您可以在渲染之前将整个文件读取到内存中。

// event loop
 while (1) {
    char key = nextEvent(...)
    if (key == 'x') quiteApp();
    else if (key == 'p') { pauseApp = (pauseApp == true) ? false : true; }
    if (!pauseApp) {
        // adjust the number of frames your read in each loop depending
        // on your frame rate. If you frame rate drops below 30 fps
        // read less frames, etc.
        readFrames(&buffer, videoFile, 10);
        getNextFrameFromBuffer(buffer, frameBuffer);
        displayFrameuBuffer(frameCount, frameBuffer);
    }
    frameCount++;
    // do time synchronisation here so that you always play at given frame
    // rate which is likely to be 30 fps.
    ...
}