如何将ffmpeg纹理转换为OpenGL纹理而不复制到CPU内存

5
这个ffmpeg示例演示了如何进行硬件解码:https://github.com/FFmpeg/FFmpeg/blob/release/4.2/doc/examples/hw_decode.c 在第109行,它执行了以下操作:
/* retrieve data from GPU to CPU */
            if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) < 0) {

我希望避免这种情况,因为这会花费时间。因此,我需要一种将已解码的视频(存在GPU内存中)重新使用并进行颜色转换的方法。
如何将GPU内存中的解码纹理转换为Open GL中的纹理而无需像上面的代码那样将其传回CPU内存?
如果上述方法不可行,如何在解码视频中使用OpenGL进行颜色转换?我听说ffmpeg支持将OpenGL着色器作为输入进行传递,所以我猜应该是可以的。
1个回答

6
简而言之:这很复杂。
根据ffmpeg在您的系统上使用的硬件后端,您可能需要进行DirectX/CUDA/OpenGL互操作。假设您正在使用VDPAU后端并希望将其与OpenGL互操作。看起来ffmpeg没有以文档方式从其公共接口公开该功能。
然而,基于vdpau_transfer_data_from的实现,似乎可以按以下方式从AVFrame中检索VdpVideoSurface
VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)frame->data[3];

从这里开始,您可以将其传递给NV_vdpau_interopNV_vdpau_interop2扩展中的VDPAURegisterVideoSurfaceNV以创建OpenGL纹理。

非常感谢,现在清楚多了!! 实际上,我打算支持Jetson Nano开发板,所以我想我必须使用CUDA。我已经找到了相同的方法,但是针对CUDA: https://github.com/FFmpeg/FFmpeg/blob/master/libavutil/hwcontext_cuda.c#L197 但是我没有看到任何"surface"。我也找到了与Direct X的互操作性 https://www.khronos.org/registry/OpenGL/extensions/NV/ 但没有针对CUDA的。也许是不同的文件吗? - PPP
1
@LucasZanella:(CUdeviceptr)src->data[i]不是指向你的CUDA图像的指针吗?我不知道是否可能直接从中创建一个OpenGL纹理,但你可以尝试将所有复制操作都在GPU上完成,而不必进入系统内存。 - Yakov Galka

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