Linux下构建带vo-aacenc和x264的FFmpeg的Android ARM以及X86版本库

背景:需要做一个Android端的视频转码so库使用,需要用到FFmpeg开源库,并且按需求集成进X264vo-aacenc两个静态库,随后就走上了不断的踩坑和爬坑之路,现在特地记录一下,以供将来脑子不好的时候有个回想的根据。

构建环境

系统:Ubuntu16.04_64位(是的,还是Mac上跑的虚拟机,网上有太多的Mac构建FFmpeg的过程,然后爬了个把星期都不能用,有哪位大神有靠谱点的教程欢迎分享);
NDK:android-ndk-r9d(不要问我为什么不用最新的,都是泪T T);
FFmpeg:2.0.7版本,根据官方的Release Note发现3.0以上版本已经不再支持vo-aacenc了,所以下了2.0.X的版本;
vo-aacenc:0.1.3版本,是的,最新版本还是2013-07-27发布的,就是说该库已经光荣退休了,有条件的推荐使用fdk-aac尝试编译一下;
X264:最新的就好,没啥要求。

过程

过程无非就是写编译脚步,调编译脚本的过程,刚学习写这玩意,过程时异常曲折。首先从各自网站上下载FFmpeg、X264和vo-aacenc,然后把压缩包解压后放到同一个目录下,不如说将x264以及vo-aacenc都放在FFmpeg解压出来的文件夹下。这样的好处是少写几个代码,整个编译过程可以放在同一个脚本中运行。顺序是按照x264\vo-aacenc\ffmpeg的先后编译,因为FFmpeg编译的时候需要用到前面两个已经生成好的静态库。主要的脚本编译放到后面去说。

