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

3
我计划使用C++,Qt和OpenGL开发实时视频处理工具。由于帧处理需要使用着色器,所以视频叠加不是一个选项。目前,我想象了以下步骤:
  1. 解码视频(CPU)
  2. 预处理视频(可选,CPU)
  3. 将其传输到视频内存(使用DMA的GPU)
  4. 使用顶点和片段着色器进一步处理它(GPU)
  5. 渲染画面(GPU)
我正在寻找一些通用建议,介绍这里可以使用的扩展或技术。是否有充分的理由使用Direct3D?
5个回答

2
如果您是使用Linux操作系统,那么NVIDIA的最新驱动程序中的180.xx系列已经添加了通过VDPAU api(Video Decoding and Presentation something)进行视频解码的支持。许多重要项目都集成了该api,包括mplayer、vlc、ffmpeg和mythtv等。我不知道所有细节,但它们提供了许多编解码器的api,包括常见的子操作和比特流操作。
在使用CUDA之前,我建议您在这里查看一下(我假设VDPAU可能会使用CUDA)。

2

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

无论如何,第三步将是“在图形卡上更改纹理数据”。在OpenGL中,这是PBO(Pixel Buffer Object)扩展或良好的glTexSubImage*函数。在D3D9中,它是锁定纹理上的LockRect或其他方式(例如,在临时纹理上锁定矩形,然后复制到GPU纹理中)。其中任何一种都有可能使用DMA,但你不能确定。

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

使用Direct3D更容易,因为有清晰定义的“浪费方法”来完成任务。在OpenGL中,有更多的选项来完成任何事情,你必须想办法找出哪些方法是快速的(有时不同平台或硬件上的快速路径是不同的)。


1

为了将帧数据从CPU传输到GPU,您可能需要了解一下PBO。还要查看this

此外,如果您已经在使用着色器,可以通过在片段着色器中进行颜色空间转换来减轻CPU负担(从YCbCr转换为RGB)。

"进一步处理"和"渲染"步骤通常是相同的,可以在着色器中进行有趣的操作并将其混合到帧缓冲区中。如果想要混合和匹配视频和不同效果,则FBO也很有用。


0

以下步骤应该可以完成:

  1. 将视频解码为YUV格式

    这通常是解码器库所做的。

  2. 作为纹理加载到OpenGL中

  3. 将YUV转换为RGB格式

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

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


0

作为替代方案,您可以考虑使用一些不同的通用GPU编程语言(GPGPU),例如NVIDIA的CUDA或ATI的Stream SDK。但是,根据您选择的语言,您可能会限制自己只能使用某个品牌的GPU。使用这些语言的原因是要在更接近普通高级编程的抽象层次上工作,而不是使用着色器。

我没有关于您想做的事情的经验,因此无法确定着色器是否实际上更适合该工作,但这是您可以考虑的。必须说,算法设计仍然与普通代码有所不同,并且需要一些努力才能掌握它(我只使用过CUDA,但它们似乎都使用类似的抽象)。

我想,如果您具有相当多的着色器工作经验,学习新平台可能并不值得麻烦。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接