使用这里提供的示例,我能够通过CUDA获得FFMPEG来解码HEVC编码的视频(任务管理器向我展示了我的测试程序使用了75%的GPU(。
我想更进一步,直接从GPU显示这些帧——很遗憾,必须将它们下载到CPU(就像上面的示例代码一样(,才能将它们作为OpenGL纹理重新上传到GPU,尤其是因为从YUV到RGB的转换在GPU上也更高效(我已经有了一个着色器(。
编辑:为了澄清我想做的事情,以下是FFMPEG通过avcodec_get_hw_config()
和av_hwdevice_get_type_name
:报告的解码设备列表
Hardware configurations:
0: Device Type: dxva2
1: Device Type: (none)
2: Device Type: d3d11va
3: Device Type: cuda
正如talonmies在评论中指出的那样,最后一个实际上是误名的,解码不是通过CUDA计算完成的,而是通过GPU芯片上的专用硬件(SIP(完成的。然而,毫无疑问,这就是我需要使用的设备,尽管它会被更恰当地指定为";NVDEC";。
编辑#2:通过NVDEC、cuviddec.c
查看负责解码的FFMPEG源代码文件,似乎没有任何选项可以防止从设备(GPU(内存到主机(CPU(内存的不必要复制。这意味着我很可能不得不自己针对NVDEC API编程。
查看示例cuda-samples/3_Imaging/cudaDecodeGL/ImageGL.cpp
,您将看到它使用CUDA API将OpenGL PBO映射为CUDA缓冲对象(cuGLRegisterBufferObject
或cuGraphicsGLRegisterBuffer
(,然后使用另一个CUDA API(cuGLMapBufferObject
(使PBO内存可用于CUDA处理。
不幸的是,在FFMPEG源代码中搜索这些函数中的任何一个都不会返回任何结果。