Поддержка FFmpeg для аппаратного декодирования libstagefright

Все: Я новичок в ffmpeg. Недавно я работаю над проектом для порта ffmpeg для устройства Android. В начале я скомпилировал ffmpeg для общих библиотек (.so-файлов) очень обычным способом, следуя некоторым руководствам в Интернете, загрузив их в свое приложение для Android. Он отлично работает.

Теперь я хочу, чтобы ffmpeg использовал libstagefright для выполнения декодирования HW. Проблема в том, что я могу скомпилировать .so libs, но когда я запускаю свое приложение и загружаю эти .so libs, всегда есть java.lang.UnsatisfiedLinkError: Не удается загрузить библиотеку: reloc_library [1314]: 114 не удается найти «_ZN7android11MediaBufferC1Ej»,

Я застрял там несколько дней. Кто-нибудь сталкивался с подобными проблемами раньше? Было бы здорово, если бы кто-нибудь мог дать мне некоторый намек на эту ошибку.

Мои шаги: 1. Скомпилируйте код ffmpeg-2.1.4 для .so общих библиотек. Для этого я использую скрипт build_libstagefright и делаю некоторые изменения, основанные на некоторых руководствах из Интернета.

#!/bin/bash #export NDK=/home/mingzhang/android/android-ndk-r9c export NDK=/home/mingzhang/android/android-ndk-r7 if [ "$NDK" = "" ]; then echo NDK variable not set, assuming ${HOME}/android-ndk export NDK=${HOME}/android-ndk fi echo "Fetching Android system headers" git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_frameworks_base.git ../android-source/frameworks/base git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_frameworks_av.git ../android-source/frameworks/av git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_frameworks_native.git ../android-source/frameworks/native git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_hardware_libhardware.git ../android-source/hardware/libhardware git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_system_core.git ../android-source/system/core echo "Fetching Android libraries for linking" # Libraries from any froyo/gingerbread device/emulator should work # fine, since the symbols used should be available on most of them. #if [ ! -d "../android-libs" ]; then # if [ ! -f "../update-cm-7.0.3-N1-signed.zip" ]; then # wget http://download.cyanogenmod.com/get/update-cm-7.0.3-N1-signed.zip -P../ # fi # unzip ../update-cm-7.0.3-N1-signed.zip system/lib/* -d../ # mv ../system/lib ../android-libs # rmdir ../system #fi SYSROOT=$NDK/platforms/android-9/arch-arm # Expand the prebuilt/* path into the correct one #TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64 TOOLCHAIN=/home/mingzhang/android/android-ndk-r7/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86 export PATH=$TOOLCHAIN/bin:$PATH ANDROID_SOURCE=../android-source ANDROID_LIBS=../android-libs ABI="armeabi-v7a" CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc #CC=$TOOLCHAIN/bin/arm-eabi-gcc-4.4.3 NM=$TOOLCHAIN/bin/arm-linux-androideabi-nm #NM=$TOOLCHAIN/bin/arm-eabi-nm rm -rf ../build/stagefright mkdir -p ../build/stagefright ADDI_CFLAGS="-marm" DEST=../build/stagefright DEST="$DEST/$ABI" FLAGS="--target-os=linux --arch=arm --cpu=armv7-a --cross-prefix=arm-linux-androideabi- --cc=$CC --nm=$NM" #FLAGS="--target-os=linux --arch=arm --cpu=armv7-a --cross-prefix=arm-eabi- --cc=$CC --nm=$NM" FLAGS="$FLAGS --sysroot=$SYSROOT" #FLAGS="$FLAGS --disable-avdevice --disable-decoder=h264 --disable-decoder=h264_vdpau --enable-libstagefright-h264" FLAGS="$FLAGS --enable-shared --disable-demuxers --disable-muxers --disable-parsers --disable-avdevice --disable-filters --disable-programs --disable-encoders --disable-decoders --disable-decoder=h264 --disable-decoder=h264_vdpau --enable-decoder=libstagefright_h264 --enable-libstagefright-h264 \ --enable-asm \ --enable-neon \ --enable-cross-compile \ --enable-gpl \ --disable-static \ --enable-memalign-hack" EXTRA_CFLAGS="-I$DEST/include" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/native/include" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/native/include/media/openmax" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/av/include" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/include -I$ANDROID_SOURCE/system/core/include" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/hardware/libhardware/include" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/media/libstagefright" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/include/media/stagefright/openmax" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$NDK/sources/cxx-stl/gnu-libstdc++/4.6/include -I$NDK/sources/cxx-stl/gnu-libstdc++/4.6/libs/$ABI/include" EXTRA_CFLAGS="$EXTRA_CFLAGS -I$NDK/sources/cxx-stl/stlport/stlport" EXTRA_CFLAGS="$EXTRA_CFLAGS -march=armv7-a -mfloat-abi=softfp -mfpu=neon -marm -mtune=cortex-a8" EXTRA_CFLAGS="$EXTRA_CFLAGS -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -D_STLP_USE_NEWALLOC" EXTRA_LDFLAGS="-Wl,--fix-cortex-a8 -L$ANDROID_LIBS -Wl,-rpath-link,$ANDROID_LIBS -L$NDK/sources/cxx-stl/gnu-libstdc++/4.6/libs/$ABI -static-libstdc++" EXTRA_CXXFLAGS="-Wno-multichar -fno-exceptions -fno-rtti" FLAGS="$FLAGS --prefix=$DEST" mkdir -p $DEST echo $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" > $DEST/info.txt ./configure $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" | tee $DEST/configuration.txt [ $PIPESTATUS == 0 ] || exit 1 make clean #make -j4 || exit 1 #make -j4 make install || exit 1 
  1. Скопируйте скомпилированные каталоги include и lib в каталог android-ndk-r7 / sources / ffmpeg-2.1.4 / android / arm. Файл Android.mk в этом каталоге.

    LOCAL_PATH: = $ (вызов my-dir)

    Включают $ (CLEAR_VARS) LOCAL_MODULE: = libavcodec LOCAL_SRC_FILES: = lib / libavcodec-55.so LOCAL_EXPORT_C_INCLUDES: = $ (LOCAL_PATH) / include включают $ (PREBUILT_SHARED_LIBRARY)

    Include $ (CLEAR_VARS) LOCAL_MODULE: = libavformat LOCAL_SRC_FILES: = lib / libavformat-55.so LOCAL_EXPORT_C_INCLUDES: = $ (LOCAL_PATH) / include включает $ (PREBUILT_SHARED_LIBRARY)

    Include $ (CLEAR_VARS) LOCAL_MODULE: = libswscale LOCAL_SRC_FILES: = lib / libswscale-2.so LOCAL_EXPORT_C_INCLUDES: = $ (LOCAL_PATH) / include включает $ (PREBUILT_SHARED_LIBRARY)

    Include $ (CLEAR_VARS) LOCAL_MODULE: = libavutil LOCAL_SRC_FILES: = lib / libavutil-52.so LOCAL_EXPORT_C_INCLUDES: = $ (LOCAL_PATH) / include включает $ (PREBUILT_SHARED_LIBRARY)

    Include $ (CLEAR_VARS) LOCAL_MODULE: = libavfilter LOCAL_SRC_FILES: = lib / libavfilter-3.so LOCAL_EXPORT_C_INCLUDES: = $ (LOCAL_PATH) / include включает $ (PREBUILT_SHARED_LIBRARY)

    Include $ (CLEAR_VARS) LOCAL_MODULE: = libwsresample LOCAL_SRC_FILES: = lib / libswresample-0.so LOCAL_EXPORT_C_INCLUDES: = $ (LOCAL_PATH) / include включает $ (PREBUILT_SHARED_LIBRARY)

  2. В jni-каталоге моего приложения для Android Android.mk есть.

     LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libripple #LOCAL_CFLAGS := -Werror LOCAL_SRC_FILES := entrypoint.cpp scene.cpp LOCAL_LDLIBS := -llog -lGLESv2 -lm include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := myfflib LOCAL_SRC_FILES := fflib.c LOCAL_LDLIBS := -L/home/mingzhang/ffmpeg_android/android-libs -llog -ljnigraphics -lz -landroid -ldl -lm -llog -lgcc -lc -lstagefright -lmedia -lutils -lbinder #-lstdc++ LOCAL_SHARED_LIBRARIES := libavformat libavcodec libswscale libavutil libutils libstagefright libbinder libmedia libstdc++-6 include $(BUILD_SHARED_LIBRARY) $(call import-module,ffmpeg-2.1.4/android/arm) 

    И Application.mk:

     APP_ABI=armeabi-v7a #APP_STL=gnustl_static APP_STL=stlport_static 

Я не уверен, какие еще материалы вам нужны, если что-то не хватает, сообщите мне, я загружу его. Спасибо вам, ребята!

FFmpeg удалил поддержку libstagefright по адресу https://github.com/FFmpeg/FFmpeg/commit/72673ad7eae2d4f685f3c0a895558502bfe07c8e (включен в n3.0 ). Сообщение о фиксации:

 avcodec: Remove libstagefright It serves absolutely no purpose other than to confuse potentional Android developers about how to use hardware acceleration properly on the the platform. The stagefright "API" is not public, and the MediaCodec API is the proper way to do this. Furthermore, stagefright support in avcodec needs a series of magic incantations and version-specific stuff, such that using it actually provides downsides compared just using the actual Android frameworks properly, in that it is a lot more work and confusion to get it even running. It also leads to a lot of misinformation, like these sorts of comments (in [1]) that are absolutely incorrect. [1] http://stackoverflow.com/a/29362353/3115956 

Так что, возможно, это невозможно.

У вас могут быть лучшие шансы с AMediaCodec и OpenMAX .