如何使用Android NDK构建FFmpeg
我写了一篇有关使用 NDK 编译 Android 的 FFmpeg 的文章,尽管它是中文并且使用起来太多了,但每天都有成千上万的访问。
在这里,您将逐步了解如何使用最新的 git 存储库和最新的 Android NDK 版本构建 FFmpeg,并保证能够正常工作。
有 FFmpeg (Got FFmpeg)
首先,您需要使用 git 来获取 FFmpeg 代码,如果您没有 git 或不想使用 git,则可以从 http://ffmpeg.org 获取 FFmpeg。
git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
git checkout 5e99df019a850e9ffa96d73e72b8a47a93a61de8
配置 NDK (Configure NDK)
在本教程中,我们不使用传统的 Android.mk 文件来构建 FFmpeg,而是尝试使用 Android NDK 独立工具链。要初始化工具链,请发出以下命令:
export ANDROID_NDK=/path/to/your/android/ndk/root
export TOOLCHAIN=/tmp/ffmpeg
export SYSROOT=$TOOLCHAIN/sysroot/
$ANDROID_NDK/build/tools/make-standalone-toolchain.sh \
--platform=android-14 \
--install-dir=$TOOLCHAIN
此时,我们可以使用位于 $TOOLCHAIN 的 Android 独立工具链来构建 FFmpeg。有关 Android 独立工具链的更多详细信息,请参见 Android NDK 的文档。
配置 FFmpeg (Configure FFmpeg)
现在我们已经准备好为 FFmpeg 做传统的 Linux 风格的 ./configure 工作了,一旦前两个准备工作都准备好了,就很容易做到。
稍作休息:直接在终端窗口中编写 bash 脚本很烦人,因此,在这一点上,我将创建一个包含以下内容的 bash 文件:
export PATH=$TOOLCHAIN/bin:$PATH
export CC=arm-linux-androideabi-gcc
export LD=arm-linux-androideabi-ld
export AR=arm-linux-androideabi-ar
CFLAGS="-O3 -Wall -mthumb -pipe -fpic -fasm \
-finline-limit=300 -ffast-math \
-fstrict-aliasing -Werror=strict-aliasing \
-fmodulo-sched -fmodulo-sched-allow-regmoves \
-Wno-psabi -Wa,--noexecstack \
-D__ARM_ARCH_5__ -D__ARM_ARCH_5E__ \
-D__ARM_ARCH_5T__ -D__ARM_ARCH_5TE__ \
-DANDROID -DNDEBUG"
EXTRA_CFLAGS="-march=armv7-a -mfpu=neon \
-mfloat-abi=softfp -mvectorize-with-neon-quad"
EXTRA_LDFLAGS="-Wl,--fix-cortex-a8"
FFMPEG_FLAGS="--prefix=/tmp/ffmpeg/build \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--cross-prefix=arm-linux-androideabi- \
--enable-shared \
--disable-symver \
--disable-doc \
--disable-ffplay \
--disable-ffmpeg \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-avfilter \
--disable-encoders \
--disable-muxers \
--disable-filters \
--disable-devices \
--disable-everything \
--enable-protocols \
--enable-parsers \
--enable-demuxers \
--disable-demuxer=sbg \
--enable-decoders \
--enable-bsfs \
--enable-network \
--enable-swscale \
--enable-asm \
--enable-version3"
./configure $FFMPEG_FLAGS \
--extra-cflags="$CFLAGS $EXTRA_CFLAGS" \
--extra-ldflags="$EXTRA_LDFLAGS"
很简单,对吧?我们只定义一些变量并启用或禁用某些 FFmpeg 组件。还包括一些 GCC 优化,可以从 man gcc 或在线文档 http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 中找到详细信息。
构建并剥离 FFmpeg (Build and strip FFmpeg)
If you succeed to configure FFmpeg for Android, it’s time to make, issue commands below:
make -j4
make install
If everything is OK, we can get libavcodec.so, libavformat.so, etc in the prefix directory. If you wanna combine them to one libffmpeg.so, run:
rm libavcodec/inverse.o
$CC -lm -lz -shared --sysroot=$SYSROOT -Wl,--no-undefined \
-Wl,-z,noexecstack $EXTRA_LDFLAGS \
libavutil/*.o libavutil/arm/*.o \
libavcodec/*.o libavcodec/arm/*.o \
libavformat/*.o libswresample/*.o \
libswscale/*.o -o libffmpeg.so
After testing with your build, you may want to strip unused information to shrink the libffmpeg.so library size:
arm-linux-androideabi-strip --strip-unneeded libffmpeg.so
For those who wanna the full code, please go to https://github.com/cedricfung/FFmpeg-Android.
Conclusion
It’s easier to port Linux library to Android since Android standalone toolchain was available, I’ve managed to compile many other libraries in my Android project.
In the later tutorials, I will share how to build a video player with FFmpeg from the ground, step by step too. Stay tuned!