在没有 hwdownload 的情况下将 ffpmeg OpenCL 过滤器输出传递给 NVenc?

Posted

技术标签:

【中文标题】在没有 hwdownload 的情况下将 ffpmeg OpenCL 过滤器输出传递给 NVenc?【英文标题】:Pass ffpmeg OpenCL filter output to NVenc without hwdownload? 【发布时间】:2021-03-17 07:31:46 【问题描述】:

我正在尝试使用 ffmpeg 对 UHD HDR 视频流进行色调映射(和调整大小)。以下命令:

ffmpeg -vsync 0 -hwaccel cuda -init_hw_device opencl=ocl -filter_hw_device ocl 
    -threads 1 -extra_hw_frames 3 -c:v hevc_cuvid -resize 1920x1080 -i "INPUT.hevc" 
    -vf "hwupload,
         tonemap_opencl=tonemap=mobius:param=0.01:desat=0:r=tv:p=bt709:t=bt709:m=bt709:format=nv12,
         hwdownload,format=nv12,hwupload_cuda" 
    -c:v hevc_nvenc -b:v 8M "OUTPUT.hevc"

似乎可以工作(在 RTX 3080 上大约 200 FPS)。但是,我注意到它仍然使用一个 CPU 内核,而 GPU 使用率仅报告为 60-70%。当我只调整大小而不使用任何过滤器时,我会在 100% 的 GPU 使用情况下获得大约 400FPS。

我怀疑最后的hwdownload,format=nv12,hwupload_cuda 语句有问题,因为这增加了主内存的绕行。我尝试只使用hwupload_cuda 而不是不使用hwdownload(如此处建议:https://***.com/a/55747785/929037 在此答案末尾附近的过滤器示例中),但随后出现以下错误:

Impossible to convert between the formats supported by the filter 'Parsed_tonemap_opencl_1' and the filter 'auto_scaler_0'
Error reinitializing filters!
Failed to inject frame into filter network: Function not implemented
Error while processing the decoded data for stream #0:0

尝试使用hwmap导致

Assertion dst->format == AV_PIX_FMT_OPENCL failed at C:/code/ffmpeg/src/libavutil/hwcontext_opencl.c:2814

是否可以避免这种额外的hwdownload

【问题讨论】:

【参考方案1】:

至少现在没有。

在 Nvidia 为它们发布互操作方法之前,ffmpeg 中不提供 Cuda 和 OpenCL 设备之间的零拷贝纹理共享又名 hwmap 过滤器。

https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__INTEROP.html

Intel 和 AMD 为 D3D11/VAAPI 提供了一些 OpenCL 扩展OpenCL 互操作,并且可以将一个共享图像(例如 NV12)拆分到不同的平面(例如平面 Y 和 UV)。 比如英特尔的cl_intel_va_api_media_sharingcl_intel_d3d11_nv12_media_sharing和AMD的cl_amd_planar_yuv

至于 Nvidia,他们确实有用于 D3D11 的 cl_nv_d3d11_sharingOpenCL 互操作,但我认为它在 Cuda 方面效果不佳。

另一种解决方案是将色调映射算法移植为 Cuda 过滤器,但这需要一些时间。一旦完成,可以预期巨大的速度提升。您可以像scale_cudaoverlay_cuda 过滤器等轻松使用它。

我看到英特尔已经在其最新的 iGPU 中通过硬件功能支持tonemap_vaapi 过滤器。不确定 Nvidia NVENC 在他们的 ASIC 中是否有类似的。

【讨论】:

感谢您的详细解答!色调映射过滤器的 cuda 版本目前正在开发中还是只是假设? 在有人将其变为现实之前,它仍处于概念之中。 AFAIKtonemap_opencl 中的一些算法是从 libplacebo 移植的。如果有任何 Cuda 和 ffmpeg 专家想要研究它,那就太好了。

以上是关于在没有 hwdownload 的情况下将 ffpmeg OpenCL 过滤器输出传递给 NVenc?的主要内容,如果未能解决你的问题,请参考以下文章

在没有 UINavigationController 的情况下将 UIBarButtonItem 添加到 UINavigation 栏

Django:如何在没有''的情况下将数组传输到javascript?

如何在没有 usermod 的情况下将用户添加到组?

如何在没有循环的情况下将文件逐行读入变量

在没有容器的情况下将数据源设置为 JPA

在没有 CoreText 的情况下将 UITextView 中的文本包装在 UIImage 周围