10

私はffmpegのlibavcodec関数への未解決の参照に関する問題を抱えています、これまでのところ(私の心を含む)他の場所で答えを見つけることができませんでした:)

私の設定を説明させてください - それはスペースをとりますが、本当に基本的です、それは私がいくらかのエラーを見るのに失敗しているということかもしれません...

ndk r5 toolchain、ffmpeg portを使ってFFMPegを構築しました。http://bambuser.com/opensource(こちらの他の質問で推奨されているように)。それはうまく構築されたので、私はこのように私のプロジェクトにいくつかの静的ライブラリを入れました:

<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を作成して、これらのlibを事前作成済みのものとしてリストします。

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

走ったとき未構築、それはうまくコンパイルされますが、リンク時にそれのほとんどすべての関数への未解決の参照を表示します。libavcodec。このライブラリの関数だけが見つからないようです。

/home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(allformats.o):   機能中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):   機能中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):   機能中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):   機能中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:   未定義の参照av_free_packet' /home/dimka/src/mobile/android/ffmpegtest/obj/local/armeabi/libavformat.a(utils.o): In functionget_audio_frame_size ':   /home/dimka/work/suzy/tmp/ffmpeg-android/ffmpeg/libavformat/utils.c:766:   未定義の参照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:   `av_dup_packet 'への未定義の参照

等々...

なぜこれが起こっているのか理解できません。走ってみたndk-build V = 1実際のリンクコマンドを確認するlibavcodecそれがあるべきように、完全に正しくそこに座っています。他のすべてのffmpegライブラリもあります。

何かヒントは?


  • あなたのコードがオープンソースでリリースされる可能性はありますか?それとも、非常に基本的な構造(つまり、.soまたは.aファイルを置く場所、Androidアプリでそれを呼び出す方法)を提供することによって私を助けることができますか?私はあなたの最初の手順と以下の答えの両方を試しましたが、どちらもうまくいきませんでした。ヒントをありがとう! - slhck
  • @slhck多分私のAndroid.mkとzip圧縮されたディレクトリにあなたに電子メールを送ることができました、それはそこでそれほど複雑ではありません、gmail comでdimsuzに私を書いてください。別の方法として、私はあなたがここで特定の質問をすること、あなたの問題を説明することができると思います、多分誰かが解決策を見つけるでしょう:) - dimsuz

3 답변


2

私はAndroidの仕事にもffmpegを使っています。私は私の造りを少し別様にする。私はbambuser.comビルドからlib * .aファイルとインクルードディレクトリを取り出し、それらを直接jniディレクトリに直接インクルードします。私のAndroid.mkは次のようになります。

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)

そこにいくらかの巧妙さがあるかもしれません、しかし多分それは正しい方向にあなたを向けるのを助けるでしょう。私はあなたが持っているようなNDKのサンプルプロジェクトにレイアウトされたフォームのいくつかに従うことを試みました。ライブラリをモジュールにまとめて、それを参照します。しかし、物事をうまく機能させるためだけの単純な直接インクルードに頼ってしまうことになり、今のところそれを再検討する理由はありません。


  • それはうまくいきました、ありがとうございました! :) - dimsuz
  • 「NDKでは静的ライブラリの結合はサポートされていません」という不思議なフレーズもありますが、最終的に静的ライブラリは単なるオブジェクトファイルの集まりなので、コマンドで指定した場合行、それらは指定された順序ですべて一緒にリンクされるべきです。それは事実でした、しかし、それは何らかの理由でうまくいきませんでした。詳細がわからない場合もあります。 - dimsuz
  • ええと、今また別のこと。 /sdcard/myfile.mp4からファイルを開こうとすると、av_open_input_fileが-2(そのようなファイルまたはディレクトリはありません)を返します(確かに存在します、androidmanifest.xmlなどに権限があります)。あなたはたぶんそのような問題を抱えていましたか、解決策を知っていますか? :) - dimsuz
  • 実はそうです。 bambuser.comビルドのデフォルトを使用している場合、ファイルプロトコルは無効になっています。現在使用しているバージョンでは有効になっています。このファイルを「file」と呼びます。/sdcard/myfile.mp4'私のコードでは。 - mikerowehl
  • おお、ありがとう。ファイルプロトコルを有効にして再コンパイルしてから、もう一度やり直してください。あなたのヒントなしにこれを見つけるには多大な時間がかかると思います、ありがとう! :) - dimsuz

5

次のAndroid.mkは、ターゲットアーチの処理を含め、私のために機能します。 bambuser build.shを実行した結果は... / build / ffmpegから/ jni / lib / ffmpegにコピーされます。 OPのようにPREBUILT_STATIC_LIBRARYではなくPREBUILD_SHARED_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ではなく自分のパッケージ名を含めるように--soname-prefix引数を変更するようにbambuser build.shを変更する必要もありました。

        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"


  • ありがとうございました!あなたはそれがなんらかの効果を発揮することに成功しましたか? :)それをコンパイルした後、私は何もしない(上記の答えに対する私の最後のコメントを参照) - dimsuz
  • はい。ファイルが使用していたファイルプロトコルとコーデック/デマルチプレクサを有効にする必要がありました。 Bambuserの設定では、使用する2つのコーデックを除くすべてが無効になっています。 - Fasaxc
  • ああ。これが私の問題かもしれないと思う。 mp4コーデックを有効にしてmp4ファイルを開こうとしましたが、開くことができませんでした。私は多分もっとコーデックを有効にする必要があるかもしれないと思うようになったかもしれません:)特定のものだけまたはすべてを有効にしましたか? - dimsuz
  • 必要なものだけを有効にしました。あなたは264デマルチプレクサと264デコーダと一緒にファイルプロトコルを必要とするでしょう、そして試行錯誤によって他のものの多分2、3。 ./configure --helpを実行し、次に--list-xyzオプションを試して、使用可能なファイルを見つけます。 - Fasaxc
  • 私のパッケージ名はどれ?まだAndroidプロジェクトがありません。 ARM用にffmpegをコンパイルしたいだけです。 ubuntuでも問題ありませんが、Windowsでは次のようなエラーが表示されます。「不明なオプション」 - soname-prefix = / data / data / com.bambuser.broadcaster / lib /" - Dr.jacky

0

ffmpegをビルドするときは、次のようにandroid-14以下を使用する必要があります。

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

リンクされた質問


最近の質問