如何使用GPU高效渲染和处理视频流?

时间:2009-01-26 16:47:17

标签: opengl gpu shader

我计划开发一个使用C ++,Qt和OpenGL进行实时视频操作的工具。视频叠加不是一种选择,因为着色器应该用于帧处理。目前我想到了以下一系列步骤:

  1. 解码视频(CPU)
  2. 预处理它(可选,CPU)
  3. 将其转移到视频内存(使用DMA的GPU)
  4. 使用顶点和片段着色器(GPU)进一步处理它
  5. 渲染(GPU)
  6. 我正在寻找一些一般性建议,解释这里可以使用的扩展或技术。是否有充分的理由使用Direct3D?

5 个答案:

答案 0 :(得分:2)

如果您是Linux,NVIDIA最近在180.xx系列中的驱动程序通过VDPAU api(视频解码和演示文稿)添加了对视频解码的支持。许多主要项目都与api集成,包括mplayer,vlc,ffmpeg和mythtv。我不知道所有细节,但它们为许多编解码器提供api,包括常见的子操作和比特流操作。

在直接进入CUDA(我假设VDPAU可能会使用)之前,我会先看一下这里。

答案 1 :(得分:2)

首先,在PC上没有明确的方法来使用DMA。驱动程序可能使用它,或者可能使用其他东西。

在任何情况下,步骤3将是“更改图形卡上的纹理数据”。在OpenGL中,PBO(像素缓冲区对象)扩展或良好的旧glTexSubImage *功能。在D3D9中,它是纹理或其他方式的LockRect(例如,在划痕纹理上的LockRect,然后blit到GPU纹理)。任何这些都可能使用DMA,但你无法确定。

然后数据在纹理中。您可以使用某些着色器将其渲染到屏幕(例如,进行YCbCr转换),或渲染到其他纹理中以执行更复杂的处理效果(例如模糊/发光/...)。

使用Direct3D更容易,因为有明确定义的“做事方式”。在OpenGL中,有很多选项可以做任何事情,你必须以某种方式找出哪些是快速的(有时快速路径在不同的平台或硬件上是不同的)。

答案 2 :(得分:1)

要将帧数据从cpu传输到gpu,您可能需要查看PBO。同时检查this

此外,如果您正在使用着色器,则可以通过在片段着色器(YCbCr到RGB)中进行色彩空间转换来减轻cpu负担。

“进一步处理”和“渲染”步骤通常几乎是一样的,在着色器中做很酷的东西并将它混合到帧缓冲区。如果您想混合和匹配视频和不同的效果,FBO也很有用。

答案 3 :(得分:0)

作为替代方案,您可以查看一些用于执行通用GPU编程(GPGPU)的不同语言,例如NVIDIA的CUDA或ATI的Stream SDK。根据您的选择,您可以将自己限制为一个品牌的GPU。使用这些语言的原因是在抽象级别上工作,这种抽象级别更接近于普通的高级编程,而不是使用着色器。

我对你想做的事没有经验所以我不能说着色器实际上是否更适合这项工作,但你可以考虑一下。必须要说的是,算法设计仍然与普通代码有些不同,需要花费一些精力来解决它(我只使用过CUDA,但它们似乎都使用类似的抽象)。

我想如果你对着色器工作有相当多的经验,你可能不值得为学习新平台而烦恼。

答案 4 :(得分:0)

以下步骤应该这样做:

  1. 将视频解码为YUV

    这通常是解码器库的功能。

  2. 作为纹理加载到OpenGL中

  3. 将YUV转换为RGB

    由于您不想使用叠加层,因此必须手动转换。 Here是使用着色器的示例。

  4. 将转换的纹理放在四边形上并渲染到屏幕