錯誤信息如下:
libavformat/hls.c:881: error: undefined reference to 'atof'
libavformat/hlsenc.c:1233: error: undefined reference to 'atof'
libavformat/http.c:1758: error: undefined reference to 'inflateEnd'
libavformat/http.c:773: error: undefined reference to 'inflateEnd'
libavformat/http.c:774: error: undefined reference to 'inflateInit2_'
libavformat/http.c:779: error: undefined reference to 'zlibCompileFlags'
libavformat/http.c:1535: error: undefined reference to 'inflate'
libavformat/id3v2.c:1031: error: undefined reference to 'uncompress'
libavformat/img2dec.c:266: error: undefined reference to 'glob'
...
造成這種問題的原因有三個:
-
有可能是在編譯 FFmpeg 庫時 Android API 版本太高導致,具體出錯原因可以參考原文解釋:
Google have moved some of the C standard library functions like atof() from being inline functions in header files to normal functions. The latest NDKs will default to building a .so that is only compatible with the latest Android devices that have the atof() function in the device’s standard C library (libc.so). This means if you run a library on an older device that has an older version of the C library, you will get an error loading the dll as the expected atof() function will not exist.
解決方案: 將 FFmpeg 編譯腳本 Android API 版本改為 17 ,重新編譯
FFmpeg 庫的依賴順序錯誤,導致定義的符號找不到,造成編譯錯誤。
簡單說一下編譯鏈接工作原理:
鏈接器從左往右掃描目標文件和靜態庫
掃描發現未解析的符號會先記住這個未解析的符號
當掃描到后面的靜態庫時,找到了前面未解析的符號,會提取相關代碼
-
最終沒有任何未解析的符號,編譯鏈接工作完成
既然知道工作原理了,只需要把依賴順序寫對就好:
avfilter avformat avcodec avutil swresample swscale
- 因為是引入靜態庫,FFmpeg 需要依賴 zlib 庫,所以在鏈接 FFmpeg 靜態庫時,需要加入 zlib 庫
target_link_libraries(...
avfilter avformat avcodec avutil swresample swscale
z)