Android上的FFMpeg,未定义的对libavcodec函数的引用,尽管它在命令行中列出

dim*_*suz 10 android ffmpeg android-ndk

我对ffmpeg的libavcodec函数的未解析引用有问题,到目前为止在其他地方找不到答案(包括我的想法):)

让我来描述我的设置 - 它需要空间,但是非常基本,可能是我没有看到一些错误......

我使用ndk r5工具链构建了一个FFMPeg,我从http://bambuser.com/opensource获得了ffmpeg端口(在此处的其他问题中推荐).它构建得很好,所以我在我的项目中放了几个静态库,如下所示:

<project>/jni/bambuser_ffmpeg/libavcodec.a
<project>/jni/bambuser_ffmpeg/libavformat.a
<project>/jni/bambuser_ffmpeg/libavcore.a
<project>/jni/bambuser_ffmpeg/libavutil.a
Run Code Online (Sandbox Code Playgroud)

接下来,我在bambuser_ffmpeg文件夹中创建了一个Android.mk,将这些库列为预构建的库:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libavcore
LOCAL_SRC_FILES := libavcore.a
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := bambuser-libavformat
LOCAL_SRC_FILES := libavformat.a
include $(PREBUILT_STATIC_LIBRARY)

(same for other two libs)
Run Code Online (Sandbox Code Playgroud)

接下来,我有另一个模块在其Android.mk中引用这些库,设置包含路径等:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := ffmpegtest
LOCAL_STATIC_LIBRARIES := bambuser-libavcodec bambuser-libavcore bambuser-libavformat bambuser-libavutil
LOCAL_SRC_FILES := ffmpeg_test.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../bambuser_ffmpeg/include
LOCAL_LDLIBS    := -llog -lz

include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

最后我有我的ffmpeg_test.cpp这是非常基本的,像这样:

#include <jni.h>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}

extern "C" {
    JNIEXPORT jint JNICALL Java_com_the7art_ffmpegtest_PaintThread_testFFMpeg(JNIEnv* env, jobject obj, jstring fileName);
}

JNIEXPORT jint JNICALL Java_com_the7art_ffmpegtest_PaintThread_testFFMpeg(JNIEnv* env, jobject obj, jstring fileName)
{
    av_register_all();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行ndk-build时,它编译得很好,但是在链接时会打印出一个未解析的引用,几乎是libavcodec中的每个函数.看起来只有这个lib的功能无法找到:

/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(allformats.o):功能__CODE__avcodec_register_all'/ home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi /libavformat.a(utils.o):在函数av_parse_video_rate'/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/ __CODE__libavformat.a(utils.o)中:在函数__CODE__av_parse_video_size'/ home/dimka中/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(utils.o):在函数__CODE__av_free_packet'/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c :1283:对__CODE__get_audio_frame_size'的未定义引用 :/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:766:对__CODE__ff_interleave_add_packet'的未定义引用 :/ home/dimka/work/suzy/tmp /ffmpeg-android/ffmpeg/libavformat/utils.c:2909:对`av_dup_packet'的未定义引用

等等...

我不明白为什么会这样.我尝试运行ndk-build V = 1来检查实际的链接命令,并且libavcodec完全正确地坐在那里,就像它应该的那样.所有其他ffmpeg库也在那里.

任何提示?

Fas*_*axc 5

以下Android.mk适用于我,包括处理目标arch.运行bambuser build.sh的结果将从.../build/ffmpeg复制到/ jni/lib/ffmpeg.OP正在使用PREBUILD_SHARED_LIBRARY而不是PREBUILT_STATIC_LIBRARY.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := lib/ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavcore
LOCAL_SRC_FILES := lib/ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavdevice
LOCAL_SRC_FILES := lib/ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavfilter
LOCAL_SRC_FILES := lib/ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := lib/ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := lib/ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := lib/ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/include
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := mynativecode
LOCAL_SRC_FILES := native.c
LOCAL_SHARED_LIBRARIES := libavcore libavdevice libavfilter libavutil libswscale libavformat
LOCAL_LDLIBS := -L$(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm/usr/lib \
                -L$(LOCAL_PATH)/lib/ffmpeg/$(TARGET_ARCH_ABI)/lib \
                -lavcore \
                -lavformat \
                -lavcodec \
                -lavdevice \
                -lavfilter \
                -lavutil \
                -lswscale \
                -llog \
                -lz \
                -ldl \
                -lgcc

include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

我还必须更改bambuser build.sh来修改--soname-prefix参数以包含我的包名而不是bambusers.

        FLAGS="--target-os=linux --cross-prefix=arm-linux-androideabi- --arch=arm"
        FLAGS="$FLAGS --sysroot=$SYSROOT"
-       FLAGS="$FLAGS --soname-prefix=/data/data/com.bambuser.broadcaster/lib/"
+       FLAGS="$FLAGS --soname-prefix=/data/data/<my package name here>/lib/"
        FLAGS="$FLAGS --enable-shared --disable-symver"
        FLAGS="$FLAGS --enable-small --optimization-flags=-O2"
Run Code Online (Sandbox Code Playgroud)

  • 是.我必须启用文件协议和我的文件正在使用的编解码器/解复用器.Bambuser的配置禁用除了他们使用的几个编解码器之外的所有编解码器. (2认同)

mik*_*ehl 2

我也一直在使用 ffmpeg 进行一些 Android 工作。不过我的构建有点不同。我从 bambuser.com 构建中获取 lib*.a 文件和包含目录,然后直接将它们包含在我的 jni 目录中,我的 Android.mk 如下所示:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ndk1
LOCAL_SRC_FILES := native.c

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS := -L$(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-arm/usr/lib -L$(LOCAL_PATH) -lavformat -lavcodec -lavdevice -lavfilter -lavutil -lswscale -llog -ljnigraphics -lz -ldl -lgcc

include $(BUILD_SHARED_LIBRARY)
Run Code Online (Sandbox Code Playgroud)

其中可能存在一些问题,但也许它会帮助您指明正确的方向。我尝试遵循 NDK 示例项目中列出的一些表格,就像您一样。将库捆绑到一个模块中,然后引用它。但最终还是依靠简单的直接包含来让事情正常运转,到目前为止还没有理由重新审视它。