Linux下ndk編譯移植FFmpeg到Android平臺(tái)(二)——集成x264和libfdk-aac

在前面的Linux下ndk編譯移植FFmpeg到Android平臺(tái)文章中介紹了如何將最基本的FFmpeg到Android平臺(tái)。但只是簡(jiǎn)單的移植了FFmpeg亥宿,沒有包含x264編碼器,并且AAC編碼器也只有默認(rèn)的题诵。在Android平臺(tái)下使用FFmpeg進(jìn)行RTMP推流(攝像頭推流)中我實(shí)際上已經(jīng)用到了x264編碼器拷淘,但沒有介紹如何將x264集成到FFmpeg中。而本篇文章將解決這個(gè)問題茄猫,重點(diǎn)講解如何集成x264和libfdk-aac狈蚤,當(dāng)然也會(huì)有問題匯總。

為什么要單獨(dú)一篇文章來介紹如何去移植FFmpeg划纽、x264和fdk_aac呢脆侮?
萬事開頭難,第一步很難勇劣,但也是最重要的靖避,不怕告訴大家,就僅僅編譯這幾個(gè)東西我足足花了兩天時(shí)間去踩坑比默。對(duì)于有些編譯出現(xiàn)各種問題導(dǎo)致沒有成功的兄弟幻捏,可能非常的挫傷積極性,打擊學(xué)習(xí)這方面知識(shí)的積極性命咐。所以我覺得有必要重點(diǎn)講解下這個(gè)環(huán)節(jié)

在進(jìn)入這是內(nèi)容之前我要強(qiáng)調(diào)一點(diǎn)篡九,一定要注意安裝版本,這個(gè)安裝版本包括linux系統(tǒng)版本醋奠、FFmpeg版本榛臼、x264版本、libfdk-aac版本窜司、ndk中android-api版本沛善。你可能會(huì)因?yàn)榘姹静黄ヅ鋵?dǎo)致編譯出現(xiàn)各種問題,既然我已經(jīng)把這些坑踩過了塞祈,希望大家不要再掉進(jìn)去

同步開源庫(kù)FFmpegSample金刁,里面有我最新編譯好的so 和對(duì)應(yīng)的編譯腳本build_x264.sh,build_fdk.sh,build_ffmpeg.sh

文章圍繞以下幾點(diǎn)介紹

  • 編譯環(huán)境
  • x264編譯
  • libfdk-aac編譯
  • FFmpeg 編譯
  • 踩坑歷程

編譯環(huán)境

  • linux版本 centos 6.8_64位 或 CentOS Linux release 7.4.1708 (Core)
[root@iZ94g6hanmqZ include]# lsb_release -a
LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description:    CentOS release 6.8 (Final)
Release:    6.8
Codename:   Final
[root@localhost /]# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core)
  • ndk版本 android-ndk-r15c
    我的安裝位置在/usr/local/app/android-ndk-r15c

接下來到了真正編譯的時(shí)候了

編譯x264

下載地址下載版本x264-snapshot-20140916-2245-stable.tar

2.png

然后解壓為x264目錄,進(jìn)入x264目錄织咧,新建build_x264.sh內(nèi)容為:

#!/bin/bash
#NDK=/usr/local/android/ndk-bundle
NDK=/usr/local/app/android-ndk-r15c
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
PLATFORM=$NDK/platforms/android-16/arch-arm
PREFIX=./android
echo $NDK
echo $TOOLCHAIN
echo $PLATFORM
echo $PREFIX
function build_one
{
    ./configure \
         --prefix=$PREFIX \
         --enable-static \
         --disable-shared \
         --enable-pic \
         --disable-asm \
         --disable-cli \
         --host=arm-linux \
         --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
         --sysroot=$PLATFORM \
 
}
build_one

然后給文件增加運(yùn)行權(quán)限 chmod +x build_x264.sh胀葱。剩下的就是配置編譯安裝啦。

