【发布时间】:2013-12-03 01:33:08
【问题描述】:
我正在按照与halfninja's build 相同的模式构建ffmpeg:使ffmpeg 的main 通过JNI 从Java 中可用。我使用以下选项构建了 ffmpeg:
./configure \
--prefix=$PREFIX \
--disable-shared \
--enable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS"
$PREFIX, TOOLCHAIN, ... 被设置为我的 NDK 中的相应文件夹。 $ADDI_CFLAGS 设置为 -marm,$ADDI_LDFLAGS 和 $ADDITIONAL_CONFIGURE_FLAGS 均未设置。创建生成的静态库:
$ ls -1 android/arm/lib/ libavcodec.a libavdevice.a libavfilter.a libavformat.a libavutil.a libswresample.a libswscale.a pkgconfig
我用Android.mk 文件公开它们,ffmpeg 是在$NDK/sources/ffmpeg-2.1.1 中构建的:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavdevice
LOCAL_SRC_FILES:= lib/libavdevice.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavcodec
LOCAL_SRC_FILES:= lib/libavcodec.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavformat
LOCAL_SRC_FILES:= lib/libavformat.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libswscale
LOCAL_SRC_FILES:= lib/libswscale.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavutil
LOCAL_SRC_FILES:= lib/libavutil.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libavfilter
LOCAL_SRC_FILES:= lib/libavfilter.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= libwsresample
LOCAL_SRC_FILES:= lib/libswresample.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
所以,到目前为止,一切看起来都很好。现在,我尝试将ffmpeg 二进制等效项构建为静态库。我在我的jni 文件夹中复制了ffmpeg.c、ffmpeg.h、cmdutils.c、cmdutils.h、ffmpeg_opt.c 和ffmpeg_filter.c(现在没有更改单个字符)。我在这个文件夹中还有两个直接与 JNI 相关的文件(从 halfninja 的构建中复制,我只是更改了包名)。这是相关的Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := /Applications/android-ndk-r9b/sources/ffmpeg-2.1.1
LOCAL_CFLAGS := -Wdeprecated-declarations
LOCAL_MODULE := videokit
ANDROID_LIB := -landroid
LOCAL_LDLIBS += -llog -ljnigraphics -lz
LOCAL_SRC_FILES := videokit/com_rfc_video_ffmpeg_Videokit.c videokit/ffmpeg.c videokit/cmdutils.c videokit/ffmpeg_opt.c videokit/ffmpeg_filter.c
LOCAL_SHARED_LIBRARIES := libavdevice libavformat libavfilter libavcodec libwscale libavutil libswresample libswscale libpostproc
include $(BUILD_SHARED_LIBRARY)
$(call import-module,ffmpeg-2.1.1/android/arm)
一切都编译得很好,但没有链接。这是第一个错误:
[armeabi] SharedLibrary : libvideokit.so /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../.. /../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: 在函数 print_all_libs_info.constprop.5:jni/videokit/cmdutils.c:1063:错误:未定义对“swresample_version”的引用 /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../.. /../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: 在函数 print_all_libs_info.constprop.5:jni/videokit/cmdutils.c:1063:错误:未定义对“swresample_configuration”的引用 /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../.. /../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: 在函数 opt_default:jni/videokit/cmdutils.c:558: 错误: 未定义的参考到“swr_get_class” /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../.. /../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: 在函数 opt_default:jni/videokit/cmdutils.c:561: 错误: 未定义的参考到“swr_alloc” /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../.. /../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/cmdutils.o: 在函数 opt_default:jni/videokit/cmdutils.c:563: 错误: 未定义的参考到“swr_free” /Applications/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../.. /../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/videokit/videokit/ffmpeg_opt.o: 在函数 show_help_default:jni/videokit/ffmpeg_opt.c:2464:错误:未定义的参考到“swr_get_class”
我不明白的是这些函数是在libswresample.a 中定义和提供的,我正在链接到:
arm-linux-androideabi-nm /Applications/android-ndk-r9b/sources/ffmpeg-2.1.1/android/arm/lib/libswresample.a | grep -i -e swr_get_class -e swresample_version 000001d4 T swr_get_class 00000178 T swresample_version
我做错了什么?是否有另一种可能更简单的方法将 ffmpeg 公开为可通过 JNI 获得的静态库? (我不使用 halfninja,因为我至少需要 ffmpeg 1.1,而他的是 0.9)。
【问题讨论】:
标签: android c android-ndk ffmpeg