我的问题:
我有一个视频(假设为25FPS),必须在屏幕上使用opengles 2.0进行渲染。 为了阅读视频,我使用解码器将该视频解码为opengl es纹理。使用renderpass,我在屏幕上绘制这个纹理。
我要做的是从解码器获取图像将其上传到gpu,调用着色器程序并在屏幕上渲染图像。如果视频有25FPS,我必须以40ms步长(1000ms / 25FPS)更新屏幕。
在每一步中我都有以下内容:
到目前为止它正在发挥作用。 现在它发生,解码器花费超过40ms来解码帧。这不会一直发生,但有时会发生。
解决方案是构建缓存。意思是,在显示第一个之前,我会渲染5个图像。这带来了一个问题,它必须发生异步,因此可以构建缓存并同时呈现屏幕。如果发生这种情况,您可以在视频中看到它,因为它不再是“流畅的”。
我的问题:
OR
我已经尝试过了:
答案 0 :(得分:1)
请记住,在OpenGL中,如果您不清除并重绘屏幕,则前一个图像将保持不变。如果新框架没有及时准备就绪,那就什么都不做。
听起来你有两个线程:一个解码帧,一个渲染它们。这很好。
如果调用render()并且未及时准备好新帧,则应立即返回render方法。不要清除或交换缓冲区。屏幕将被保留。
现在,当帧重复两次时,用户/可能/偶尔会发出打嗝声。 25 fps是一种不自然的帧速率(OpenGL仅支持60/30/15 /等),因此它不会完全符合屏幕刷新率。
你可以忍受这个(用户可能不会注意到)。或者你可以通过缓冲帧强制播放到30 fps。
一个好主意是在解码器和渲染器之间放置一个消息队列。它可能是一帧或几帧深。它可以是数组,链表或环形缓冲区。这允许解码器在渲染绘制不同纹理时上传到许多缓存纹理中。
解码器在进入队列时将帧添加到队列中。渲染器以固定速率(30 fps)运行。您可以暂停渲染,直到N帧被缓冲。