我正在尝试将此命令转换为在 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!
以下命令可能有效:
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
和overlay_cuda
。(使用
scale2ref_npp
需要从带有 NPP 库的源构建 FFmpeg)。subtitles
过滤器没有 GPU 实现,因此我们必须在使用过滤器之前将帧下载到主机。耗时的操作将是下载、CPU 中的过滤和上传。
使用 GPU 进行编码和解码可能不会显着提高性能,但事实就是如此......