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 …
- ¿Android 4.x soporta streaming RTSP sobre TCP?
- Compilar ffmpeg con android ndk r5b
- Cómo construir ffmpeg en la aplicación android?
- Ffmpeg 10.04 no pudo encontrar parámetros de codec
- Captura de pantalla del Nexus One de adb?
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ónparse_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ónparse_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ónflush_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 aav_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 aav_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?
- FFMPEG para Android toolchains: brazo-linux-armeabi-eabi-pkg-config - hay algún toolchain que contenga la herramienta pkg-config
- Construyendo FFMPEG con librtmp para android
- GC y onTouch causan un error de señal fatal 11 (SIGSEGV) en la aplicación que utiliza ffmpeg a través de ndk
- Android: ExoPlayer - Obtener el número de fotograma actual del vídeo
- Concatenar archivos mp4 en Android usando halfninja ffmpeg
- Cómo instalar JavaCV en Android y utilizar FrameGrabber
- Cómo aumentar el rendimiento del dibujo de mapa de bits en Android
- Añadir animación diferente para diferentes fotogramas en vídeo con ffmpeg android
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
- Crash en dispositivos Samsung para EditText que contiene enlaces
- Pestaña con icono usando TabLayout en Android Design Library