【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )
文章目錄
- I . 導入 z 庫 ( FFMPEG 動態庫 與 靜態庫區別 )
- II . FFMPEG 庫引入順序
- III . Android Studio 中 FFMPEG 靜態庫引入完整 CMakeList.txt 構建腳本
I . 導入 z 庫 ( FFMPEG 動態庫 與 靜態庫區別 )
1 . 導入 FFMPEG 靜態庫 會報以下錯誤 :
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 ) 導致的 ;
3 . 修改方法 : 在 CMakeList.txt 構建腳本中 , 鏈接庫時鏈接 z 庫 ; 在 target_link_libraries 中 , 添加 z 庫的鏈接 , 如下 :
4 . FFMPEG 靜態庫 : FFMPEG 使用靜態庫編譯需要增加額外配置 , 如上述的 libz.so 庫 ; 因為靜態庫在打包時就需要將所依賴的庫都打包到靜態庫中 ;
5 . FFMPEG 動態庫 : 如果使用的是 FFMPEG 動態庫 , 則不需要引入 z 庫 , 動態庫在運行時才鏈接其用到的函數庫 ;
II . FFMPEG 庫引入順序
1 . 問題產生 : Android Studio 中導入 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 導入順序 : FFMPEG 中的 6 個模塊 之間有相互依賴關系 , 必須按照指定的順序進行加載 ;
3 . 問題案例分析 : avcodec 模塊 ( 音視頻編解碼 ) 需要依賴 avformat 模塊 ( 音頻封裝格式 ) ; 因此 , 導入 FFMPEG 函數庫時 , avcodec 模塊 必須在 avformat 模塊之后 ;
4 . 推薦順序 : ① avfilter , ② avformat , ③ avcodec , ④ avutil , ⑤ swresample , ⑥ swscale ;
# FFMPEG 靜態庫# 注意這些庫的順序必須按照如下進行 , 否則會報錯# 這些庫之間有依賴的關系 , 必須按照順序加載庫 , 如 avcodec 內部依賴 avformat 庫avfilteravformatavcodecavutilswresampleswscaleIII . Android Studio 中 FFMPEG 靜態庫引入完整 CMakeList.txt 構建腳本
# I . 指定 CMake 最低版本 cmake_minimum_required(VERSION 3.4.1)# II . 設置函數庫編譯 add_library( # 參數 1 : 設置生成的動態庫名稱native-lib# 參數 2 : 設置生成的函數庫類型 : ① 靜態庫 STATIC ② 動態庫 SHAREDSHARED# 參數 3 : 配置要編譯的源文件native-lib.cppFFMPEG.cppJavaCallHelper.cppAudioChannel.cppVideoChannel.cpp)# III . 到預設的目錄查找 log 庫 , 將找到的路徑賦值給 log-lib # 這個路徑是 NDK 的 ndk-bundle\platforms\android-29\arch-arm\usr\lib\liblog.so # 不同的 Android 版本號 和 CPU 架構 需要到對應的目錄中查找 , 此處是 29 版本 32 位 ARM 架構的日志庫 # # 可以不配置 : # 可以不進行該配置, 直接在后面的 target_link_libraries 中鏈接 log 也不會出錯 find_library(log-liblog)# IV . 指定 FFMPEG 頭文件查找目錄 # CMAKE_SOURCE_DIR 指的是當前的文件地址 include_directories(${CMAKE_SOURCE_DIR}/include)# V . 指定 FFMPEG 靜態庫 # CMAKE_CXX_FLAGS 表示會將 C++ 的參數傳給編譯器 # CMAKE_C_FLAGS 表示會將 C 參數傳給編譯器# 參數設置 : 傳遞 CMAKE_CXX_FLAGS C+= 參數給編譯器時 , 在 該參數后面指定庫的路徑 # CMAKE_SOURCE_DIR 指的是當前的文件地址 # -L 參數指定動態庫的查找路徑 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/lib")# V . 鏈接函數庫 # 參數 1 : 本構建腳本要生成的動態庫目標 # 參數 2 ~ ... : 后面是之前預編譯的動態庫或靜態庫 , 或引入的動態庫 target_link_libraries(native-lib# FFMPEG 靜態庫# 注意這些庫的順序必須按照如下進行 , 否則會報錯# 這些庫之間有依賴的關系 , 必須按照順序加載庫 , 如 avcodec 內部依賴 avformat 庫avfilteravformatavcodecavutilswresampleswscale# 日志庫${log-lib}#FFMPEG 使用到了 libz 庫 , 沒有會報錯# FFMPEG 對于 z 的依賴是以動態庫的形式進行的# 如果 FFMPEG 是動態庫 , 那么可以不鏈接這個庫 , 可以運行時鏈接這個庫# 當前 FFMPEG 是靜態庫 , 需要在編譯時將這個庫打包到靜態庫中# 推薦使用靜態庫 , 靜態庫打包出來的庫比動態庫小很多 , 一倍左右z )
總結
以上是生活随笔為你收集整理的【Android FFMPEG 开发】Android Studio 中配置 FFMPEG 库注意事项 ( 静态库 链接 libz.so 库 | 导入 FFMPEG 函数库顺序 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android FFMPEG 开发】A
- 下一篇: 【Android FFMPEG 开发】C