树莓派FFmpeg硬件加速
最近在整理 NAS 的时候发现很多以前的电影是 RMVB 格式的,强迫症发作想把这些 RMVB 视频统统用 H264 转成 mp4 视频。这时想起来树莓派 FFmpeg 支持硬解码,所以打起来让树莓派来完成这些工作的主意。
准备配置
Raspberry Pi的GPU对 H264有一系列针对 MPEG4 H264、MPEG2 和 VC1(需要额外授权)的硬件加速优化,为了得到最好的性能,建议先对树莓派的启动设置文件(/boot/config.txt)进行如下的调整:
gpu_mem=256
framebuffer_depth=16
准备 FFmpeg
直接使用 apt-get 安装的ffmpeg没有专门的优化,对硬解的支持不好,所以需要自己从源码编译安装,首先用 apt-get 安装一些必要的包:
apt-get install autoconf automake build-essential libass-dev libfreetype6-dev libtheora-dev libtool libvorbis-dev pkg-config texinfo zlib1g-dev unzip cmake yasm libx264-dev libmp3lame-dev libopus-dev bzip2-dev
为了方便管理,后续的编译操作都在 /root/soft/kit 文件夹中完成,用户为root。
编译安装 x264
x264 库是MPEG4 H264编码必须要的用到的组件。
git clone git://git.videolan.org/x264
cd x264/
git checkout 72d53ab2ac7af24597a824e868f2ef363a22f5d4
./configure --disable-asm --enable-shared --disable-win32thread --enable-strip --extra-cflags='-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard'
make -j 4 V=1
make install
ldconfig
编译安装 libmpeg2
这里是将旧的 libmpeg2 库作为 FFmpeg libavcodec 的替代方案,如果没有 libavcodec 后续可能会报错。
wget http://libmpeg2.sourceforge.net/files/libmpeg2-0.5.1.tar.gz
tar -xvzpf libmpeg2-0.5.1.tar.gz
cd libmpeg2-0.5.1
./configure --disable-largefile
设置完成之后,修改Makefiles文件(可直接用 vi 编辑 libmpeg2-0.5.1 目录下的Makefiles文件),找到 “CFLAGS=” 字段,在末尾添加“ -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard” 然后继续编译安装。
make -j 4 V=1
make install
ldconfig
编译安装 libass
libass 库是用来提供字幕支持的,更多的信息可以看这里。
wget https://github.com/libass/libass/releases/download/0.13.7/libass-0.13.7.tar.gz
tar -xvzpf libass-0.13.7.tar.gz
cd libass-0.13.7/
./configure
make -j 4 V=1
make install
ldconfig
编译安装 FFmpeg
我在树莓派2代B型上全部编译完成大概需要一个小时,3代以后的应该会更快一些。源码选择Kodi Community修改的FFmpeg Version 3.1.6-Krypton树莓派特别优化版,目前最新版是4.0.4-Leia-18.4,新版本有更多的性能提升和优化,推荐使用新版本。
wget https://github.com/xbmc/FFmpeg/archive/4.0.4-Leia-18.4.tar.gz
tar -xzpf FFmpeg-4.0.4-Leia-18.4.tar.gz
cd FFmpeg-4.0.4-Leia-18.4
export LDFLAGS="-L /opt/vc/lib/"
./configure --extra-ldflags="-L /opt/vc/lib/" --extra-cflags='-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mvectorize-with-neon-quad -mfloat-abi=hard' --extra-cxxflags='-march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4 -mvectorize-with-neon-quad -mfloat-abi=hard' --disable-devices --disable-ffprobe --disable-doc --disable-w32threads --enable-ffplay --extra-libs=-ldl --enable-shared --enable-libass --disable-devices --enable-mmal --enable-decoder=h264_mmal --enable-decoder=mpeg2_mmal --enable-encoder=h264_omx --enable-omx --enable-omx-rpi --enable-neon --enable-gnutls --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis --enable-nonfree --enable-libx264 --enable-gpl --enable-runtime-cpudetect --enable-postproc --enable-bzlib --enable-muxer=spdif --enable-muxer=adts --enable-muxer=asf --enable-encoder=ac3 --enable-encoder=aac --enable-encoder=wmav2 --enable-protocol=http --enable-encoder=png --enable-encoder=mjpeg --enable-pthreads --enable-pic --enable-zlib --disable-mipsdsp --disable-mipsdspr2
make -j 3 V=1
make install
ldconfig
其中,如果你用的是3代以上的话,可以将configure的参数修改如下:
./configure --extra-ldflags="-L /opt/vc/lib/" --extra-cflags='-march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mvectorize-with-neon-quad -mfloat-abi=hard' --extra-cxxflags='-march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mvectorize-with-neon-quad -mfloat-abi=hard' --disable-devices --disable-ffprobe --disable-doc --disable-w32threads --enable-ffplay --extra-libs=-ldl --enable-shared --enable-libass --disable-devices --enable-mmal --enable-decoder=h264_mmal --enable-decoder=mpeg2_mmal --enable-encoder=h264_omx --enable-omx --enable-omx-rpi --enable-neon --enable-gnutls --enable-libvorbis --enable-muxer=ogg --enable-encoder=libvorbis --enable-nonfree --enable-libx264 --enable-gpl --enable-runtime-cpudetect --enable-postproc --enable-bzlib --enable-muxer=spdif --enable-muxer=adts --enable-muxer=asf --enable-encoder=ac3 --enable-encoder=aac --enable-encoder=wmav2 --enable-protocol=http --enable-encoder=png --enable-encoder=mjpeg --enable-pthreads --enable-pic --enable-zlib --disable-mipsdsp --disable-mipsdspr2
成功编译安装之后,支持硬解的FFmpeg就安装成功了,可以通过 ffmpeg -version 命令查看安装的版本, ffmpeg -encoders|grep omx 命令查看 h264_omx 编码器的支持情况。
批量转码
由于待转码的视频文件比较多,一条一条地去准备命令会比较麻烦,所以通过 Shell 脚本批量转换会比较靠谱,ssh 登上树莓派之后,启动一个screen,然后在视频目录创建RpiConvert.sh文件,内容如下:
for i in *.rmvb; do
echo "rmvb checking... $i"
if [ ! -f "${i%.*}.mp4" ]; then
echo "Begin conver ${i}"
ffmpeg -i "$i" -metadata title="${i%.*}" -c:v h264_omx -b:v 2000K -c:a aac -f mp4 "${i%.*}.mp4"
fi
done
然后用bash RpiConvert.sh 执行脚本即可。启用硬件加速的 FFmpeg 可以在保持 1X 左右转码速度的情况下显著降低 CPU 使用率,使 CPU 的基本负载稳定在0.6~0.8之间。
关于 FFmpeg
FFmpeg真的是非常强大,可用的选项很多,应用范围甚广:不仅能完成播放、转码、裁减、增减水印等常规操作,也可以实现自动化抓图、预览动画、直播推等实用功能。
查看FFmpeg相关信息的功能性指令有:
可用的编解码器
ffmpeg –codecs
可用的解码器
ffmpeg –decoders
可用的编码器
ffmpeg –encoders
可用的过滤器
ffmpeg –filters
可用的视频格式
ffmpeg –formats
可用的协议
ffmpeg -protocals
常用的参数有:
-metadata 表示修改视频文件的元数据,其中 title="${i%.*}" 表示根据文件名修改视频文件信息中的视频标题,一般播放器会优先现实元数据的内容,可以修改的元数据还有很多。
-c:v 表示使用的视频编码器,即输出视频的编码类型,h264_omx 是有硬件加成的 h264 编码器,c:v是简写,它还可以写作 -codec:v ,-vcodec ,若把h264_omx改为 copy 则保持原文件的视频编码;
-c:a 表示使用的音频编码器,a与上面的v相对应,还可以写作 -codec:a , -acodec 用法与 c:v 类似,一般都是acc;
-b: 表示视频文件的码流,码流越大视频的质量就越好。 其中 -b:v 表示视频的码流, -b:a表示音频的码流,默认是200Kbit/s,所以要保持原视频的质量一定要设置这个参数,否则转出来的效果惨不忍睹;
-f 表示输出视频的封装格式,可以取mp4、flv等值;
-ss: 表示开始时间(默认从 0:0:00 开始);
-t: 表示持续时间(默认是原视频全长);
-s 表示输出视频的分辨率,参数格式为w*h或w×h
-r: 表示提取图像频率,一般会用于视频截图;
-re 表示以原视频的帧率读取数据。FFmpeg 一般会尽可能快地读数据,流文件推送就需要加上这个参数,如果是转推直播流的话,不用加此参数;