Linux下構(gòu)建帶vo-aacenc和x264的FFmpeg的Android ARM以及X86版本庫(kù)

背景:需要做一個(gè)Android端的視頻轉(zhuǎn)碼so庫(kù)使用炉菲,需要用到FFmpeg開源庫(kù)堕战,并且按需求集成進(jìn)X264vo-aacenc兩個(gè)靜態(tài)庫(kù),隨后就走上了不斷的踩坑和爬坑之路拍霜,現(xiàn)在特地記錄一下嘱丢,以供將來(lái)腦子不好的時(shí)候有個(gè)回想的根據(jù)。

構(gòu)建環(huán)境

系統(tǒng):Ubuntu16.04_64位(是的祠饺,還是Mac上跑的虛擬機(jī)越驻,網(wǎng)上有太多的Mac構(gòu)建FFmpeg的過(guò)程,然后爬了個(gè)把星期都不能用道偷,有哪位大神有靠譜點(diǎn)的教程歡迎分享)缀旁;
NDK:android-ndk-r9d(不要問(wèn)我為什么不用最新的,都是淚T T);
FFmpeg:2.0.7版本勺鸦,根據(jù)官方的Release Note發(fā)現(xiàn)3.0以上版本已經(jīng)不再支持vo-aacenc了并巍,所以下了2.0.X的版本;
vo-aacenc:0.1.3版本换途,是的懊渡,最新版本還是2013-07-27發(fā)布的嘶窄,就是說(shuō)該庫(kù)已經(jīng)光榮退休了,有條件的推薦使用fdk-aac嘗試編譯一下距贷;
X264:最新的就好,沒(méi)啥要求吻谋。

過(guò)程

過(guò)程無(wú)非就是寫編譯腳步忠蝗,調(diào)編譯腳本的過(guò)程,剛學(xué)習(xí)寫這玩意漓拾,過(guò)程時(shí)異常曲折阁最。首先從各自網(wǎng)站上下載FFmpeg、X264和vo-aacenc骇两,然后把壓縮包解壓后放到同一個(gè)目錄下速种,不如說(shuō)將x264以及vo-aacenc都放在FFmpeg解壓出來(lái)的文件夾下。這樣的好處是少寫幾個(gè)代碼低千,整個(gè)編譯過(guò)程可以放在同一個(gè)腳本中運(yùn)行配阵。順序是按照x264\vo-aacenc\ffmpeg的先后編譯,因?yàn)镕Fmpeg編譯的時(shí)候需要用到前面兩個(gè)已經(jīng)生成好的靜態(tài)庫(kù)示血。主要的腳本編譯放到后面去說(shuō)棋傍。

期間真的遇到了無(wú)數(shù)的坑,差點(diǎn)都要放棄了难审,(╯°Д°)╯︵ ┻━┻
主要摘了一些典型的記錄一下:
1.腳本運(yùn)行中出現(xiàn)No such file or directory VS no such command
別笑瘫拣,還真是這種問(wèn)題折磨的死去活來(lái)死去,因?yàn)槟_本里面要配置的東西太多了告喊,ToolChains的路徑又要配置好幾次麸拄,稍不留神寫錯(cuò)一個(gè)路徑,編譯就無(wú)法成功黔姜,這個(gè)時(shí)候千萬(wàn)淡定拢切,看看腳本命令行之間是不是都用\分隔著,路徑有沒(méi)有出錯(cuò)地淀,最好打印一下失球,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....
典型錯(cuò)誤帮毁,去掉腳本中的--enable-asm
3.undefined reference to "__umodsi3"
undefined reference to "__udivdi3"
在腳本中沒(méi)有指定連接的GCC庫(kù)实苞,添加-lgcc,多說(shuō)一句烈疚,-lgcc代表鏈接器將連接GCC的支持庫(kù)libgcc.a黔牵,-lm代表鏈接器將連接GCC的標(biāo)準(zhǔn)數(shù)學(xué)庫(kù)libm.a,-lc代表鏈接器將連接GCC的標(biāo)準(zhǔn)C庫(kù)libc.a爷肝。
4.諸如C compiler not found之類的錯(cuò)誤就是你的GCC路徑?jīng)]設(shè)對(duì)了猾浦。

構(gòu)建腳本

最后陆错,貼一下構(gòu)建的腳本(這個(gè)雖然是現(xiàn)成的,但是思想和踩坑經(jīng)過(guò)才是最重要的金赦!)
再啰嗦一句音瓷,標(biāo)題上寫的是構(gòu)建基于X86和armeabi的,那么為什么不加上arm64呢夹抗?對(duì)于ARM64架構(gòu)的so庫(kù)绳慎,目前無(wú)法編譯,因?yàn)閍rm64的GCC版本于Android-21(5.0.1-2014年發(fā)布)才開始支持漠烧,而FFmpeg中的AAC編解碼的開源模塊于2013年就已停止維護(hù)杏愤,官方文檔也說(shuō)明該庫(kù)不支持ARM64的架構(gòu)。話又說(shuō)回來(lái)已脓,64位也是兼容32位的靜態(tài)庫(kù)的珊楼,只不過(guò)性能上就要犧牲一下了。MIPS的畢竟太少太少度液,就不折騰了厕宗。
貼一下X86的運(yùn)行腳本,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

腳本中用的都是絕對(duì)路徑恨诱,現(xiàn)實(shí)中使用的話需要都改成當(dāng)前電腦上的配置路徑媳瞪。PREFIX是靜態(tài)庫(kù)的輸出文件夾,setup_paths方法用于配置腳本的各種設(shè)置,后面的幾個(gè)方法就是依次構(gòu)建的過(guò)程照宝。具體的配置命令的意思可以通過(guò)在本地包含configure的目錄下使用./configure --help的命令查詢蛇受。
總結(jié)一點(diǎn)就是膽大心細(xì),多Google厕鹃!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末兢仰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子剂碴,更是在濱河造成了極大的恐慌把将,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忆矛,死亡現(xiàn)場(chǎng)離奇詭異察蹲,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)催训,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門洽议,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人漫拭,你說(shuō)我怎么就攤上這事亚兄。” “怎么了采驻?”我有些...
    開封第一講書人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵审胚,是天一觀的道長(zhǎng)匈勋。 經(jīng)常有香客問(wèn)我,道長(zhǎng)膳叨,這世上最難降的妖魔是什么洽洁? 我笑而不...
    開封第一講書人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮菲嘴,結(jié)果婚禮上诡挂,老公的妹妹穿的比我還像新娘。我一直安慰自己临谱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開白布奴璃。 她就那樣靜靜地躺著悉默,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苟穆。 梳的紋絲不亂的頭發(fā)上抄课,一...
    開封第一講書人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音雳旅,去河邊找鬼跟磨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛攒盈,可吹牛的內(nèi)容都是我干的抵拘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼型豁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼僵蛛!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起迎变,我...
    開封第一講書人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤充尉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后衣形,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驼侠,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年谆吴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了倒源。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纪铺,死狀恐怖相速,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鲜锚,我是刑警寧澤突诬,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布苫拍,位于F島的核電站,受9級(jí)特大地震影響旺隙,放射性物質(zhì)發(fā)生泄漏绒极。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一蔬捷、第九天 我趴在偏房一處隱蔽的房頂上張望垄提。 院中可真熱鬧,春花似錦周拐、人聲如沸铡俐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)审丘。三九已至,卻和暖如春勾给,著一層夾襖步出監(jiān)牢的瞬間滩报,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工播急, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脓钾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓桩警,卻偏偏與公主長(zhǎng)得像可训,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捶枢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容