OpenGL视频播放器的纹理缓冲区

时间:2011-07-21 11:07:19

标签: multithreading opengl textures video-processing

我正在使用OpenGL,Ffmpeg和SDL来播放视频,目前正在优化获取帧,解码帧,将它们从YUV转换为RGB,将它们上传到纹理并在四边形上显示纹理的过程。这些阶段中的每一个都由一个单独的线程执行,并且它们被写入由SDL互斥体和条件控制的共享缓冲区(除了上传和显示纹理时,它们需要在相同的上下文中)。

我让播放器在单独的线程上使用解码,转换和OpenGL上下文工作正常,但我意识到因为视频是每秒25帧,我只从缓冲区获得转换后的帧,将其上传到OpenGL并绑定它/在OpenGL线程中每40毫秒显示一次。由于这个40ms的间隙,渲染循环绕过大约6-10次没有显示它显示的每一帧的下一帧。

因此我决定为纹理设置一个缓冲区也是个好主意,并设置一个纹理数组,用glGenTextures()和我需要的glParameters等创建和初始化。

当自上次帧刷新以来还没有40ms时,运行一个方法,它从转换缓冲区中抓取下一个转换后的帧,并通过绑定它然后调用glTexSubImage2D()将其上传到纹理缓冲区中的下一个自由纹理。 。当自最后一帧刷新以来已经过了40ms,运行了一个单独的方法,它从纹理缓冲区中抓取下一个GLuint纹理并将其与glBindTexture()绑定。因此,我只是将之前正在完成的工作(从转换缓冲区,上传,显示中获取)拆分为单独的方法(从转换缓冲区中获取,上传到纹理缓冲区|并从纹理缓冲区中获取,显示)以利用浪费的时间在40毫秒之间刷新。

听起来合理吗?因为当跑步时,视频一直以零星的方式停止,有时大约4帧被播放(每40ms)但是然后有2秒的间隙,然后显示1帧,然后是3秒的间隙而且视频完全无法观看。

代码几乎与我如何管理转换线程从解码缓冲区中获取解码帧,将它们从YUV转换为RGB然后将它们放入转换缓冲区,因此无法看到大量瓶颈可能存在的位置。 / p>

瓶颈可能在OpenGL方面吗?事实是我将新的图像数据存储到10个不同的纹理这个问题就像从纹理缓冲区中抓取新纹理一样,原始数据在视频内存上的内存位置方面可能距离最后一个数百万英里。 ?这是我唯一的尝试答案,但我不太了解OpenGL如何在内部工作,这就是我在这里发帖的原因。

有人有什么想法吗?

1 个答案:

答案 0 :(得分:6)

我不是OpenGL专家,但我对瓶颈的猜测是纹理在系统内存中正确初始化,但是在“错误”时间发送到视频内存(就像一次性而不是尽快发送到视频内存) ),拖延管道。使用glTexSubImage2D时,无法保证纹理何时到达视频内存,直到绑定它为止。

在Google上搜索似乎像素缓冲对象可以让您更好地控制它们在视频内存中的位置:http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=262523