我用 Qt
、OpenGl
和 FFMpeg
制作了一个视频播放器,效果很好。
现在我想使用多线程和缓冲区来获得更好的性能。我已经设置了一个线程来解码帧并将其存储在 QMap 中:
QMap<int, uint8_t *> myBuffer;
第一个整数是时间码,第二个指向 OpenGl 纹理。
每次解码帧时,我都会使用 new
将其添加到缓冲区中,并在读取帧后立即将其删除
。
假设这不是最好的方法,不是在内存管理方面(没有内存泄漏),而是在性能方面。
有没有更好的方法来做到这一点?
最佳答案
您可以直接解码为 OpenGL 像素缓冲区对象。创建一个数量(3 或 4 个应该足够)的 PBO,并让渲染器线程使用 glMapBuffer
将其中至少 2 个映射到进程地址空间,并将位置和 PBO ID 排队到可用缓冲区池中。要解码帧,请将指针/ID 从可用的 PBO 池中取出并解码到提供的内存中。解码帧后,将使用的 PBO 的 ID 放入“已解码”池中,渲染器线程使用该池通过 glUnmapBuffer();
取消映射,然后立即使用 加载到纹理中>glTexSubImage2D
;纹理上传是异步发生的。将纹理 ID 排入“准备显示”队列/FIFO。然后让渲染器从“准备显示”下一个显示纹理出队;通过在“准备显示”FIFO 帧中保留至少 3 个元素,在绘制先前解码的帧时异步上传帧,而无需 OpenGL 阻塞,因为它必须等待前面的步骤完成。
关于带有 Qt 的 C++ 缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22665220/