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

标签 android ffmpeg android-ndk

我有一个 Unresolved 对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

接下来,我在 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)

接下来,我有另一个模块在其 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)

最后我得到了我的 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;
}

当我运行 ndk-build 时,它编译得很好,但在链接时它打印出对 libavcodec 中几乎每个函数的未解析引用。看起来只有这个库的函数无法定位:

/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(allformats.o): In function `av_register_all':
/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/allformats.c:47: undefined reference to `avcodec_register_all'
/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(utils.o): In function `parse_frame_rate':
/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:3240: undefined reference to `av_parse_video_rate'
/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(utils.o): In function `parse_image_size':
/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:3234: undefined reference to `av_parse_video_size'
/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(utils.o): In function `flush_packet_queue':
/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:1277: undefined reference to `av_free_packet'
/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:1283: undefined reference to `av_free_packet'
/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(utils.o): In function `get_audio_frame_size':
/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:766: undefined reference to `av_get_bits_per_sample'
/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(utils.o): In function `ff_interleave_add_packet':
/home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:2909: undefined reference to `av_dup_packet'
and so on...

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

有什么提示吗?

最佳答案

以下 Android.mk 适合我,包括处理目标架构。运行 bambuser build.sh 的结果从 .../build/ffmpeg 复制到/jni/lib/ffmpeg。我正在使用 PREBUILD_SHARED_LIBRARY 而不是 OP 所做的 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)

我还必须更改 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"

关于android - Android 上的 FFMpeg,未定义对 libavcodec 函数的引用,尽管它在命令行中列出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5337833/

相关文章:

android - 使用 OpenSL 的所有安卓设备以 8KHz 采样率进行语音通信

android - 如何在垂直居中显示自定义对话框

java - 安装错误: INSTALL_FAILED_OLDER_SDK in eclipse

具有与 FFmpeg 相同功能的音频重采样 C# 库

linux - 转换 MP4 版本 - FFmpeg

java - 从 C 到 Java 的类型转换

android - ftello 函数未声明

android - ActionBarCompat : java. lang.IllegalStateException : You need to use a Theme. AppCompat

android - SPen 将图像转换为文本

c++ - DXGI 桌面重复 : encoding frames to send them over the network