【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
文章目錄
- I . 導(dǎo)入 z 庫 ( FFMPEG 動態(tài)庫 與 靜態(tài)庫區(qū)別 )
- II . FFMPEG 庫引入順序
- III . Android Studio 中 FFMPEG 靜態(tài)庫引入完整 CMakeList.txt 構(gòu)建腳本
I . 導(dǎo)入 z 庫 ( FFMPEG 動態(tài)庫 與 靜態(tài)庫區(qū)別 )
1 . 導(dǎo)入 FFMPEG 靜態(tài)庫 會報以下錯誤 :
libavformat/id3v2.c:1021: error: undefined reference to 'uncompress'libavformat/rtmpproto.c:1077: error: undefined reference to 'inflateInit_'libavformat/rtmpproto.c:1087: error: undefined reference to 'inflate'libavformat/rtmpproto.c:1105: error: undefined reference to 'inflateEnd'libavformat/http.c:1646: error: undefined reference to 'inflateEnd'libavformat/http.c:680: error: undefined reference to 'inflateEnd'libavformat/http.c:681: error: undefined reference to 'inflateInit2_'libavformat/http.c:686: error: undefined reference to 'zlibCompileFlags'libavformat/http.c:1437: error: undefined reference to 'inflate'libavformat/matroskadec.c:1402: error: undefined reference to 'inflateInit_'libavformat/matroskadec.c:1410: error: undefined reference to 'inflateEnd'libavformat/matroskadec.c:1417: error: undefined reference to 'inflate'libavformat/mov.c:5073: error: undefined reference to 'uncompress'libavformat/swfdec.c:364: error: undefined reference to 'uncompress'libavformat/swfdec.c:153: error: undefined reference to 'inflateInit_'libavformat/swfdec.c:121: error: undefined reference to 'inflate'libavcodec/cscd.c:93: error: undefined reference to 'uncompress'libavcodec/flashsv.c:126: error: undefined reference to 'inflateInit_'libavcodec/flashsv.c:259: error: undefined reference to 'deflateInit_'libavcodec/flashsv.c:261: error: undefined reference to 'deflateBound'libavcodec/flashsv.c:262: error: undefined reference to 'deflateEnd'libavcodec/flashsv.c:191: error: undefined reference to 'inflateReset'libavcodec/flashsv.c:210: error: undefined reference to 'inflateSync'libavcodec/flashsv.c:160: error: undefined reference to 'deflateInit_'libavcodec/flashsv.c:166: error: undefined reference to 'deflate'libavcodec/flashsv.c:167: error: undefined reference to 'deflateEnd'libavcodec/flashsv.c:169: error: undefined reference to 'inflateReset'libavcodec/lcldec.c:134: error: undefined reference to 'inflateReset'libavcodec/mscc.c:141: error: undefined reference to 'inflateReset'clang++: error: linker command failed with exit code 1 (use -v to see invocation)ninja: build stopped: subcommand failed.2 . 問題原因 : 這是由于沒有找到 z 庫 ( libz.so ) 導(dǎo)致的 ;
3 . 修改方法 : 在 CMakeList.txt 構(gòu)建腳本中 , 鏈接庫時鏈接 z 庫 ; 在 target_link_libraries 中 , 添加 z 庫的鏈接 , 如下 :
4 . FFMPEG 靜態(tài)庫 : FFMPEG 使用靜態(tài)庫編譯需要增加額外配置 , 如上述的 libz.so 庫 ; 因為靜態(tài)庫在打包時就需要將所依賴的庫都打包到靜態(tài)庫中 ;
5 . FFMPEG 動態(tài)庫 : 如果使用的是 FFMPEG 動態(tài)庫 , 則不需要引入 z 庫 , 動態(tài)庫在運行時才鏈接其用到的函數(shù)庫 ;
II . FFMPEG 庫引入順序
1 . 問題產(chǎn)生 : Android Studio 中導(dǎo)入 FFMPEG 庫后 , 編譯時報如下錯誤 ;
libavformat/utils.c:5548: error: undefined reference to 'av_bitstream_filter_filter'libavformat/codec2.c:74: error: undefined reference to 'avpriv_codec2_mode_bit_rate'libavformat/codec2.c:75: error: undefined reference to 'avpriv_codec2_mode_frame_size'libavformat/codec2.c:76: error: undefined reference to 'avpriv_codec2_mode_block_align'libavformat/spdifdec.c:63: error: undefined reference to 'av_adts_header_parse'clang++: error: linker command failed with exit code 1 (use -v to see invocation)ninja: build stopped: subcommand failed.2 . FFMPEG 導(dǎo)入順序 : FFMPEG 中的 6 個模塊 之間有相互依賴關(guān)系 , 必須按照指定的順序進(jìn)行加載 ;
3 . 問題案例分析 : avcodec 模塊 ( 音視頻編解碼 ) 需要依賴 avformat 模塊 ( 音頻封裝格式 ) ; 因此 , 導(dǎo)入 FFMPEG 函數(shù)庫時 , avcodec 模塊 必須在 avformat 模塊之后 ;
4 . 推薦順序 : ① avfilter , ② avformat , ③ avcodec , ④ avutil , ⑤ swresample , ⑥ swscale ;
# FFMPEG 靜態(tài)庫# 注意這些庫的順序必須按照如下進(jìn)行 , 否則會報錯# 這些庫之間有依賴的關(guān)系 , 必須按照順序加載庫 , 如 avcodec 內(nèi)部依賴 avformat 庫avfilteravformatavcodecavutilswresampleswscaleIII . Android Studio 中 FFMPEG 靜態(tài)庫引入完整 CMakeList.txt 構(gòu)建腳本
# I . 指定 CMake 最低版本 cmake_minimum_required(VERSION 3.4.1)# II . 設(shè)置函數(shù)庫編譯 add_library( # 參數(shù) 1 : 設(shè)置生成的動態(tài)庫名稱native-lib# 參數(shù) 2 : 設(shè)置生成的函數(shù)庫類型 : ① 靜態(tài)庫 STATIC ② 動態(tài)庫 SHAREDSHARED# 參數(shù) 3 : 配置要編譯的源文件native-lib.cppFFMPEG.cppJavaCallHelper.cppAudioChannel.cppVideoChannel.cpp)# III . 到預(yù)設(shè)的目錄查找 log 庫 , 將找到的路徑賦值給 log-lib # 這個路徑是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so # 不同的 Android 版本號 和 CPU 架構(gòu) 需要到對應(yīng)的目錄中查找 , 此處是 29 版本 32 位 ARM 架構(gòu)的日志庫 # # 可以不配置 : # 可以不進(jìn)行該配置, 直接在后面的 target_link_libraries 中鏈接 log 也不會出錯 find_library(log-liblog)# IV . 指定 FFMPEG 頭文件查找目錄 # CMAKE_SOURCE_DIR 指的是當(dāng)前的文件地址 include_directories(${CMAKE_SOURCE_DIR}/include)# V . 指定 FFMPEG 靜態(tài)庫 # CMAKE_CXX_FLAGS 表示會將 C++ 的參數(shù)傳給編譯器 # CMAKE_C_FLAGS 表示會將 C 參數(shù)傳給編譯器# 參數(shù)設(shè)置 : 傳遞 CMAKE_CXX_FLAGS C+= 參數(shù)給編譯器時 , 在 該參數(shù)后面指定庫的路徑 # CMAKE_SOURCE_DIR 指的是當(dāng)前的文件地址 # -L 參數(shù)指定動態(tài)庫的查找路徑 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/lib")# V . 鏈接函數(shù)庫 # 參數(shù) 1 : 本構(gòu)建腳本要生成的動態(tài)庫目標(biāo) # 參數(shù) 2 ~ ... : 后面是之前預(yù)編譯的動態(tài)庫或靜態(tài)庫 , 或引入的動態(tài)庫 target_link_libraries(native-lib# FFMPEG 靜態(tài)庫# 注意這些庫的順序必須按照如下進(jìn)行 , 否則會報錯# 這些庫之間有依賴的關(guān)系 , 必須按照順序加載庫 , 如 avcodec 內(nèi)部依賴 avformat 庫avfilteravformatavcodecavutilswresampleswscale# 日志庫${log-lib}#FFMPEG 使用到了 libz 庫 , 沒有會報錯# FFMPEG 對于 z 的依賴是以動態(tài)庫的形式進(jìn)行的# 如果 FFMPEG 是動態(tài)庫 , 那么可以不鏈接這個庫 , 可以運行時鏈接這個庫# 當(dāng)前 FFMPEG 是靜態(tài)庫 , 需要在編譯時將這個庫打包到靜態(tài)庫中# 推薦使用靜態(tài)庫 , 靜態(tài)庫打包出來的庫比動態(tài)庫小很多 , 一倍左右z )
總結(jié)
以上是生活随笔為你收集整理的【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android FFMPEG 开发】A
- 下一篇: 【Android FFMPEG 开发】F