我正在尝试将此命令转换为在 nvenc hvec 视频编码器上工作,以使其更快并利用我的 3060:
ffmpeg -i video.mkv -i logo.png -filter_complex "[1]format=rgba,colorchannelmixer=aa=0.4[logo];[logo][0]scale2ref=oh*mdar:ih*0.05[logo][video];[video][logo]overlay=(main_w-overlay_w)-10:10[AddedLogo];[AddedLogo]subtitles=subtitles.ass[EndVideo]" -map 0:a -map [EndVideo] -b:v 2400k output.mp4
以下是我从文档/论坛中找到的信息拼凑起来的:
ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -i video.mkv -i logo.png -filter_complex "[1]format=rgba,colorchannelmixer=aa=0.4[logo];[logo][0]scale2ref=oh*mdar:ih*0.05[logo][video];[video][logo]overlay=(main_w-overlay_w)-10:10[AddedLogo];[AddedLogo]subtitles=subtitles.ass[EndVideo]" -map 0:a -map [EndVideo] -c:v hevc_nvenc -fps_mode passthrough -preset slow -b:v 2400k output.mp4 out.flv 2> log.txt
nvenc 命令抛出错误(它被裁剪以显示错误):
Stream #0:0 (hevc) -> scale2ref (graph 0)
Stream #1:0 (png) -> format:default (graph 0)
Stream #0:1 -> #0:0 (aac (native) -> aac (native))
subtitles:default (graph 0) -> Stream #0:1 (hevc_nvenc)
Stream #0:0 -> #1:0 (hevc (native) -> flv1 (flv))
Stream #0:1 -> #1:1 (aac (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
[Parsed_subtitles_4 @ 00000237222fa380] libass API version: 0x1701000
[Parsed_subtitles_4 @ 00000237222fa380] libass source: commit: 0.17.0-55-g5c15c883a4783641f7e71a6a1f440209965eb64f
[Parsed_subtitles_4 @ 00000237222fa380] Shaper: FriBidi 1.0.13 (SIMPLE) HarfBuzz-ng 8.1.1 (COMPLEX)
[Parsed_subtitles_4 @ 00000237222fa380] Using font provider directwrite (with GDI)
Impossible to convert between the formats supported by the filter 'Parsed_scale2ref_2' and the filter 'auto_scale_0'
[fc#0 @ 0000023721c200c0] Error reinitializing filters!
Failed to inject frame into filter network: Function not implemented
Error while filtering: Function not implemented
[out#0/mp4 @ 000002372237d180] Nothing was written into output file, because at least one of its streams received no packets.
[out#1/flv @ 000002372237d6c0] Nothing was written into output file, because at least one of its streams received no packets.
frame= 0 fps=0.0 q=0.0 Lq=0.0 size= 0kB time=00:00:00.23 bitrate= 0.0kbits/s speed=5.24x
[aac @ 00000237235307c0] Qavg: 65536.000
Conversion failed!
答案1
以下命令可能会起作用:
ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -i video.mkv -i logo.png -filter_complex "[0:v]scale_cuda=format=yuv420p,hwdownload[v0];[1:v]format=rgba,colorchannelmixer=aa=0.4[logo];[logo][v0]scale2ref=oh*mdar:ih*0.05[logo][video];[video][logo]overlay=(main_w-overlay_w)-10:10[AddedLogo];[AddedLogo]subtitles=subtitles.ass,format=yuv420p[EndVideo]" -map 0:a -map [EndVideo] -c:v hevc_nvenc -fps_mode passthrough -preset slow -b:v 2400k output.mp4
该问题与视频帧的存储位置有关。
- 使用时
-hwaccel cuda -hwaccel_output_format cuda
,FFmpeg使用CUDA加速解码(或NVDEC),并将解码后的帧存储在设备内存中(GPU中)。 - 滤镜
format
、scale2ref
和overlay
是subtitles
在 CPU 上执行的滤镜(不能在 GPU 上执行)。
在执行这些滤镜之前,必须将帧存储在“主机”的内存中(即 CPU 的内存中)。 - 为了将解码后的帧从设备下载到主机,我们可以使用
hwdownload
过滤器。
由于 GPU 中的像素格式定义为“cuda”,我们还必须先将格式转换为yuv420p
。hwdownload
转换
然后下载时,适用以下内容:[0:v]scale_cuda=format=yuv420p,hwdownload[v0]
- 我们还必须
yuv420p
在使用hevc_nvenc
编码器之前将输出的像素格式转换为。在之后
添加。format=yuv420p
subtitles=subtitles.ass
format
与、scale2ref
和等效的 GPU 过滤器overlay
是format_cuda
和scale2ref_npp
。 (使用需要从具有 NPP 库overlay_cuda
的源构建 FFmpeg)。过滤器没有 GPU 实现,因此我们必须在使用过滤器之前将帧下载到主机。scale2ref_npp
subtitles
耗时的操作包括下载、在 CPU 中进行过滤以及上传。
使用 GPU 进行编码和解码可能不会显著提高性能,但事实就是如此……