FFMpeg en Android, referencias indefinidas a las funciones de libavcodec, aunque aparece en la línea de comandos

Tengo un problema con las referencias no resueltas a las funciones libavcodec de ffmpeg, hasta ahora no encontré la respuesta en otros lugares (incluyendo mi mente) 🙂

Permítanme describir mi configuración – se necesita espacio, pero es realmente básico, puede ser que estoy fallando a ver algún error …

Construí un FFMPeg con ndk r5 toolchain, puerto ffmpeg que obtuve de http://bambuser.com/opensource (como se recomienda en otras preguntas aquí). Se construyó bien, por lo que poner varias bibliotecas estáticas en mi proyecto como este:

<project>/jni/bambuser_ffmpeg/libavcodec.a <project>/jni/bambuser_ffmpeg/libavformat.a <project>/jni/bambuser_ffmpeg/libavcore.a <project>/jni/bambuser_ffmpeg/libavutil.a 

A continuación, creé una aplicación Android.mk en la carpeta bambuser_ffmpeg para listar estas librerías como las pre-construidas:

 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) 

A continuación, tengo otro módulo que hace referencia a estas libs en su Android.mk, configura rutas de inclusión, etc:

 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) 

Y finalmente tengo mi ffmpeg_test.cpp que es realmente básico, así:

 #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; } 

Cuando ejecuto ndk-build , compila bien, pero al vincularlo imprime una referencia no resuelta a casi todas las funciones de libavcodec . Parece que sólo las funciones de este lib no están localizadas:

/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(allformats.o): En la función 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): En la función 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): En la función 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): En función flush_packet_queue': /home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:1277: undefined reference to Av_free_packet '/ inicio / dimka / trabajo / suzy / tmp / ffmpeg-android / ffmpeg / libavformat / uti Ls.c: 1283: referencia indefinida a 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: referencia no definida a 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: referencia no definida a `av_dup_packet'

y así…

No entiendo por qué sucede esto. Traté de ejecutar ndk-build V = 1 para comprobar el comando de enlace real, y libavcodec está sentado allí perfectamente bien, como debería. Todas las demás libs ffmpeg están allí también.

¿Algún consejo?

He estado usando ffmpeg para algunos trabajos de Android también. Hago mi construcción un poco diferente. Tomo los archivos lib * .a y el directorio include de la compilación bambuser.com y solo los incluyo directamente en mi directorio jni, mi Android.mk se ve así:

 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) 

Podría haber algún cruft allí, pero tal vez le ayudará a señalar en la dirección correcta. He intentado seguir algunas de las formas establecidas en los proyectos de ejemplo NDK como usted. Agrupando las bibliotecas en un módulo y haciendo referencia a eso. Pero terminó cayendo hacia atrás en la simple directa incluyen sólo para hacer las cosas funcionando, y hasta ahora no han tenido motivos para volver a visitarlo.

El siguiente Android.mk funciona para mí, incluyendo el manejo del arco de destino. El resultado de ejecutar el bambuser build.sh se copia desde … / build / ffmpeg a / jni / lib / ffmpeg. Estoy usando PREBUILD_SHARED_LIBRARY en lugar de PREBUILT_STATIC_LIBRARY como lo hizo el OP.

 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) 

También tuve que cambiar el bambuser build.sh para modificar el argumento –soname-prefix para incluir mi nombre de paquete en lugar de 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" 

Cuando usted construye ffmpeg debe usar android-14 o inferior, como esto:

 export NDK=/Users/luoye/Downloads/android-ndk-r11c export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt export PLATFORM=$NDK/platforms/android-8/arch-arm export PREFIX=../simplefflib build_one(){ ./configure --target-os=linux --prefix=$PREFIX \ --enable-cross-compile \ --enable-runtime-cpudetect \ --disable-asm \ --arch=arm \ --cc=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-gcc \ --cross-prefix=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi- \ --disable-stripping \ --nm=$PREBUILT/darwin-x86_64/bin/arm-linux-androideabi-nm \ --sysroot=$PLATFORM \ --enable-gpl --enable-shared --disable-static --enable-small \ --disable-ffprobe --disable-ffplay --disable-ffmpeg --disable-ffserver --disable-debug \ --extra-cflags="-fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors - Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a" } build_one make make install 
  • Documentación sobre el proyecto Guardian ffmpeg android
  • ffmpeg para un android (usando el tutorial: "ffmpeg y Android.mk")
  • Ffmpeg con un conjunto de archivos de imagen no formateado como% d.jpg
  • Decodificación AAC en FFmpeg para Android
  • Ffmpeg Build ¿La salida no está demostrando?
  • Android NDK. Cómo reproducir video.
  • Recepción de flujo de vídeo desde una cámara IP en android
  • Cómo transmitir a ffserver desde android
  • Compilación ffmpeg neón en android - errores de ensamblador
  • Android: ¿Cómo configurar la última versión de FFMPEG en android studio?
  • Android.mk LOCAL_MODULE_FILENAME no debe contener extensiones
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.