./build_x264.sh
make -j4
make install

安裝目錄就在當(dāng)前目錄下生成android目錄笙蒙,當(dāng)然庫(kù)文件和頭文件就有了

drwxr-xr-x 2 root root 4096 Jan 25 15:06 include
drwxr-xr-x 3 root root 4096 Jan 25 15:06 lib

編譯libfdk-aac

先來幾個(gè)問題:

    1. 為啥要集成libfdk-aac呢抵屿?
      嘿嘿!別著急捅位,這個(gè)我會(huì)在下篇文章介紹ffmpeg進(jìn)行AAC編碼時(shí)候講到轧葛,這里我只講如何編譯。
    1. 為什么不集成libfaac艇搀?
      不少嘗試過的童鞋會(huì)發(fā)現(xiàn)尿扯,在編譯FFmpeg時(shí)集成libfaac也就是configure增加--enable-libfaac參數(shù)時(shí)會(huì)提示ffmpeg: remove option for libfaac,Unknown option "--enable-libfaac",因?yàn)楝F(xiàn)在FFmpeg不支持libfaac擴(kuò)展了焰雕。而網(wǎng)上很多比較早期的文章都是講如何集成libfaac的衷笋,所以很多童鞋就比較疑惑。
3.png

下面正式進(jìn)入編譯fdk_aac
下載地址版本選擇0.1.4

4.png

同樣加壓到fdk-aac-0.1.4目錄矩屁,進(jìn)入目錄辟宗,新建build_fdk.sh內(nèi)容為:

#!/bin/bash
NDK_HOME=/usr/local/app/android-ndk-r15c
ANDROID_API=android-14
SYSROOT=$NDK_HOME/platforms/$ANDROID_API/arch-arm
ANDROID_BIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/
CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
ARM_INC=$SYSROOT/usr/include
ARM_LIB=$SYSROOT/usr/lib
LDFLAGS=" -nostdlib -Bdynamic -Wl,--whole-archive -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$NDK_HOME/sources/cxx-stl/gnu-libstdc++/libs/armeabi -L$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/arm-linux-androideabi/lib -L$ARM_LIB  -lc -lgcc -lm -ldl  "
FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared"
export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"
export LDFLAGS="$LDFLAGS"
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
./configure $FLAGS  --prefix='/usr/local/app/fdk-aac-0.1.4/android'

剩下的就是配置編譯安裝啦爵赵。

./build_fdk.sh
make -j4
make install

安裝目錄就在當(dāng)前目錄下生成android目錄,當(dāng)然庫(kù)文件和頭文件就有了

drwxr-xr-x 2 root root 4096 Jan 25 15:06 include
drwxr-xr-x 3 root root 4096 Jan 25 15:06 lib

編譯FFmpeg

FFmpeg版本3.2.4 下載地址
下載完源碼解壓后泊脐,我們進(jìn)入目錄先修改configure文件
中的下面四行:

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'

替換為:

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

這里是修改編譯完成后so文件的文件名格式

新建build_ffmpeg.sh腳本空幻,內(nèi)容

#!/bin/bash
NDK=/usr/local/app/android-ndk-r15c
SYSROOT=$NDK/platforms/android-16/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

function build_one
{
./configure  --prefix=$PREFIX \
    --enable-shared \
    --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
    --disable-static \
    --disable-doc \
    --disable-ffserver \
    --disable-yasm \
    --enable-cross-compile \
    --enable-gpl \
    --enable-libx264 \
    --enable-decoder=h264 \
    --enable-encoder=libx264 \
    --enable-libfdk-aac \
    --enable-encoder=libfdk_aac \
    --enable-decoder=libfdk_aac \
    --enable-nonfree \
    --cross-prefix="$TOOLCHAIN/bin/arm-linux-androideabi-" \
    --target-os=linux \
    --arch=arm \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
}

CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm -I/usr/local/app/x264-snapshot-20140916-2245-stable/android/include -DANDROID -I/usr/local/app/fdk-aac-0.1.4/android/include"
ADDI_LDFLAGS="-L/usr/local/app/x264-snapshot-20140916-2245-stable/android/lib -L/usr/local/app/fdk-aac-0.1.4/android/lib"

build_one

然后給文件增加運(yùn)行權(quán)限 chmod +x build_ffmpeg.sh。剩下的就是配置編譯安裝啦容客。

./build_x264.sh
make -j4
make install

安裝完之后我們最終的so包就生成了秕铛。在當(dāng)前目錄下的 ./android/arm下。

drwxr-xr-x  2 root root 4096 Jan 25 15:23 bin
drwxr-xr-x 10 root root 4096 Jan 25 15:11 include
drwxr-xr-x  3 root root 4096 Jan 25 15:23 lib
drwxr-xr-x  3 root root 4096 Jan 25 15:11 share

我們的動(dòng)態(tài)庫(kù)就在lib下了

-rwxr-xr-x 1 root root 12983912 Jan 25 15:23 libavcodec-57.so
lrwxrwxrwx 1 root root       16 Jan 25 15:23 libavcodec.so -> libavcodec-57.so
-rwxr-xr-x 1 root root    59384 Jan 25 15:23 libavdevice-57.so
lrwxrwxrwx 1 root root       17 Jan 25 15:23 libavdevice.so -> libavdevice-57.so
-rwxr-xr-x 1 root root  1877548 Jan 25 15:23 libavfilter-6.so
lrwxrwxrwx 1 root root       16 Jan 25 15:23 libavfilter.so -> libavfilter-6.so
-rwxr-xr-x 1 root root  1956464 Jan 25 15:23 libavformat-57.so
lrwxrwxrwx 1 root root       17 Jan 25 15:23 libavformat.so -> libavformat-57.so
-rwxr-xr-x 1 root root   443860 Jan 25 15:23 libavutil-55.so
lrwxrwxrwx 1 root root       15 Jan 25 15:23 libavutil.so -> libavutil-55.so
-rwxr-xr-x 1 root root    42276 Jan 25 15:23 libpostproc-54.so
lrwxrwxrwx 1 root root       17 Jan 25 15:23 libpostproc.so -> libpostproc-54.so
-rwxr-xr-x 1 root root    91532 Jan 25 15:23 libswresample-2.so
lrwxrwxrwx 1 root root       18 Jan 25 15:23 libswresample.so -> libswresample-2.so
-rwxr-xr-x 1 root root   406924 Jan 25 15:23 libswscale-4.so
lrwxrwxrwx 1 root root       15 Jan 25 15:23 libswscale.so -> libswscale-4.so
drwxr-xr-x 2 root root     4096 Jan 25 15:23 pkgconfig

這里對(duì)腳本做個(gè)解釋缩挑,增加了幾個(gè)命令但两。

  • 支持x264擴(kuò)展
    --enable-libx264 \
    --enable-decoder=h264 \
    --enable-encoder=libx264 \
  • 支持fdk_aac擴(kuò)展
    --enable-libfdk-aac \
    --enable-encoder=libfdk_aac \
    --enable-decoder=libfdk_aac \

要支持fdk_aac必須還加上

    --enable-nonfree \
    --enable-gpl \

最后就是制定x264 fdk_aac的頭文件和庫(kù)文件的目錄--extra-cflags加入頭文件目錄,--extra-ldflags包含庫(kù)文件目錄,也就是

ADDI_CFLAGS="-marm -I/opt/x264/android/include -DANDROID -I/opt/fdk-aac-0.1.4/android/include"
ADDI_LDFLAGS="-L/opt/x264/android/lib -L/opt/fdk-aac-0.1.4/android/lib"

