使用ffmpeg 2.1.1 for Android时未定义的引用

时间:2013-12-02 15:21:57

标签: android c android-ndk ffmpeg

我正在按照与halfninja's build相同的模式构建ffmpeg:通过JNI从Java获取ffmpeg的main。我使用以下选项构建了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"

$PREFIXTOOLCHAIN,...设置为我的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二进制等价物构建为静态库。我复制了(暂时没有更改过一个字符)ffmpeg.cffmpeg.hcmdutils.ccmdutils.hffmpeg_opt.cffmpeg_filter.c in我的jni文件夹。我在这个文件夹中也有两个直接与JNI相关的文件(从halfninja的build中复制,我刚刚更改了包名)。这是相关的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: in function print_all_libs_info.constprop.5:jni/videokit/cmdutils.c:1063: error: undefined reference to '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: in function print_all_libs_info.constprop.5:jni/videokit/cmdutils.c:1063: error: undefined reference to '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: in function opt_default:jni/videokit/cmdutils.c:558: error: undefined reference to '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: in function opt_default:jni/videokit/cmdutils.c:561: error: undefined reference to '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: in function opt_default:jni/videokit/cmdutils.c:563: error: undefined reference to '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: in function show_help_default:jni/videokit/ffmpeg_opt.c:2464: error: undefined reference to '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)。

1 个答案:

答案 0 :(得分:2)

你的名字有点混乱:在一个地方,你把它称为libwsresample,在其他地方libswresample

检查所有名称的一致性。