FFMPEG в Android NDK — не удалось загрузить библиотеку libavfilter.so

Я пытаюсь использовать FFMPEG для обрезки видео с помощью Android NDK. Я могу успешно собрать ffmpeg, но у меня проблемы с libavfilter. Как только я включаю его в свои LOCAL_SHARED_LIBRARIES в Android.mk, я получаю эту ошибку UnsatisfiedLinkError:

java.lang.UnsatisfiedLinkError: dlopen failed: could not load library "libavfilter.so" needed by "videocrop.so"; caused by cannot locate symbol "avcodec_find_best_pix_fmt_of_2" referenced by "libavfilter.so"...
        at java.lang.Runtime.loadLibrary(Runtime.java:371)
        at java.lang.System.loadLibrary(System.java:989)

(Я пытаюсь загрузить свою библиотеку в статическом инициализаторе на стороне Java с помощью System.loadLibrary).

Функция «avcodec_find_best_pix_fmt_of_2» существует в libavcodec/avcodec.h, поэтому я не знаю, почему она не может найти ее. Файл libavfilter.so (равно как и все остальные библиотеки), похоже, собирается нормально и находится в папке libs/. Я пытался отредактировать конфигурацию и перестроить FFMPEG, а также попытался изменить LOCAL_C_INCLUDES в Android.mk, чтобы включить файлы заголовков libavcodec, но безуспешно.

Вот мой Android.mk для моего модуля:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := videocrop
LOCAL_CFLAGS :=
LOCAL_SRC_FILES := VideoCrop.c
    LOCAL_C_INCLUDES += $(LOCAL_PATH)/../ffmpeg/ffmpeg/$(TARGET_ARCH)/include/libavcodec/
    LOCAL_SHARED_LIBRARIES := libavformat libavutil libavcodec libavfilter

    LOCAL_LDLIBS := -llog
    LOCAL_LDFLAGS +=-ljnigraphics

    include $(BUILD_SHARED_LIBRARY)

А вот мой Android.mk для самих библиотек ffmpeg, хотя он довольно прост:

LOCAL_PATH := $(call my-dir)

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

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

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

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

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

LOCAL_PATH:= $(call my-dir)

Я в тупике. Если у кого-то есть идеи, это было бы очень признательно.


person gcgrant    schedule 16.01.2015    source источник
comment
запустите nm -D, чтобы убедиться, что avcodec_find_best_pix_fmt_of_2 является T в ffmpeg/$(TARGET_ARCH_ABI)/lib/libavcodec.so. Она может отсутствовать, даже если какой-то файл .h объявляет эту функцию.   -  person Alex Cohn    schedule 17.01.2015
comment
Я работаю на Mac, поэтому опции -D нет, но запуск nm на libavcodec.so (или любом из встроенных файлов .so) не дает результата.   -  person gcgrant    schedule 19.01.2015
comment
Вы должны использовать nm из соответствующей цепочки инструментов NDK, например. /usr/local/android-ndk-r10d/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm. И да, он поддерживает -D.   -  person Alex Cohn    schedule 19.01.2015
comment
У меня такая же проблема, и результат запуска nm такой (но как решить?): U av_find_best_pix_fmt_of_2 U av_frame_set_best_effort_timestamp 000fa7ac T avcodec_find_best_pix_fmt2 000fa7a8 T avcodec_find_best_pix_fmt_of_2 000fa7b0 T avcodec_find_best_pix_fmt_of_list   -  person QZHua    schedule 12.05.2016


Ответы (1)


Вам нужно загрузить библиотеки в обратном порядке зависимости, например. так:

System.loadLibrary("avutil");
System.loadLibrary("avcodec");
System.loadLibrary("avformat");
System.loadLibrary("swscale");
System.loadLibrary("avfilter");
System.loadLibrary("videocrop");

См., например. этот пост для получения более подробной информации: Загрузка общих библиотек, которые зависят от других общих библиотеки

person mstorsjo    schedule 16.01.2015
comment
К сожалению, это тоже не сработало. Это представляет ту же ошибку, за исключением строки, которая загружает avfilter вместо videocrop. - person gcgrant; 16.01.2015