1. 项目概述
在安卓平台上编译支持Rockchip芯片硬件加速的FFmpeg(ffmpeg-rockchip)是一个常见但颇具挑战性的任务。作为一名长期从事多媒体开发的工程师,我最近完成了这个项目的完整编译流程,现将详细过程整理成文。这个指南不仅包含标准编译步骤,还特别针对Rockchip平台的特殊需求进行了优化,确保能充分利用RK芯片的硬件编解码能力。
ffmpeg-rockchip是FFmpeg的一个定制分支,主要增加了对Rockchip系列芯片(如RK3399、RK3588等)的硬件编解码支持。通过MPP(Media Process Platform)和RGA(Raster Graphic Acceleration)等Rockchip专有库,可以实现H.264/H.265视频的高效编解码和图像处理。本指南将带你完成从环境准备到最终测试的全过程,适用于armeabi-v7a和arm64-v8a两种架构。
2. 环境准备与工具链配置
2.1 基础环境要求
编译ffmpeg-rockchip需要一个稳定的Linux环境,推荐使用Ubuntu 18.04 LTS。以下是我们的实验环境配置:
- 虚拟机配置:VMWare Workstation 16 Pro
- CPU:8核(宿主机器为Intel i9-9900K)
- 内存:200GB(大内存主要为了加速编译,实际100GB也足够)
- 磁盘空间:至少200GB空闲空间(编译中间文件会占用大量空间)
注意:虽然可以在物理机上直接操作,但使用虚拟机更方便环境隔离和快照管理。如果使用WSL2,需要注意文件系统性能问题。
2.2 关键工具安装
2.2.1 CMake 3.28安装
Rockchip MPP库对CMake版本有严格要求,必须使用3.28版本:
bash复制wget https://cmake.org/files/v3.28/cmake-3.28.0-linux-x86_64.tar.gz
tar -xzf cmake-3.28.0-linux-x86_64.tar.gz -C ~/
echo 'export PATH=$HOME/cmake-3.28.0-linux-x86_64/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
验证安装:
bash复制cmake --version # 应输出3.28.0
2.2.2 Meson和Ninja安装
Meson是一个现代化的构建系统生成器,与Ninja配合使用:
bash复制sudo apt-get update
sudo apt-get install -y python3 python3-pip ninja-build
pip3 install --user meson
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
验证安装:
bash复制meson --version # 应输出0.61.5或更高
ninja --version # 应输出1.10.0或更高
2.2.3 Android NDK配置
使用NDK r27d版本,这是经过验证能与Rockchip库良好配合的版本:
bash复制wget https://dl.google.com/android/repository/android-ndk-r27d-linux.zip
unzip android-ndk-r27d-linux.zip -d ~/
echo 'export ANDROID_NDK_ROOT=$HOME/android-ndk-r27d' >> ~/.bashrc
source ~/.bashrc
3. 依赖库编译
3.1 Rockchip MPP编译
MPP是Rockchip的媒体处理核心库,必须首先编译:
bash复制git clone -b jellyfin-mpp --depth=1 https://gitee.com/nyanmisaka/mpp.git rkmpp
cd rkmpp/build
修改ev_setup.sh中的NDK路径:
bash复制NDK_SEARCH_PATH=(
"/home/test/ndk/"
)
对于32位架构(armeabi-v7a):
bash复制cd android/arm
./make-Android.bash
make -j8
make install
对于64位架构(arm64-v8a):
bash复制cd ../aarch64
./make-Android.bash
make -j8
make install
常见问题:如果遇到"OBJECT library not supported"错误,一定是CMake版本不对,必须使用3.28。
3.2 Rockchip RGA编译
RGA提供2D图形加速功能:
bash复制git clone -b jellyfin-rga --depth=1 https://gitee.com/nyanmisaka/rga.git rkrga
cd rkrga/toolchains
修改toolchain_android_ndk.cmake:
cmake复制SET(CMAKE_ANDROID_NDK "/home/test/ndk/android-ndk-r27d")
SET(CMAKE_SYSTEM_NAME Android)
SET(CMAKE_SYSTEM_VERSION 24)
SET(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
编译:
bash复制./cmake-android.sh
对于64位,修改ABI为arm64-v8a后重新编译。
3.3 libdrm编译
libdrm是Direct Rendering Manager的核心库:
bash复制git clone https://gitlab.freedesktop.org/mesa/libdrm.git
cd libdrm
mkdir build install
创建cross_file.txt:
ini复制[binaries]
c = 'armv7a-linux-androideabi23-clang'
cpp = 'armv7a-linux-androideabi23-clang++'
ar = 'llvm-ar'
strip = 'llvm-strip'
[host_machine]
system = 'android'
cpu_family = 'arm'
cpu = 'arm'
endian = 'little'
编译:
bash复制meson --prefix=$(pwd)/../install --cross-file=../cross_file.txt \
-D intel=disabled -D radeon=disabled -D amdgpu=disabled \
-D nouveau=disabled -D vmwgfx=disabled -D vc4=disabled \
-D etnaviv=disabled -D cairo-tests=disabled \
-D man-pages=disabled -D valgrind=disable
ninja && ninja install
4. FFmpeg-Rockchip编译
4.1 准备编译脚本
创建android.sh脚本:
bash复制#!/bin/sh
NDK_ROOT=/home/test/android-ndk-r27d/toolchains/llvm/prebuilt/linux-x86_64
INSTALL_BASE=/home/test/install
FFMPEG_SRC=$(pwd)
build_armeabi_v7a() (
ABI=armeabi-v7a
PREFIX=/home/test/install/ffmpeg/${ABI}
TARGET=armv7a-linux-androideabi
API=27
export PATH=${NDK_ROOT}/bin:$PATH
export CC=${TARGET}${API}-clang
export CXX=${TARGET}${API}-clang++
./configure \
--prefix=${PREFIX} \
--enable-gpl \
--enable-rkmpp \
--enable-rkrga \
--enable-libdrm \
--disable-ffplay \
--extra-cflags="-I${INSTALL_BASE}/mpp/${ABI}/include" \
--extra-ldflags="-L${INSTALL_BASE}/mpp/${ABI}/lib"
make -j8 && make install
)
build_arm64_v8a() (
ABI=arm64-v8a
PREFIX=/home/test/install/ffmpeg/${ABI}
TARGET=aarch64-linux-android
API=27
export PATH=${NDK_ROOT}/bin:$PATH
export CC=${TARGET}${API}-clang
export CXX=${TARGET}${API}-clang++
./configure \
--prefix=${PREFIX} \
--enable-gpl \
--enable-rkmpp \
--enable-rkrga \
--enable-libdrm \
--disable-ffplay \
--extra-cflags="-I${INSTALL_BASE}/mpp/${ABI}/include" \
--extra-ldflags="-L${INSTALL_BASE}/mpp/${ABI}/lib"
make -j8 && make install
)
build_armeabi_v7a
build_arm64_v8a
4.2 执行编译
bash复制chmod +x android.sh
./android.sh
编译完成后,在/home/test/install/ffmpeg目录下会有两个子目录:
armeabi-v7a:32位库文件arm64-v8a:64位库文件
5. 验证与测试
5.1 基本功能验证
检查FFmpeg版本及支持的编解码器:
bash复制./ffmpeg -version
./ffmpeg -codecs | grep h26[45]
应该能看到类似以下输出,表明Rockchip硬件编解码器已启用:
code复制DEV.LS h264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_rkmpp ) (encoders: h264 h264_rkmpp )
DEV.L. hevc H.265 / HEVC (High Efficiency Video Coding) (decoders: hevc hevc_rkmpp ) (encoders: hevc hevc_rkmpp )
5.2 硬件加速测试
测试H.264硬件解码:
bash复制./ffmpeg -hwaccel rkmpp -c:v h264_rkmpp -i input.h264 -f null -
测试H.265硬件编码:
bash复制./ffmpeg -i input.yuv -c:v hevc_rkmpp -b:v 2M output.hevc
6. 常见问题与解决方案
6.1 编译错误:找不到rkmpp库
现象:configure阶段报错"ERROR: rkmpp not found"
解决:
- 确认PKG_CONFIG_PATH包含mpp的pkgconfig路径
- 检查mpp是否成功编译安装
- 确保使用的mpp版本与ffmpeg-rockchip兼容
6.2 运行时错误:dlopen failed
现象:运行时出现"dlopen failed: library "librga.so" not found"
解决:
- 将编译生成的库文件打包到APK的jniLibs目录
- 在Java代码中显式加载依赖库:
java复制static {
System.loadLibrary("rga");
System.loadLibrary("mpp");
System.loadLibrary("avcodec");
}
6.3 性能问题
现象:硬件加速没有明显提升性能
解决:
- 检查是否真的使用了硬件加速(通过logcat查看mpp日志)
- 确认视频分辨率与芯片能力匹配(如RK3399最大支持4K@30fps)
- 调整FFmpeg参数,如增加
-async_depth 4提高并行度
7. 优化建议
- 内存优化:Rockchip芯片的VPU有特殊内存要求,建议使用
drm_fourcc格式分配内存:
c复制AVBufferRef *hw_frames_ctx;
av_hwframe_ctx_init(hw_frames_ctx);
- 多实例处理:MPP支持多实例并行,但需要确保每个解码器实例使用独立的MPP上下文:
c复制MPP_RET ret = mpp_create(&ctx, &mpi);
ret = mpi->control(ctx, MPP_DEC_SET_EXT_BUF_GROUP, group);
- 低延迟配置:对于实时视频应用,调整以下参数:
bash复制./ffmpeg -flags low_delay -x264opts no-scenecut -tune zerolatency ...
通过本指南,你应该已经成功编译出支持Rockchip硬件加速的FFmpeg。在实际项目中,还需要根据具体芯片型号(RK3399、RK3588等)调整参数,这些经验往往需要通过实际测试积累。如果有任何问题,欢迎在评论区交流讨论。
