在没有 hwdownload 的情况下将 ffpmeg OpenCL 过滤器输出传递给 NVenc?
Pass ffpmeg OpenCL filter output to NVenc without hwdownload?
我正在尝试使用 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%。当我只在没有任何过滤器的情况下调整大小时,我得到大约 400FPS 和 100% GPU 使用率。
我怀疑最后的 hwdownload,format=nv12,hwupload_cuda
语句有问题,因为这增加了一条通过主内存的弯路。我尝试只使用 hwupload_cuda
而不是 hwdownload
(就像这里建议的那样: 在这个答案末尾的过滤器示例中),但后来我收到以下错误:
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
?
至少暂时不会。
Cuda 和 OpenCL 设备之间的零拷贝纹理共享又名 hwmap
过滤器在 ffmpeg 中不可用,直到 Nvidia 为它们发布互操作方法。
https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__INTEROP.html
英特尔和 AMD 为 D3D11/VAAPI<->OpenCL 互操作提供了一些 OpenCL 扩展,并且可以将一个共享图像(例如 NV12)拆分为不同的平面(例如平面 Y 和 UV)。
比如AMD的cl_intel_va_api_media_sharing
cl_intel_d3d11_nv12_media_sharing
from Intel and cl_amd_planar_yuv
。
至于 Nvidia,他们确实有 cl_nv_d3d11_sharing
用于 D3D11<->OpenCL 互操作,但我认为它在 Cuda 方面效果不佳。
另一种解决方案是将色调映射算法移植为 Cuda 过滤器,但这需要一些时间。一旦完成,可以预期会有巨大的速度提升。您可以像 scale_cuda
或 overlay_cuda
过滤器等一样轻松使用它。
我看到英特尔已经在其最新的 iGPU 中支持 tonemap_vaapi
通过硬件功能进行过滤。不确定 Nvidia NVENC 在他们的 ASIC 中是否有类似的。
我正在尝试使用 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%。当我只在没有任何过滤器的情况下调整大小时,我得到大约 400FPS 和 100% GPU 使用率。
我怀疑最后的 hwdownload,format=nv12,hwupload_cuda
语句有问题,因为这增加了一条通过主内存的弯路。我尝试只使用 hwupload_cuda
而不是 hwdownload
(就像这里建议的那样:
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
?
至少暂时不会。
Cuda 和 OpenCL 设备之间的零拷贝纹理共享又名 hwmap
过滤器在 ffmpeg 中不可用,直到 Nvidia 为它们发布互操作方法。
https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__INTEROP.html
英特尔和 AMD 为 D3D11/VAAPI<->OpenCL 互操作提供了一些 OpenCL 扩展,并且可以将一个共享图像(例如 NV12)拆分为不同的平面(例如平面 Y 和 UV)。
比如AMD的cl_intel_va_api_media_sharing
cl_intel_d3d11_nv12_media_sharing
from Intel and cl_amd_planar_yuv
。
至于 Nvidia,他们确实有 cl_nv_d3d11_sharing
用于 D3D11<->OpenCL 互操作,但我认为它在 Cuda 方面效果不佳。
另一种解决方案是将色调映射算法移植为 Cuda 过滤器,但这需要一些时间。一旦完成,可以预期会有巨大的速度提升。您可以像 scale_cuda
或 overlay_cuda
过滤器等一样轻松使用它。
我看到英特尔已经在其最新的 iGPU 中支持 tonemap_vaapi
通过硬件功能进行过滤。不确定 Nvidia NVENC 在他们的 ASIC 中是否有类似的。