我有一个完全由 C/C++ 代码组成的 Android NDK 项目,它基本上处理图像而不使用任何外部库。
我正在使用 Android Studio + Gradle NDK 实验插件(0.7.0-alpha1)。
现在,我需要将 ffmpeg 集成为本机库,以便从 C/C++ 代码中使用它来解码 H.264 视频帧。
这些是我在这里找到的关于这个问题的问题:
Android - 集成 ffmpeg 和 android-ndk-r9c
带有 ffmpeg 库的 Android NDK - 运行项目时出错
无法使用 gradle-experimental 使用预构建的静态库构建
这是我的 build.gradle 文件:
apply plugin: 'com.android.model.application'
def ffmpeg_path = file(project(':ffmpeg').projectDir).absolutePath + "/ffmpeg-android"
model {
repositories {
libs(PrebuiltLibraries) {
libavcodec {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libavcodec.a")
}
}
libavutil {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libavutil.a")
}
}
libswresample {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libswresample.a")
}
}
libswscale {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libswscale.a")
}
}
libavformat {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libavformat.a")
}
}
libavdevice {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libavdevice.a")
}
}
libavfilter {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libavfilter.a")
}
}
libpostproc {
headers.srcDir "${ffmpeg_path}/include"
binaries.withType(StaticLibraryBinary) {
staticLibraryFile = file("${ffmpeg_path}/${targetPlatform.getName()}/lib/libpostproc.a")
}
}
}
}
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.example.hellojni"
minSdkVersion.apiLevel = 4
targetSdkVersion.apiLevel = 23
}
}
/*
* native build settings
*/
android.ndk {
moduleName = "hello-jni"
platformVersion = 9 //same as minSdkVersion.apiLevel for better compatibility
stl = "c++_static"
abiFilters.addAll(["armeabi", "armeabi-v7a", "x86"]) //filtering ABIs on the ones Google Play Games library is compatible with.
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-rules.txt'))
}
}
android.sources {
main {
jni {
dependencies {
library "libavcodec" linkage "static"
library "libavutil" linkage "static"
library "libswresample" linkage "static"
library "libswscale" linkage "static"
library "libavformat" linkage "static"
library "libavdevice" linkage "static"
library "libavfilter" linkage "static"
library "libpostproc" linkage "static"
}
}
}
}
}
我基于来自 Google 的这个示例,它集成了一个外部原生库。
这是我在导入之前编译的 ffmpeg 项目: https ://github.com/WritingMinds/ffmpeg-android
我已经添加了所有 .a 和 .h 文件,并且能够在我的 C/C++ 代码中导入头文件,但是当我尝试编译它时出现以下错误:
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function try_decode_frame: error: undefined reference to 'avpriv_h264_has_num_reorder_frames'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function compute_pkt_fields: error: undefined reference to 'avpriv_h264_has_num_reorder_frames'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function parse_packet: error: undefined reference to 'av_parser_parse2'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function parse_packet: error: undefined reference to 'av_parser_close'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function read_frame_internal: error: undefined reference to 'av_parser_init'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function avformat_find_stream_info: error: undefined reference to 'av_parser_init'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function avformat_find_stream_info: error: undefined reference to 'avcodec_pix_fmt_to_codec_tag'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function avformat_find_stream_info: error: undefined reference to 'avpriv_get_raw_pix_fmt_tags'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function ff_stream_add_bitstream_filter: error: undefined reference to 'av_bitstream_filter_init'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function ff_stream_add_bitstream_filter: error: undefined reference to 'av_bitstream_filter_close'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(utils.o):utils.c:function av_apply_bitstream_filters: error: undefined reference to 'av_bitstream_filter_filter'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(aadec.o):aadec.c:function aa_read_packet: error: undefined reference to 'av_tea_init'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(aadec.o):aadec.c:function aa_read_packet: error: undefined reference to 'av_tea_crypt'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(aadec.o):aadec.c:function aa_read_header: error: undefined reference to 'av_tea_alloc'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(aadec.o):aadec.c:function aa_read_header: error: undefined reference to 'av_tea_init'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(aadec.o):aadec.c:function aa_read_header: error: undefined reference to 'av_tea_crypt'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(ac3dec.o):ac3dec.c:function ac3_eac3_probe.isra.0: error: undefined reference to 'avpriv_ac3_parse_header'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(adtsenc.o):adtsenc.c:function adts_write_header: error: undefined reference to 'avpriv_mpeg4audio_get_config'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(adtsenc.o):adtsenc.c:function adts_write_header: error: undefined reference to 'avpriv_copy_pce_data'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(asfcrypt.o):asfcrypt.c:function ff_asfcrypt_dec: error: undefined reference to 'av_rc4_alloc'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(asfcrypt.o):asfcrypt.c:function ff_asfcrypt_dec: error: undefined reference to 'av_rc4_init'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(asfcrypt.o):asfcrypt.c:function ff_asfcrypt_dec: error: undefined reference to 'av_rc4_crypt'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(asfcrypt.o):asfcrypt.c:function ff_asfcrypt_dec: error: undefined reference to 'av_rc4_init'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(asfcrypt.o):asfcrypt.c:function ff_asfcrypt_dec: error: undefined reference to 'av_rc4_crypt'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(matroska.o):matroska.c:function ff_mkv_stereo3d_conv: error: undefined reference to 'av_stereo3d_alloc'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(nut.o):nut.c:function ff_nut_add_sp: error: undefined reference to 'av_tree_node_alloc'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(nut.o):nut.c:function ff_nut_add_sp: error: undefined reference to 'av_tree_insert'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(nut.o):nut.c:function ff_nut_free_sp: error: undefined reference to 'av_tree_enumerate'
/Users/marcos/Documents/Android/fdecoder/ffmpeg/ffmpeg-android/armeabi-v7a/lib/libavformat.a(nut.o):nut.c:function ff_nut_free_sp: error: undefined reference to 'av_tree_destroy'
Error:error: ld returned 1 exit status
Error:Execution failed for task ':app:linkHello-jniArmeabi-v7aDebugSharedLibrary'.
> A build operation failed.
Linker failed while linking libhello-jni.so.
See the complete log at: file:///Users/marcos/Documents/Android/fdecoder/app/build/tmp/linkHello-jniArmeabi-v7aDebugSharedLibrary/output.txt
Information:BUILD FAILED
Information:Total time: 14.993 secs
Information:2 errors
Information:0 warnings
Information:See complete output in console
显然有些东西我没有正确导入,但无法确切地确定缺少什么。