简述
FFmpeg是开源的音视频编解码库,我们在做音视频应用开发时可以考虑引入FFmpeg来提供软编解码功能,首先我们需要先将FFmpeg编译成Android系统可用的静态库。
编译Android静态库库需要NDK,经过多种尝试后发现不同版本的NDK和不同版本的FFmpeg在编译时都会或多或少产生一些问题,最终,笔者选择了ffmpeg-4.1.3和android-ndk-r17c这两个版本进行编译,如果选择其他版本可能不会遇到下面描述的问题或者可能遇到新的问题。
编译流程
下载r17版本的NDK并解压
wget https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
unzip android-ndk-r17c-linux-x86_64.zip
下载ffmpeg源码并解压
wget https://ffmpeg.org/releases/ffmpeg-4.1.3.tar.bz2
tar -xjf ffmpeg-4.1.3.tar.bz2
这个时候应该有以下两个目录
android-ndk-r17c ffmpeg-4.1.3
配置编译
在ffmpeg目录下执行配置工作,为编译作准备,其中PREFIX是编译文件输出路径,编译出的静态库可以在这里找到
cd ffmpeg-4.1.3
./configure
NDK=/root/ffmpeg/android-ndk-r17c
SYSROOT=$NDK/platforms/android-19/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
PREFIX=$(pwd)/android/armeabi-v7a
./configure \
--prefix=$PREFIX \
--disable-shared \
--enable-static \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-ffmpeg \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-I$NDK/sysroot/usr/include/arm-linux-androideabi -isysroot $NDK/sysroot -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a" \
--enable-neon
如果要编译动态库,则将--disable-shared改为--enable-shared,将--enable-static改为--disable-static
./configure \
--prefix=$PREFIX \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-ffmpeg \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-I$NDK/sysroot/usr/include/arm-linux-androideabi -isysroot $NDK/sysroot -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a" \
--enable-neon
编译
make
编译时会出现很多错误,是因为ndk和ffmpeg版本不兼容导致名称冲突,前面说过了,不同的版本搭配都可能或多或少产生一些问题,因此,在这里我们说明下在当前采用的版本下如何解决编译产生的问题。
问题1
libavcodec/aaccoder.c: In function 'search_for_ms':
libavcodec/aaccoder.c:803:25: error: expected identifier or '(' before numeric constant
int B0 = 0, B1 = 0;
解决方案:libavcodec/aaccoder.c 文件中B0变量改成其他不会冲突的名字(如b0)
问题2
libavcodec/hevc_mvs.c: In function 'derive_spatial_merge_candidates':
libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function)
((y ## v) >> s->ps.sps->log2_min_pu_size))
解决方案libavcodec/hevc_mvs.c文件中B0、xB0、yB0改成其他不会冲突的名字(如b0,xb0,yb0)
问题3
libavcodec/opus_pvq.c: In function 'quant_band_template':
libavcodec/opus_pvq.c:498:9: error: expected identifier or '(' before numeric constant
int B0 = blocks;
解决方法:将libavcodec/opus_pvq.c文件中B0变量改成其他不会冲突的名字(如b0)
输出静态库
make install
执行之后可以在ffmpeg-4.1.3/android/armeabi-v7a/lib目录下看到编译好的静态库