到這里我們就完成了整個(gè)編譯调煎。得到的so庫(kù)不僅有FFmpeg基礎(chǔ)功能镜遣,還有x264和fdk_aac的編解碼功能


踩坑歷程

configure FFmpeg提示找不到x264

看到這個(gè)問題,我開始很詫異士袄,我明明都配置正確了,后來查看config日志谎僻,提示 找不到什么log2方法娄柳。后來發(fā)現(xiàn)新版本的x264的config.h中啟用了這個(gè)方法,所以大家按我選擇的版本就沒問題啦艘绍。

make FFmpeg 報(bào)錯(cuò)

libavcodec/libx264.c: In function 'x264_frame' :
libavcodec/libx264.c:282:9 error: 'x264_bit_depth' undeclared(first use in this function)  
             if(x264_bit_depth>8)     

libavcodec/libx264.c: In function 'x264_init_static':
libavcodec/libx264.c:892.9 error: 'x264_bit_depth' undeclared(first use in this function)
             if(x264_bit_depth== 8)  

很明顯沒有找到x264_bit_depth這個(gè)變量赤拒。那咋辦,還是版本不對(duì)應(yīng)咯诱鞠。你用的x264挎挖,F(xiàn)Fmpeg可能不太兼容哦。

configure FFmpeg是faac不能用

這個(gè)前面已經(jīng)提到了,FFmpeg已經(jīng)不再支持libfaac啦航夺。

編譯好的so 蕉朵,放在android平臺(tái)下使用時(shí),提示找不到x264.so

這里要注意阳掐,我在編譯x264和fdk_aac時(shí)全部使用的靜態(tài)編譯始衅,編出來的是靜態(tài)庫(kù)。那么最終我編譯完FFmpeg后就不需要講x264的so加入到android應(yīng)用項(xiàng)目中缭保。如果你是動(dòng)態(tài)編譯x264和fdk_aac那么你就得把這兩個(gè)庫(kù)的so也加入到android應(yīng)用項(xiàng)目中汛闸。
注意編譯x264和fdk_aac中間的參數(shù)--enable-static --disable-shared


到此所有講解結(jié)束了,先預(yù)告下一篇艺骂,下一篇將介紹Android平臺(tái)下使用FFmpeg進(jìn)行AAC編譯诸老。里面會(huì)給大家解釋為什么要用fdk_aac,而不用默認(rèn)的AAC編碼器钳恕。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末别伏,一起剝皮案震驚了整個(gè)濱河市蹄衷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌畸肆,老刑警劉巖宦芦,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異轴脐,居然都是意外死亡调卑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門大咱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恬涧,“玉大人,你說我怎么就攤上這事碴巾∷堇Γ” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵厦瓢,是天一觀的道長(zhǎng)提揍。 經(jīng)常有香客問我,道長(zhǎng)煮仇,這世上最難降的妖魔是什么劳跃? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮浙垫,結(jié)果婚禮上刨仑,老公的妹妹穿的比我還像新娘。我一直安慰自己夹姥,他們只是感情好杉武,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辙售,像睡著了一般轻抱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上圾亏,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天十拣,我揣著相機(jī)與錄音,去河邊找鬼志鹃。 笑死夭问,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曹铃。 我是一名探鬼主播缰趋,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了秘血?” 一聲冷哼從身側(cè)響起味抖,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎灰粮,沒想到半個(gè)月后仔涩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粘舟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年熔脂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柑肴。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡霞揉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晰骑,到底是詐尸還是另有隱情适秩,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布硕舆,位于F島的核電站秽荞,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏抚官。R本人自食惡果不足惜蚂会,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耗式。 院中可真熱鬧,春花似錦趁猴、人聲如沸刊咳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)娱挨。三九已至,卻和暖如春捕犬,著一層夾襖步出監(jiān)牢的瞬間跷坝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工碉碉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柴钻,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓垢粮,卻偏偏與公主長(zhǎng)得像贴届,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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