如何利用Intel GPU硬加速完成NV12转BGRA,降低FFmpeg输出RTSP流到/dev/fb0的CPU占用
如何利用Intel GPU硬加速完成NV12转BGRA,降低FFmpeg输出RTSP流到/dev/fb0的CPU占用
你好,针对你的问题,核心就是把NV12到BGRA的格式转换工作从CPU转移到Intel GPU上,避免用swscale做软转换占用CPU。下面是具体的解决方案和思路:
问题根源回顾
你之前的命令里,-pix_fmt bgra是让FFmpeg在CPU端完成格式转换,这会触发swscale软缩放,所以CPU占用飙升。而解码已经用了VA-API硬加速,所以GPU占用稳定在1.5%左右。
解决方案:用VA-API硬滤镜完成格式转换
我们可以用FFmpeg的scale_vaapi滤镜,让格式转换全程在GPU上完成,不需要把帧拷贝回CPU。这里的关键是要让解码后的帧一直留在GPU内存里,再通过硬滤镜完成转换,最后直接输出到fbdev。
完整命令示例
ffmpeg -init_hw_device vaapi=intel:/dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -loglevel verbose -rtsp_transport tcp -stimeout 30000000 -i rtsp://192.168.0.21/media.smp -vf "scale_vaapi=format=bgra" -f fbdev /dev/fb0
关键参数解释
-hwaccel_output_format vaapi:强制解码后的帧保留在VA-API的GPU内存中,避免拷贝到CPU,这是硬转换的前提-vf "scale_vaapi=format=bgra":使用VA-API硬滤镜完成格式转换(即使分辨率不需要缩放,也可以用这个滤镜来转格式),把NV12直接在GPU上转换成BGRA- 去掉了原来的
-pix_fmt bgra,因为格式转换已经由硬滤镜完成,不需要再在CPU端处理
效果验证
运行这个命令后,你可以用sudo intel_gpu_top观察:
- GPU的负载会略有上升(因为多了格式转换的工作)
- CPU占用会降到和
-f null -测试时的3%-5%左右,和之前的13%相比大幅降低
关于你其他疑问的补充
- fb0支持NV12的可能性:大多数情况下,/dev/fb0这类帧缓冲设备只支持RGB类格式(比如BGRA、RGB24),不支持YUV格式的NV12,所以直接输出NV12是不可行的,必须转成BGRA,但用硬转换就不会占用CPU。
- vpp_qsv的问题:你观察到的没错,vpp_qsv确实不支持输出BGRA格式,所以用VA-API的
scale_vaapi是更合适的选择,它支持BGRA的输出格式,完全匹配fbdev的需求。
注意事项
- 确保你的FFmpeg是支持VA-API的(Ubuntu 22.04官方源的ffmpeg 4.4.2已经默认启用了VA-API,所以不需要额外编译)
- 运行命令时要保证有访问
/dev/dri/renderD128和/dev/fb0的权限,必要时可以加sudo,或者把当前用户加入video组
备注:内容来源于stack exchange,提问作者user3299264
相关产品推荐
相关产品推荐

