使用FFmpeg VAAPI借助Vega 11 GPU进行1280x720硬件转码时,如何保留原视频比例并添加黑边?
解决VAAPI硬件加速转码时保留宽高比并添加黑边的问题
我来帮你搞定这个转码难题!你遇到的错误核心是硬件滤镜和软件滤镜的帧格式不兼容:scale_vaapi输出的是VAAPI GPU硬件帧,而普通的pad滤镜只能处理CPU端的软件帧,两者没法直接对接,所以才会报错。
下面给你两种可行的解决方案,优先推荐第一种全硬件加速的方式:
方法1:全程GPU硬件加速(效率最高)
用VAAPI专属的硬件滤镜链,让缩放和加黑边都在GPU里完成,不需要CPU插手:
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 \ -i input.mp4 \ -c:v h264_vaapi \ -vf "scale_vaapi=w=1280:h=720:force_original_aspect_ratio=decrease,pad_vaapi=w=1280:h=720:x='(ow-iw)/2':y='(oh-ih)/2',setsar=1:1" \ output.mp4
关键参数拆解:
scale_vaapi=...:force_original_aspect_ratio=decrease:和你树莓派上的逻辑一致,先按原视频的宽高比缩小,确保画面不超过1280x720的尺寸,完全避免拉伸pad_vaapi=...:用VAAPI硬件滤镜添加黑边,把缩放后的画面居中到1280x720的画布上,全程GPU处理,速度快- 整个滤镜链都是VAAPI硬件滤镜,没有CPU和GPU之间的帧拷贝损耗
方法2:兼容旧版FFmpeg的方案(硬件转软件再转回)
如果你的FFmpeg版本比较老,没有pad_vaapi滤镜,可以先把GPU帧转到CPU处理,完成加黑边后再转回GPU编码:
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -vaapi_device /dev/dri/renderD128 \ -i input.mp4 \ -vf "scale_vaapi=w=1280:h=720:force_original_aspect_ratio=decrease,format=nv12,pad=1280:720:'(ow-iw)/2':'(oh-ih)/2',format=vaapi,hwupload" \ -c:v h264_vaapi \ output.mp4
步骤解释:
scale_vaapi:GPU端完成按比例缩放format=nv12:把GPU硬件帧转换成CPU能处理的NV12格式(软件帧)pad:CPU端添加黑边format=vaapi,hwupload:把处理好的软件帧重新上传到GPU,交给VAAPI编码器
注意:
这种方法会有一次CPU和GPU之间的数据拷贝,性能比第一种稍差,但能兼容不支持pad_vaapi的旧版FFmpeg。
为什么你之前的命令会失败?
你之前的命令里,scale_vaapi输出的是VAAPI硬件帧,后面直接接了软件版的pad滤镜。FFmpeg尝试自动转换帧格式,但这个转换需要显式指定格式和下载操作,不能直接衔接,所以才会抛出“无法转换格式”的错误。
内容的提问来源于stack exchange,提问作者Rusty Lemur




