我在视频上叠加水印,如下所示:
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i ./input.avi -i ./watermark.png -filter_complex "
[0]hwdownload,format=nv12[downloaded_video];
[1]format=rgba,colorchannelmixer=aa=0.3[logo];
[logo]scale=300:300[scaled_logo];
[downloaded_video][scaled_logo]overlay=W-w-10:H-h+10[overlayed_video];
[overlayed_video]hwupload_cuda=extra_hw_frames=5" -c:v h264_nvenc ./output.mp4
有没有办法使用 nvidia 的缩放过滤器 (scale_cuda、scale_npp、scale2ref_npp) 和覆盖过滤器 (overlay_cuda) 来避免 hwdownload 和 hwupload?我尝试了很多方法,但无法保留 png 图像的透明度,这会使水印变成一个大的白色块。
使用 FFmpeg 7.1 版本时
[0:v][uploaded_logo]overlay_cuda
出现错误Can't overlay yuva420p on nv12
(但没有白块)。我们可以通过使用从 NV12 转换为 来修复它:
[0:v]scale_cuda=format=yuv420p
yuv420p
ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid -i ./input.avi -i ./watermark.png -filter_complex "[0:v]scale_cuda=format=yuv420p[yuv420p_video];[1]format=rgba,colorchannelmixer=aa=0.3,scale=300:300,hwupload_cuda[uploaded_logo];[yuv420p_video][uploaded_logo]overlay_cuda=W-w-10:H-h+10" -c:v h264_nvenc ./output.mp4
-c:v h264_cuvid
- 具体选择与Gyan 对以下帖子的评论相关的解码器。(没有它解决方案仍然可以工作)。
[1]format=rgba,colorchannelmixer=aa=0.3,scale=300:300,hwupload_cuda[uploaded_logo]
- 在CPU中准备徽标,并将其上传到GPU。上传的徽标格式会自动从 转换rgba
为yuva420p
。[0:v]scale_cuda=format=yuv420p[yuv420p_video]
- 将 GPU 中解码的视频格式从默认的 NV12 格式转换为yuv420p
格式。这是必需的,因为overlay_cuda
过滤器无法将yuva420p
格式覆盖在 NV12 格式上。[yuv420p_video][uploaded_logo]overlay_cuda=W-w-10:H-h+10
- 使用overlay_cuda
过滤器将徽标叠加在 GPU 中的视频上。测试:
构建示例输入文件:
ffmpeg -y -f lavfi -i testsrc=size=640x480:rate=10:duration=10 -c:v libx264 -pix_fmt yuv420p input.avi
使用以下水印。
执行上述命令(使用

aa=0.9
)将得到所需的输出:注意:由于格式的颜色二次采样,覆盖
不如覆盖准确。看来 GPU 实现仅限于“二次采样”像素格式(但我没有尝试所有选项)。
yuva420p
yuv420p
rgba
rgb24
4:2:0