NDKr20編譯ffmpeg-4.2.2

思想覺悟發表於2020-02-17

有關ffmpeg的編譯資料網上一大推,但是照著資料拷貝的執行進行編譯能順利編譯出靜態庫或靜態庫產物的寥寥無幾。 筆者在學習的時候也是踩了很多的坑,確實是每次編譯會誕生一個放棄的念頭,原因還是自己的基礎學得不夠紮實。

因為ffmpeg和NDK都是在不斷進行迭代的,比如說NDK在r18之後之後徹底移除了gcc(包含r18版本),ffmpeg在4.o版本開始也針對Android平臺的交叉編譯預設使用clang編譯,但是網上的很多資料都是使用gcc編譯的。 所以如果要對照網上資料進行編譯的話,保證NDK版本和ffmpeg版本甚至是編譯環境工具都和作者的一樣,這樣會大大提高編譯的成功率。 在編譯成功之後再不斷嘗試修改引數結合搜尋資料嘗試,力求弄清楚每個引數的意義,做到觸類旁通。

本次編譯使用的是mac蘋果電腦,使用的NDK版本是r20,ffmpeg是從官網下載的最新版4.2.2。

編譯指令碼

從ffmpeg官網下載好原始碼解壓後,進入原始碼目錄,新建shell指令碼檔案,比如build_ffmpeg.sh
指令碼內容如下:

#!/bin/bash
# 將NDK的路徑替換成你自己的NDK路徑
NDK=/Users/liangchuanfei/Documents/Android/SDK/android-ndk-r20b
API=21
# arm aarch64 i686 x86_64
ARCH=arm
# 指定目標cpu的架構 armv7a aarch64 i686 x86_64
PLATFORM=armv7a

TARGET=$PLATFORM-linux-androideabi

# 設定工具鏈mac蘋果電腦的是darwin-x86_64 而如果是linux的話則是linux-x86_64

TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin

# 設定編譯產物的輸出目錄,這裡表示在當前目錄下新建Android_out目錄
PREFIX=./Android_out/$PLATFORM
 
CFLAG="-D__ANDROID_API__=$API -U_FILE_OFFSET_BITS -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD -Os -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm"
 
build_one()
{
./configure \
--ln_s="cp -rf" \
--prefix=$PREFIX \
--cc=$TOOLCHAIN/$TARGET$API-clang \
--cxx=$TOOLCHAIN/$TARGET$API-clang++ \
--ld=$TOOLCHAIN/$TARGET$API-clang \
--target-os=android \
--arch=$ARCH \
--cpu=$PLATFORM \
--cross-prefix=$TOOLCHAIN/$ARCH-linux-androideabi- \
--enable-cross-compile \
--enable-shared \
--disable-static \
--enable-runtime-cpudetect \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--enable-small \
--enable-gpl \
--enable-nonfree \
--enable-version3 \
--disable-iconv \
--enable-neon \
--enable-hwaccels \
--enable-jni \
--enable-mediacodec \
--disable-avdevice  \
--disable-decoders \
--enable-decoder=vp9 \
--enable-decoder=h264 \
--enable-decoder=mpeg4 \
--enable-decoder=aac \
--enable-decoder=h264_mediacodec \
--disable-postproc \
--extra-cflags="$CFLAG" \
--extra-ldflags="-marm"
}
 
build_one
 
make clean

# 使用4條執行緒進行編譯,增加編譯速度
make -j4
 
make install
複製程式碼

儲存後執行指令碼./build_ffmpeg.sh
執行指令碼的時候可能會遇到沒有許可權的問題,執行命令列chmod +x build_ffmpeg.sh增加一下執行許可權後再次執行即可進行編譯。
如果沒有報錯,大概幾分鐘後就能看編譯成功:

編譯成功
編譯成功後在目標輸出目錄下會生成三個檔案,如圖:
編譯成功後的目錄
其中include目錄下是使用動態庫或靜態庫時所需要的一些標頭檔案;
lib目錄存放這編譯產物動態庫或者靜態庫; share目錄則存放一些簡單的demo,我們可以參照這些demo編寫音視訊的編解碼等邏輯。

一些技巧

更多引數可在ffmpeg的原始碼目錄下執行./configure --help檢視。 CFLAG引數這麼長,怎麼來的?其實這個不用死記,可以從AS NDK工程的.externativeBuild/cmake/debug/armeabi-v7a/build.ninja中拷貝,需要注意的是替換掉NDK的路徑地址。
與網上gcc編譯的指令碼對比可以發現少了一些類似--sysroot這樣的引數,或許這就是clang的好處之一吧。

最後如果你對音視訊開發感興趣可掃碼關注,後續我們共同探討,共同進步。

NDKr20編譯ffmpeg-4.2.2

相關文章