轉自:https://juejin.im/post/5e130df55188253a8b42ebac
目錄
一、Android音視頻硬解碼篇:
二、使用OpenGL渲染視頻畫面篇
- 1,初步瞭解OpenGL ES
- 2,使用OpenGL渲染視頻畫面
- 3,OpenGL渲染多視頻,實現畫中畫
- 4,深入瞭解OpenGL之EGL
- 5,OpenGL FBO數據緩衝區
- 6,Android音視頻硬編碼:生成一個MP4
三、Android FFmpeg音視頻解碼篇
- 1,FFmpeg so庫編譯
- 2,Android 引入FFmpeg
- 3,Android FFmpeg視頻解碼播放
- 4,Android FFmpeg+OpenSL ES音頻解碼播放
- 5,Android FFmpeg+OpenGL ES播放視頻
- 6,Android FFmpeg簡單合成MP4:視屏解封與重新封裝
- 7,Android FFmpeg視頻編碼
本文你可以瞭解到
使用
GCC
或CLANG
交叉編譯出Android平臺可以使用的FFmpeg so庫。爲了很好的邁出FFmpeg
開發的第一步,不僅要知其然,更要知其所以然。不僅要知道怎麼樣能成功編譯,更要知道爲什麼能成功編譯。在開始動手之前,建議先通讀整篇文章,相信本文定可以讓你有所感悟。
一、前言
網上其實已經有很多的關於FFmpeg so庫編譯的分享,但是大部分都是直接把配置文件的內容貼出來。我想大部分去搜索 「如何編譯FFmpeg so庫」的人,對交叉編譯這個東東都是比較陌生的。
特別對於移動端開發者來說,大部分人大多數時候都是在Java層做開發,很少接觸到NDK層的東西。如果直接去看一份交叉編譯的配置,估計會很上頭。
通常情況下,在一篇FFmpeg編譯的文章下面都會有很多的類似「爲什麼按照樓主的配置還是無法編譯成功?」的評論,那爲什麼人家可以編譯成功,我們copy下來卻不可以呢?
原因有非常多,大部分其實集中在以下幾個方面:
1. 無腦copy,祈求有一個傻瓜式的配置可以成功編譯;
2. FFmpeg版本和NDK版本很多,每一個版本都可能需要不一樣的配置;
3. 不瞭解每個配置項的意義,即使好運配置對了, 但是稍微一修改,又無法正常編譯了。
複製代碼
爲什麼FFmpeg讓人覺得很難搞?
我想主要是因爲邁出第一步就很困難,連so庫都編譯不出來,後面的都是扯淡了。
二、什麼是交叉編譯
定義
引自百度百科的定義:交叉編譯,是在一個平臺上生成另一個平臺上的可執行代碼。
什麼意思呢?說白了,就是在一個機器上生成一個程序,這個程序可以跑在另外一個機器上。舉慄:在PC上編譯一個apk,這個apk可以跑在Android手機上,這其實就是一個交叉編譯的過程。
爲什麼要交叉編譯
我們知道,PC上的軟件是直接在PC上編譯生成的,那爲什麼Android上的軟件不能在Android上自己編譯生成呢?
理論上是可以,但是Android手機上的資源有限啊,在PC上編譯一個apk都要那麼久,你可以想象在Android手機上編譯一個apk要多久嗎?或者你能想象在手機上敲代碼的情景嗎?
那我們會想既然PC上資源那麼豐富,那可不可以利用PC來編譯出在手機上可以運行的軟件呢?
於是,交叉編譯出現。
交叉編譯需要的什麼
編譯環境
我們知道PC上的環境和手機上的運行環境是絕然不同的,如果使用PC上的環境直接編譯的話,可以想象這個編譯出來的App,分分鐘就會掛掉。
所以,交叉編譯最重要的是,要配置好編譯過程中使用到的相關的環境,而這個環境其實就是目標機器(比如Android手機)正在運行的環境。
編譯工具鏈
對於C/C++的編譯,通常有兩個工具 GCC
和 CLANG
。
GCC
可能大家都有聽說過,這是一個老牌的編譯工具,不僅可以編譯C/C++,也可以編譯Java,Object-C,Go等語言。
CLANG
則是一個效率更高的C/C++編譯工具,並且兼容GCC,Google在很早以前就開始建議使用clang進行編譯,並且在 ndk 17
以後,把 GCC
移除了,全面推行使用 CLANG
。
三、如何交叉編譯FFmpeg
FFmpeg是什麼
鼎鼎大名的FFmpeg,不說在音視頻界如雷貫耳,就算一個不開發音視頻的開發者也都是略有耳聞。
官方簡介
A complete, cross-platform solution to record, convert and stream audio and video.
翻譯過來就是:FFmpeg是一套集錄制、轉換以及流化音視頻的完整的跨平臺解決方案。
從這段簡介可以看到FFmpeg有以下特點:
- 功能強大:錄製、解碼、編碼、編輯、推流等等
- 跨平臺
編譯流程
從前面的介紹,基本上可以總結出FFmepg編譯的基本流程:
- 選擇編譯工具
- 配置交叉編譯環境
- 配置編譯參數(比如去掉一些不需要的功能)
- 啓動編譯
流程就是這麼簡單,接下來就來詳細看看,如何通過 CLANG
和 GCC
兩種方式來編譯。
四、使用CLANG編譯FFmpeg
注:本文編譯平臺爲Mac,建議使用Mac或者Linux進行編譯,據說Windows有很多坑。
下載Android NDK
Android 的 NDK
已經迭代了很多版本,在 r17c
以後,Google正式移除 GCC
,不再支持 GCC
,新版本的 NDK
都是使用 CLANG
進行編譯。
這裏就使用目前最新的 NDK r20b
版本來編譯。
NDK
下載地址:Android-NDK
NDK 目錄
最主要的就是這兩個路徑:
編譯工具鏈目錄:
toolchains/llvm/prebuilt/darwin-x86_64/bin
交叉編譯環境目錄:
toolchains/llvm/prebuilt/darwin-x86_64/sysroot
複製代碼
- 編譯工具路徑
根據不同的CPU架構區和不同的Android版本,區分了不同的clang工具,根據自己需要選擇就好了。
本文選擇 CPU 架構 armv7a
,Android版本 21
:
armv7a-linux-androideabi21-clang
armv7a-linux-androideabi21-clang++
複製代碼
- 編譯環境路徑
在 toolchains/llvm/prebuilt/darwin-x86_64/sysroot
目錄下,包含了兩個目錄: usr/include
,usr/lib
,分別對應了 頭文件
和 庫文件
。
下載FFmpeg源碼
FFmpeg官網下載,直接DownLoad即可。
本文使用的是目前最新的版本 ffmpeg-4.2.2
。
下載好源碼後,進入根目錄,找到一個名爲 congfigure
的文件,這是一個shell腳本,用於生成一些 FFmpeg
編譯需要的配置文件。
這個文件非常重要,
FFmpeg
的編譯配置就是靠它完成的。 後面我們將對其中一些重要的內容進行分析,這是理解FFmpeg
編譯配置的關鍵。
有了以上基礎以後,就可以對FFmpeg進行編譯了。
配置腳本
- 修改 configure 腳本
- 新增
cross_prefix_clang
參數
打開(注:不是雙擊運行) ffmpeg-4.2.2
根目錄下的 configure
文件,搜索 CMDLINE_SET
,可以找到以下代碼,然後新增一個命令行選項:cross_prefix_clang
CMDLINE_SET="
$PATHS_LIST
ar
arch
as
assert_level
build_suffix
cc
objcc
cpu
cross_prefix
# 新增命令行參數
cross_prefix_clang
custom_allocator
cxx
dep_cc
# 省略其他.....
"
複製代碼
- 修改編譯工具路徑設置
搜索 ar_default="${cross_prefix}${ar_default}"
, 找到以下代碼
ar_default="${cross_prefix}${ar_default}"
cc_default="${cross_prefix}${cc_default}"
cxx_default="${cross_prefix}${cxx_default}"
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"
複製代碼
將中間兩行修改爲
ar_default="${cross_prefix}${ar_default}"
#------------------------------------------------
cc_default="${cross_prefix_clang}${cc_default}"
cxx_default="${cross_prefix_clang}${cxx_default}"
#------------------------------------------------
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"
複製代碼
至於爲什麼這麼修改,將在後面的 configure
分析中詳細講解
- 新建編譯配置腳本
在 ffmpeg-4.2.2
根目錄下新建 shell
腳本,命名爲: build_android_clang.sh
#!/bin/bash
set -x
# 目標Android版本
API=21
CPU=armv7-a
#so庫輸出目錄
OUTPUT=/Users/cxp/Desktop/FFmpeg/ffmpeg-4.2.2/android/$CPU
# NDK的路徑,根據自己的NDK位置進行設置
NDK=/Users/cxp/Desktop/FFmpeg/android-ndk-r20b
# 編譯工具鏈路徑
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
# 編譯環境
SYSROOT=$TOOLCHAIN/sysroot
function build
{
./configure \
--prefix=$OUTPUT \
--target-os=android \
--arch=arm \
--cpu=armv7-a \
--enable-asm \
--enable-neon \
--enable-cross-compile \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-ffmpeg \
--sysroot=$SYSROOT \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--cross-prefix-clang=$TOOLCHAIN/bin/armv7a-linux-androideabi$API- \
--extra-cflags="-fPIC"
make clean all
# 這裏是定義用幾個CPU編譯
make -j12
make install
}
build
複製代碼
這個shell腳本,大體上其實還是很容易懂的,比如
--disabble-static
--enable-shared
分別用於禁止輸出靜態庫,以及輸出動態庫;
--arch
--cpu
用於配置輸出的so庫是什麼架構的;
--prefix
用於配置輸出的so庫的存放路徑。
接下來重點來講一下幾個選項:
- target-os
--target-os=android
:在舊版本的 FFmpeg
中,對Android平臺的支持並不是很完善,並沒有 android
這個target,所以在一些比較老的文章中都會提到,編譯Android平臺的so庫,需要對 configure
做以下修改,否則會按照 linux
標準的方式輸出so庫,其命名方式和Android的so不一樣,Android是無法加載的。
SLIBNAME_WITH_VERSION='$(SLIBNAME).$(LIBVERSION)'
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_VERSION='$(SLIBNAME).$(LIBVERSION)'
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
複製代碼
但是在新版本的FFmpeg中,這個問題終於被解決了,FFmpeg加入了 android
這個 target
。所以我們再也不需要手動去修改了
。
- sysroot
--sysroot=$SYSROOT
: 用於配置交叉編譯環境的 根路徑
,編譯的時候會默認從這個路徑下去尋找 usr/include
usr/lib
這兩個路徑,進而找到相關的頭文件和庫文件。
r20b
版本的 NDK
系統的頭文件和庫文件就是在 $SYSYROOT/usr/include
和 $SYSYROOT/usr/lib
中。
基本上很多新手在編譯的時候都會出現找不到各種頭文件,導致編譯失敗。所以當編譯出現找不到頭文件的時候,首先要檢查的就是這個路徑。
一點疑問
在使用最新的
ndk r20b
版本進行編譯的時候發現,即使不配置sysroot
也可以正常編譯,懷疑 Android 的clang
工具是否經過了處理,會自動去尋找對應的路徑。 目前沒有從configure
文件中找到原因。
如有知情者的,還望告知呀~。
說到 sysroot
就不得不提到另外一個參數 -isysyroot
,這個參數也讓我困惑了很久,因爲很少文章會提到這個兩個參數的聯繫和區別,然而這個參數也很導致讓人很莫名奇妙的編譯失敗。
- extra-cflags
介紹 -isysroot
之前,先看看這個 extra-cflags
選項。
這個選項的作用是,給編譯器指定除了 sysroot
之外的頭文件搜索路徑。比如:
--extra-cflags="-I$SYSROOT/usr/include"
# 其中 -I 用於區分不同的路徑
複製代碼
而 -isysroot
是這個選項的一個配置。比如
--extra-cflags="-isysroot $SYSROOT"
複製代碼
-isysroot
的作用就是,把後面的路徑設置爲默認的頭文件搜索路徑,這時候,前面 sysroot
配置路徑就不再作爲 頭文件
默認的搜索路徑了,不過依然是 庫文件
默認的搜索路徑。
可以看到,這兩個配置從某種程度上說是一樣的:
--extra-cflags="-I$SYSROOT/usr/include"
約等於
--extra-cflags="-isysroot $SYSROOT"
複製代碼
- extra-ldflags
這個和上面的 extra-cflags
作用是類似的,不過是用於配置額外的 庫文件
搜索路徑,如
--extra-ldflags="-L$SYSROOT/usr/lib"
# 其中 -L 用於區分不同的路徑
複製代碼
可以看到 extra-cflags
extra-ldflags
結合起來可以替代 sysroot
。
- cross-prefix
這個選項直譯爲 交叉編譯前綴
,指的是交叉編譯工具的前綴。
這個選項經常和另外一個選項 cc
一起出現搭配使用。
這是什麼意思呢?網上有的文章對於 cc
這個選項經常出現兩種配置方式:
一種是隻配置 cross-prefix
,沒有配置 cc
,比如本文。
另一種是既配置 cross-prefix
,又配置 cc
。
比如:
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
複製代碼
這是兩種完全不同的配置方式,但是很神奇的是有時候他們都能成功編譯,有時候又會出現找不到編譯鏈工具的錯誤。
爲了搞明白 cross-prefix
cc
這兩個選項的配置到底有什麼影響,到底應該怎麼使用這兩個配置,我特地仔細的去看了 FFmpeg
根目錄下的 configure
配置腳本,找到了一些蛛絲馬跡。
分析 configure 配置腳本
注:以下分析基於ffmpeg-4.2.2版本,其他版本可能有所不同,掌握基本原理即可。
- 獲取用戶配置選項
打開(注:不是雙擊運行)configure
shell腳本,首先來看看 configure 是如何獲取用戶配置的編譯選項的。
搜索 for opt do
,可以找到以下代碼
for opt do
optval="${opt#*=}"
case "$opt" in
--extra-ldflags=*)
add_ldflags $optval
;;
--extra-ldexeflags=*)
add_ldexeflags $optval
;;
--extra-ldsoflags=*)
add_ldsoflags $optval
;;
--extra-ldlibflags=*)
warn "The --extra-ldlibflags option is only provided for compatibility and will be\n"\
"removed in the future. Use --extra-ldsoflags instead."
add_ldsoflags $optval
;;
--extra-libs=*)
add_extralibs $optval
;;
--disable-devices)
disable $INDEV_LIST $OUTDEV_LIST
;;
--enable-debug=*)
debuglevel="$optval"
;;
# 省略中間一些代碼...
*)
optname="${opt%%=*}"
optname="${optname#--}"
optname=$(echo "$optname" | sed 's/-/_/g')
if is_in $optname $CMDLINE_SET; then
eval $optname='$optval'
elif is_in $optname $CMDLINE_APPEND; then
append $optname "$optval"
else
die_unknown $opt
fi
;;
esac
done
複製代碼
這個shell腳本的代碼有很多特有的語法,也不用鑽牛角尖,能大概看明白就可以了。
for循環的首行 通過分割 =
獲取到用戶設置的選項值 optval
。
下面除了一些特殊的選項,我們看看最後的通配符 *)
,這段代碼的目的,其實就是把用戶配置的選項和值關聯起來。
比如 --cpu=armv7-a
,前面三行就是把 cpu
分割出來,賦值給 optname
,再把 optval
賦值給 cpu
,說白了就是初始化了 cpu
這個變量爲 armv7-a
。
- Android相關的配置
搜索 android
關鍵字,可以找到以下代碼
# ffmpeg-4.2.2/configure
if test "$target_os" = android; then
cc_default="clang"
fi
ar_default="${cross_prefix}${ar_default}"
cc_default="${cross_prefix}${cc_default}"
cxx_default="${cross_prefix}${cxx_default}"
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"
複製代碼
當你配置了 --target-os=android
的時候,FFmpeg默認的編譯工具爲 clang
。
cc_default
其實就是配置項 cc
的默認值,可以看到 cc_default
在這裏和 cross_prefix
做了拼接。這裏就是爲什麼說 cross_prefix
是交叉編譯工具前綴。
拼接完是這樣的:
cc_defalut=$TOOLCHAIN/bin/arm-linux-androideabi-$cc
複製代碼
看下 ar_default
cc_default
cxx_default
這些默認值是什麼。
搜索 cc_default
可以找到以下代碼
# ffmpeg-4.2.2/configure
ar_default="ar"
cc_default="gcc"
cxx_default="g++"
host_cc_default="gcc"
複製代碼
可以看到,FFmpeg 默認的編譯工具是 GCC
。
當你編譯 Android 平臺的庫時,由於 configure
強制設置 cc_default="clang"
,所以:
-
當你使用
GCC
作爲編譯工具時,必須配置cc
選項,或修改configure
中的cc_default="clang"
爲cc_default="gcc"
; -
當你使用
CLANG
作爲編譯工具時,可以不配置cc
選項。
仔細想想會發現,爲什麼當 cc
配置爲下邊的值時,也可以正常編譯呢?
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
複製代碼
這時 cc_defalut
不就等於
cc_defalut=$TOOLCHAIN/bin/arm-linux-androideabi-$TOOLCHAIN/bin/arm-linux-androideabi-gcc
複製代碼
這個路徑肯定是錯的啊!
這就要來看到底 cc_default
是怎麼使用的了。
- 初始化變量
搜索 set_default arch
,可以看到以下代碼,在這裏 configure
重新設置了 cc
的默認值。
set_default arch cc cxx doxygen pkg_config ranlib strip sysinclude \
target_exec x86asmexe nvcc
複製代碼
這裏調用了一個叫 set_default
的函數,來看看這個函數的實現
set_default(){
for opt; do
eval : \${$opt:=\$${opt}_default}
done
}
複製代碼
這也是一個看不太懂的shell語法,大概的意思就是:for循環獲取所有的輸入參數變量,然後給這個變量賦值。
比如 set_default cc
,意思就是 cc=cc_default
,不過有一點要注意的是中間這個符號 :=
。
這個符號類似Java中的三目運算符:
opt != null? opt:opt_defalut
複製代碼
也就是說,如果參數爲空,將 xx_default
賦值給 xx
。
這就可以解釋上面的疑問了。
- 當配置
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
複製代碼
set_default cc
等於沒有用了。因爲經過 for
循環獲取了用戶的配置以後, cc
不爲空。 set_default
後,cc
的值是不會改變的。
-
當
cc
不配置的時候,FFmpeg 根據默認的拼接方式,把拼接好的路徑設置給cc
。 -
但是,不能配置
cc=gcc
這種,這樣,最後cc
的值就只有gcc
,肯定是不能正確找到編譯工具的。
- 爲什麼要加入
corss-prefix-clang
這個選項
現在可以來解釋爲什麼前面需要修改 configure
配置腳本了。
原始的配置是這樣的
ar_default="${cross_prefix}${ar_default}"
cc_default="${cross_prefix}${cc_default}"
cxx_default="${cross_prefix}${cxx_default}"
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"
複製代碼
也就是說,默認的 cc
ar
nm
路徑前綴是一樣的,但是 Android NDK
的路徑卻是這樣的
看到了不?ar
/nm
和 cc
的前綴是不一樣的,前者是 arm-linux-androideabi-
, 後者是 armv7a-linux-androideabi16-
。
因此,需要對 cc
和 cxx
兩個前綴進行修改,爲此新加了 cross_prefix_clange
來進行單獨配置。
這裏只是針對 NDK r20b 的情況,不同的 NDK 版本可能有所不同,根據這個原理去設置即可。
綜上,解釋了一些編譯 FFmpeg 常用的配置選項,並且從原理上弄明白爲何要這樣配置,基本上搞清楚了這些,想要組合兩個不同版本的FFmpeg和NDK來編譯,都會比較容易實現。
啓動編譯
打開cmd終端,cd 到 FFmpeg 所在目錄
輸入 ./build_android_clang.sh
等待編譯完成,將會在 ffmpeg/android/armv7-a目錄下得到 include
和 lib
兩個目錄,分別是 頭文件
和 so庫文件
五、使用 GCC 編譯FFmpeg
目前大部分網上的文章都是使用 GCC
來編譯 FFmpeg
的,下面就來看看如何配置 GCC
的編譯參數。
下載 Android NDK r17b
前面就說過,NDK r17c 以後,Googole 就移除了 GCC,所以要使用 GCC 只能下載 r17c 及以前的版本,本文使用 r17c 來編譯。
根據自己編譯平臺選擇對應的版本:NDK r17c
本文選擇的是 Mac 版本:Mac OS X。
NDK 相關的環境路徑
和 NDK r20b
相比,NDK r17c
的目錄稍微有些變化。
- 交叉編譯環境路徑
# 庫文件路徑
android-ndk-r17c/platforms/android-21/arch-arm/usr/lib
複製代碼
# 頭文件路徑
android-ndk-r17c/sysroot/usr/include
複製代碼
- GCC 工具鏈路徑
android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin
複製代碼
可以看到,Google 將 頭文件
和 庫文件
分離了,這也是很多新手在編譯的時候一直沒有配對路徑,導致編譯失敗的原因。
新建編譯配置腳本
FFmpeg 的版本依然是使用上面的 ffmpeg-4.2.2
, 當然,這次不需要修改 configure
了。
根據前面介紹的知識,很容易就能寫出編譯配置了
在 ffmpeg-4.2.2
根目錄新建腳本: build_android_gcc.sh
#!/bin/bash
set -x
API=21
CPU=armv7-a
#so庫輸出目錄
OUTPUT=/Users/cxp/Desktop/FFmpeg/ffmpeg-4.2.2/android/$CPU
# NDK的路徑,根據自己的安裝位置進行設置
NDK=/Users/cxp/Desktop/FFmpeg/android-ndk-r17c
# 庫文件
SYSROOT=$NDK/platforms/android-$API/arch-arm
# 頭文件
ISYSROOT=$NDK/sysroot/usr/include
# 彙編頭文件
ASM=$ISYSROOT/arm-linux-androideabi
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
function build
{
./configure \
--prefix=$OUTPUT \
--target-os=android \
--arch=arm \
--cpu=armv7-a \
--enable-asm \
--enable-cross-compile \
--enable-shared \
--disable-static \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-ffmpeg \
--sysroot=$SYSROOT \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--extra-cflags="-I$ISYSROOT -I$ASM -fPIC"
make clean all
# 這裏是定義用幾個CPU編譯
make -j12
make
make install
}
build
複製代碼
可以看到,在基本上配置和使用 CLANG
進行編譯差不多。
有以下不同:
- 多了
cc
配置。因爲如果不配置cc
默認爲clang
(參考前文的分析); - 多了
extra-cflags
的配置,因爲SYSROOT
中只包含了庫文件
,需要額外配置頭文件
的搜索路徑;彙編頭文件
的路徑也不在SYSROOT
中,也需要額外配置ASM
。
啓動編譯
打開 cmd 終端,cd 到 ffmpeg-4.2.2 目錄
執行 ./build_android_gcc.sh
六、總結
通過對 configure
的分析,可以讓我們更加清晰的理解每個參數配置項的意義,以及如何搭配使用這些配置。只要清楚了各個配置的含義,無論版本怎麼變化,都可很快的寫出編譯腳本。
當了,本文只是介紹了最基礎的配置方案,你還可以通過更多的 --disable-xxx
選項實現對 FFmpeg
的裁剪,或者通過 --enable-xxx
選項,開啓一些高級功能。