期间真的遇到了无数的坑,差点都要放弃了,(╯°Д°)╯︵ ┻━┻
主要摘了一些典型的记录一下:
1.脚本运行中出现No such file or directory VS no such command
别笑,还真是这种问题折磨的死去活来死去,因为脚本里面要配置的东西太多了,ToolChains的路径又要配置好几次,稍不留神写错一个路径,编译就无法成功,这个时候千万淡定,看看脚本命令行之间是不是都用\分隔着,路径有没有出错,最好打印一下,echo $PATH之类的。
2.In file included from libavcodec/x86/mpegvideoenc.c:81:0: libavcodec/x86/mpegvideoenc_template.c: In function 'dct_quantize_SSSE3': libavcodec/x86/mpegvideoenc_template.c:144:9: error: 'asm' operand has impossible constraints __asm__ volatile( libavcodec/x86/mpegvideoenc_template.c:179:9: error: 'asm' operand has impossible constraints __asm__ volatile( CC libavcodec/x86/videodsp_init.o CC libpostproc/postprocess.o common.mak:48: recipe for target 'libavcodec/x86/mpegvideoenc.o' failed make: *** [libavcodec/x86/mpegvideoenc.o] Error 1 make: *** Waiting for unfinished jobs....
典型错误,去掉脚本中的--enable-asm
3.undefined reference to "__umodsi3"
undefined reference to "__udivdi3"
在脚本中没有指定连接的GCC库,添加-lgcc,多说一句,-lgcc代表链接器将连接GCC的支持库libgcc.a,-lm代表链接器将连接GCC的标准数学库libm.a,-lc代表链接器将连接GCC的标准C库libc.a。
4.诸如C compiler not found之类的错误就是你的GCC路径没设对了。

构建脚本

最后,贴一下构建的脚本(这个虽然是现成的,但是思想和踩坑经过才是最重要的!)
再啰嗦一句,标题上写的是构建基于X86和armeabi的,那么为什么不加上arm64呢?对于ARM64架构的so库,目前无法编译,因为arm64的GCC版本于Android-21(5.0.1-2014年发布)才开始支持,而FFmpeg中的AAC编解码的开源模块于2013年就已停止维护,官方文档也说明该库不支持ARM64的架构。话又说回来,64位也是兼容32位的静态库的,只不过性能上就要牺牲一下了。MIPS的毕竟太少太少,就不折腾了。
贴一下X86的运行脚本,armeabi的稍微换一下就好了

#!/bin/bash
function setup_paths
{
    export PLATFORM=$NDKROOT/platforms/$PLATFORM_VERSION/arch-$ARCH
    if [ ! -d $PLATFORM ]; then
        echo $PLATFORM does not exist
        exit 1
    fi
    echo "Using platform: $PLATFORM"
    export PATH=${PATH}:$PREBUILT/bin/
    export CROSS_COMPILE=$PREBUILT/bin/$EABIARCH-
    export CFLAGS=$OPTIMIZE_CFLAGS
    export CPPFLAGS="$CFLAGS"
    export CFLAGS="$CFLAGS"
    export CXXFLAGS="$CFLAGS"
    export CXX="${CROSS_COMPILE}g++ --sysroot=$PLATFORM -m32"
    export AS="${CROSS_COMPILE}gcc --sysroot=$PLATFORM"
    export CC="${CROSS_COMPILE}gcc --sysroot=$PLATFORM -m32"
    export PKG_CONFIG="${CROSS_COMPILE}pkg-config"
    export LD="${CROSS_COMPILE}ld"
    export NM="${CROSS_COMPILE}nm"
    export STRIP="${CROSS_COMPILE}strip"
    export RANLIB="${CROSS_COMPILE}ranlib"
    export AR="${CROSS_COMPILE}ar"
    export LDFLAGS="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lm -lc -lgcc -ldl -llog"
    export PKG_CONFIG_LIBDIR=$PREFIX/lib/pkgconfig/
    export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig/


    if [ ! -f "${CROSS_COMPILE}gcc" ]; then
        echo "Gcc does not exists in path: ${CROSS_COMPILE}gcc"
        exit 1;
    fi

    if [ ! -f "${PKG_CONFIG}" ]; then
        echo "Pkg config does not exists in path: ${PKG_CONFIG} - Probably BUG in NDK but..."
        set +e
        SYS_PKG_CONFIG=$(which pkg-config)
        if [ "$?" -ne 0 ]; then
            echo "This system does not contain system pkg-config, so we can do anything"
            exit 1
        fi
        set -e
        cat > $PKG_CONFIG << EOF
#!/bin/bash
pkg-config \$*
EOF
        chmod u+x $PKG_CONFIG
        echo "Because we have local pkg-config we will create it in ${PKG_CONFIG} directory using ${SYS_PKG_CONFIG}"
    fi
    

}

function build_x264_x86
{
    echo "Starting build x264 for $ARCH"
    cd x264
    ./configure \
        --prefix=$PREFIX \
        --host=$ARCH-linux \
        --enable-static \
        $ADDITIONAL_CONFIGURE_FLAG

    make clean
    make -j4 install
    make clean
    cd ..
    echo "finished x264 for $ARCH"
}

function build_aac_x86
{
    echo "Starting build aac for $ARCH"
    cd vo-aacenc-0.1.3
    ./configure \
        --prefix=$PREFIX \
        --host=$ARCH-linux \
        --disable-dependency-tracking \
        --disable-shared \
        --enable-static \
        --with-pic \
        $ADDITIONAL_CONFIGURE_FLAG

    make clean
    make -j4 install
    make clean
    cd ..
    echo "Finished aac for $ARCH"
}


function build_ffmpeg_x86
{
    echo "Starting build ffmpeg-x86 for $ARCH"

    ./configure --target-os=linux \
        --prefix="$PREFIX" \
        --enable-cross-compile \
        --enable-runtime-cpudetect \
        --arch=$ARCH \
        --cc=$PREBUILT/bin/$EABIARCH-gcc \
        --cross-prefix=$PREBUILT/bin/$EABIARCH- \
        --disable-stripping \
        --nm=$PREBUILT/bin/$EABIARCH-nm \
        --sysroot=$PLATFORM \
        --extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums  -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
            --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -nostdlib -lc -lm -ldl -llog -L$PREFIX/lib" \
        --extra-cflags="-I$PREFIX/include" \
        --extra-libs="-lgcc" \
        --enable-static \
        --disable-shared \
        --disable-yasm \
        --disable-amd3dnow \
        --enable-version3 \
        --enable-gpl \
        --enable-libvo-aacenc \
        --enable-libx264 \
        --disable-everything \
        --enable-parser=h263 \
        --enable-parser=mpeg4video \
        --enable-demuxer=mov \
        --enable-decoder=amrnb \
        --enable-decoder=amrwb \
        --enable-decoder=h263 \
        --enable-decoder=aac \
        --enable-decoder=h264 \
        --enable-decoder=mpeg4 \
        --enable-encoder=mjpeg  \
        --enable-encoder=libvo_aacenc  \
        --enable-encoder=libx264  \
        --enable-muxer=mp4 \
        --enable-muxer=mov \
        --enable-protocol=file \
        --disable-ffmpeg \
        --disable-ffplay \
        --disable-ffprobe \
        --disable-ffserver \
        --disable-network \
        --disable-swscale-alpha \
        --disable-debug \
        --disable-logging \
        --enable-small \
        $ADDITIONAL_CONFIGURE_FLAG


    make clean
    make -j4 install
    make clean

    echo "Finished ffmpeg_x86 for $ARCH"
}

NDKROOT=/home/young/Documents/android-ndk-r9d
EABIARCH=i686-linux-android
ARCH=x86
OPTIMIZE_CFLAGS="-m32 -march=i686"
PREBUILT=$NDKROOT/toolchains/$ARCH-4.8/prebuilt/linux-x86_64
PREFIX=/home/young/Documents/FFmpeg3.1.2/output_android
PLATFORM_VERSION=android-14
ADDITIONAL_CONFIGURE_FLAG=--disable-asm


setup_paths
build_x264_x86
build_aac_x86
build_ffmpeg_x86

脚本中用的都是绝对路径,现实中使用的话需要都改成当前电脑上的配置路径。PREFIX是静态库的输出文件夹,setup_paths方法用于配置脚本的各种设置,后面的几个方法就是依次构建的过程。具体的配置命令的意思可以通过在本地包含configure的目录下使用./configure --help的命令查询。
总结一点就是胆大心细,多Google!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容