2

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

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

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

提供一些相同的解决方案。

4

1 回答 1

0

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

这可能是使用生产者-消费者算法。请注意,尽管您不需要在多线程环境中执行此操作,但如果您的系统无法以 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.
    ...
}
于 2015-09-19T08:59:46.727 回答