我使用NDK v15.2编译了ffmpeg v3.4,我正在创建一个名为ffmpeg-jni的包装器库。
static {
try {
System.loadLibrary("avutil");
System.loadLibrary("avcodec");
System.loadLibrary("avformat");
System.loadLibrary("swscale");
System.loadLibrary("avfilter");
System.loadLibrary("ffmpeg-jni"); // Exception here line#101
loadedLibraries = true;
} catch (Throwable e) {
e.printStackTrace();
}
}
下面是加载我的包装器库时抛出的异常。
10-24 11:12:13.819 21499-21499/com.myeglu.android.canary.staging W/System.err: java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "av_register_all" referenced by "/data/app/com.myeglu.android.canary.staging-2/lib/arm/libffmpeg-jni.so"...
但令我惊讶的是,这个函数是在libavformat.so中定义的,它已成功加载;从nm tool output可以清楚地看出,libavformat.so中定义了av_register_all()函数(T)
这是所有预先构建的库的链接,这些库在运行时很难实现和平。 (除了ffmpeg库之外还有一些其他库)
https://drive.google.com/drive/folders/0B20ExoMyOP_UeDhNdmwzc2tjR3M?usp=sharing
有人帮助我理解在这种情况下我可能会遗漏的内容。谢谢你的时间。
答案 0 :(得分:1)
首先,您应该以正确的顺序明确列出所有需要的库,或者让系统解析依赖关系(如果您的平台至少是Lollipop)。
具体来说, libavcodec 需要 libswresample 。
但 ffmpeg-jni 似乎无法正确构建。其动态部分仅列出
0x00000001 (NEEDED) Shared library: [libandroid.so]
0x00000001 (NEEDED) Shared library: [libjnigraphics.so]
0x00000001 (NEEDED) Shared library: [libavcodec.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libc.so]
此外, .dynsym 表包含
5: 00000000 0 NOTYPE GLOBAL DEFAULT UND av_register_all
我希望相反,
5: 00000000 0 FUNC GLOBAL DEFAULT UND av_register_all@LIBAVFORMAT_57 (4)
请注意 avcodec_find_decoder 的符号类型以及来自库中 libavcodec.so 的其他引用是正确的。
您是否已将{{1>}用于 libffmpeg-jni.so ?
更新:实际上,cmake使用Android工具链编写的LOCAL_ALLOW_UNDEFINED_SYMBOLS=true
将CMAKE_SHARED_LINKER_FLAGS
传递给链接器;通过覆盖此变量,您实际上允许未定义的符号(并丢失了一些针对Android调整的其他重要标志)。最重要的是,重写CMAKE标准变量是危险的。