1 背景

最近需要在android上编译ffmpeg, 网上找了很多资料, 编译到arm平台上的倒是不少, 但是编译到x86平台上的就很少. 最终找到一个github上的repo: ffmpeg-android. 经过漫长的git clone, git submodule update以及下载一些链接已经无效的库, 终于成功编译出了x86上的ffmpeg for android. 这里不得不吐槽一下学校的渣渣网络, 以及那些提供一个脚本自动下载自动安装的库, 对于网络不行的人群简直就是噩梦. 然而我们的项目是运行在x86_64上的, 所以革命尚未成功, 接下来就要折腾如何修改编译脚本使之支持x86_64

2 修改脚本

ffmpeg-android有好几个编译脚本, 入口为android_build.sh, 设置好参数后分辨调用x264_build.sh, libpng_build.sh等一系列脚本编译各个组件, 最后调用ffmpeg_build.sh编译出ffmpeg.

for i in "${SUPPORTED_ARCHITECTURES[@]}"
do
  rm -rf ${TOOLCHAIN_PREFIX}
  # $1 = architecture
  # $2 = base directory
  # $3 = pass 1 if you want to export default compiler environment variables
  ./x264_build.sh $i $BASEDIR 0 || exit 1
  ./libpng_build.sh $i $BASEDIR 1 || exit 1
  ./freetype_build.sh $i $BASEDIR 1 || exit 1
  ./expat_build.sh $i $BASEDIR 1 || exit 1
  ./fribidi_build.sh $i $BASEDIR 1 || exit 1
  ./fontconfig_build.sh $i $BASEDIR 1 || exit 1
  ./libass_build.sh $i $BASEDIR 1 || exit 1
  ./lame_build.sh $i $BASEDIR 1 || exit 1
  ./ffmpeg_build.sh $i $BASEDIR 0 || exit 1
done

可以看到, ffmpeg-android会对所有支持的体系结构分别编译出一个ffmpeg, 这个支持的体系结构列表定义在settings.sh中:

SUPPORTED_ARCHITECTURES=(armeabi-v7a armeabi-v7a-neon x86)

所以为了增加x86_64的支持, 首先就要在这个列表中新增一项:

SUPPORTED_ARCHITECTURES=(armeabi-v7a armeabi-v7a-neon x86 x86_64)

在android_build.sh中, 这个支持的体系结构会被分别传入其他sh编译脚本中, 这些脚本又会将这个参数传递给abi_settings.sh:

case $1 in
  armeabi-v7a)
    NDK_ABI='arm'
    NDK_TOOLCHAIN_ABI='arm-linux-androideabi'
    NDK_CROSS_PREFIX="${NDK_TOOLCHAIN_ABI}"
  ;;
  armeabi-v7a-neon)
    NDK_ABI='arm'
    NDK_TOOLCHAIN_ABI='arm-linux-androideabi'
    NDK_CROSS_PREFIX="${NDK_TOOLCHAIN_ABI}"
    CFLAGS="${CFLAGS} -mfpu=neon"
  ;;
  x86)
    NDK_ABI='x86'
    NDK_TOOLCHAIN_ABI='x86'
    NDK_CROSS_PREFIX="i686-linux-android"
    CFLAGS="$CFLAGS -march=i686"
esac

因此, 为了支持x86_64, 需要在这里增加一项:

x86_64)
  NDK_ABI='x86_64'
  NDK_TOOLCHAIN_ABI='x86_64'
  NDK_CROSS_PREFIX="x86_64-linux-android"
  CFLAGS="$CFLAGS"

除了abi_settings.sh, 还有两个脚本也依赖这个体系结构的参数.

ffmpeg_build.sh:

case $1 in
    armeabi-v7a | armeabi-v7a-neon)
        CPU='cortex-a8'
        ;;
    x86)
        CPU='i686'
        ;;
    x86_64)
        CPU='x86_64'
esac

lame_build.sh:

case $1 in
    armeabi-v7a | armeabi-v7a-neon)
        HOST=arm-linux
        ;;
    x86)
        HOST=i686-linux
        ;;
    x86_64)
        HOST=x86_64-linux
esac

至此, 执行android_build.sh就能编译出x86_64下的ffmpeg for android了

3 遇到的问题

No working compiler found

错误提示: No platform files (android-9) for this architecture: x86_64.

看了一下ndk目录下的platform, 里面的android-9 API不支持x86_64, 解决方法就是在settings.sh中将ANDROID_API_VERSION设置的高一点. 同时, ndk-r10e中的x86_64编译器只有gcc 4.9, 而ffmepg-android中的脚本用的是gcc 4.8, 也要根据实际情况修改.

ANDROID_API_VERSION=21
NDK_TOOLCHAIN_ABI_VERSION=4.9

C compiler test failed

错误提示: gcc is unable to create an executable file.

网上找了很多帖子都反映编译ffmpeg遇到了这种问题, 解决方案千奇百怪, 感觉已经上升到玄学了, 但是一个都不能解决我的问题. 最后发现其实可以查看config.log文件, 拉到最后就能看到到底是什么问题, 比如我的问题就是-march 参数设置错了. 在abi_setting.sh中, 我一开始修改为:

x86_64)
  NDK_ABI='x86_64'
  NDK_TOOLCHAIN_ABI='x86_64'
  NDK_CROSS_PREFIX="x86_64-linux-android"
  CFLAGS="$CFLAGS -march=x86_64"

但是实际上这个参数对于x86_64并不需要, 因此删掉-march就行.

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>