10

나는 ffmpeg의 libavcodec 함수에 대한 미해결 참조에 대한 문제가 있으며, 지금까지는 (내 마음을 포함하여) 다른 장소에서 대답을 찾지 못했습니다. :)

제가 설치 프로그램을 설명하겠습니다. 공간이 필요하지만 실제로는 기본입니다. 오류가 발생하지 않을 수도 있습니다 ...

ndk r5 toolchain, ffmpeg 포트가있는 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를 작성하여이 라이브러리를 미리 빌드 된 것으로 나열합니다.

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에서 이러한 libs를 참조하는 다른 모듈을 포함하고 경로 등을 설정합니다.

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. 이 lib 함수 만 찾지 못하는 것처럼 보입니다.

/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 어쩌면 나는 안드로이드의 이메일을 보낼 수 있었을 것이다. 아주 복잡하지는 않았지만 gmail.com에서 나를 쓰라. 대안으로 나는 당신이 여기에 특정 질문을 할 수있을 것 같아요, 당신의 문제를 설명, 어쩌면 누군가가 해결책을 찾을 수 :) - dimsuz

3 답변


2

나도 안드로이드 작업을 위해 ffmpeg를 사용 해왔다. 나는 약간 다른 생각을하지만. lib * .a 파일과 bambuser.com 빌드의 include dir을 가져 와서 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 예제 프로젝트에 배치 된 양식 중 일부를 따르려고했다. libs를 모듈로 번들링 한 다음 참조하십시오. 그러나 간단하게 직접적으로 돌아가는 일은 단지 일을하기위한 것이었고, 지금까지는 그것을 다시 방문 할 이유가 없었습니다.


  • 그건 잘 됐네, 고마워! :) - dimsuz
  • 또한 "NDK는 정적 라이브러리 결합을 지원하지 않습니다."라는 미스터리 문구를 발견했습니다. 그러나 의미는 확실하지 않습니다. 결국 정적 라이브러리는 객체 파일의 모음이므로, 명령에서 지정하면 지정된 순서대로 모두 연결해야합니다. 그랬지만 어떤 이유로 든 작동하지 않았습니다. 아마 약간의 세부 사항을 모르겠다. :) - dimsuz
  • 어, 이제 또 하나. av_open_input_file은 /sdcard/myfile.mp4에서 파일을 열려고 시도 할 때 -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의 config는 그들이 사용하는 몇 가지 코덱을 제외한 모든 것을 비활성화합니다. - Fasaxc
  • 아하. 나는 이것이 내 문제일지도 모른다. mp4 코덱을 활성화하고 mp4 파일을 열려고했지만 열 수 없습니다. 나는 어쩌면 내가 더 많은 코덱을 가능하게 할 필요가 있다고 생각하기 시작했다. 아마 모든 것을 가능하게하려고 시도 할 수도있다. - dimsuz
  • 나는 내가 필요한 것들을 가능하게했다. 264 demuxer 및 264 디코더와 함께 파일 프로토콜이 필요하며 시행 착오를 통해 다른 몇 가지 작업을 수행 할 수도 있습니다. ./configure --help를 수행 한 다음 --list-xyz 옵션을 사용하여 사용할 수있는 항목을 찾으십시오. - Fasaxc
  • 내 패키지 이름은?! 아직 안드로이드 프로젝트가 없습니다! 난 그냥 ARM을위한 ffmpeg를 컴파일 싶어요! 우분투에서는 괜찮지 만 윈도우에서는 다음과 같은 오류가 발생합니다. "알 수없는 옵션"- 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

연결된 질문


최근 질문