错误信息如下:
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)