2013-10-23 30 views
2

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

一旦我做了上面,我的下一个任务是实现其他功能,如播放,暂停,后退一步,向前一步,等

目前我只是渲染帧作为连带如何解码并转换为RGB。这是帧率在60-70帧/秒左右。现在,如果我必须实现这种播放/暂停功能,那么我应该如何继续。这就是说,如果按下暂停,解码器应该等到我按下播放按钮。

为此提供一些解决方案。

回答

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. 
    ... 
}