未定义的参考 - 在android ndk上的ffmpeg

时间:2011-10-16 04:41:24

标签: android ffmpeg android-ndk

我花了很多时间试图找出为什么在尝试链接到ffmpeg时仍然会得到“未定义的引用”。 我已经阅读了大部分(如果不是所有)有关该主题的帖子和网站,所以我想我在这里遗漏了一些东西,我希望你能帮助我。

我有什么:

我使用的是Windows 7 + cygwin + crystax r4。 我使用RockPlayer的ffmpeg源编译了FFMPEG以及我做过的一些修改(仅包括/排除解复用器,解码器,编码器......) 编译完成后,我得到:

  • 一个名为armv5te的新文件夹,其中包括:
  • 一个名为“include”的文件夹,其中包含每个libs的所有文件夹'.h
  • 名为“lib”的文件夹,其中包含所有libs'.a
  • 一个名为libffmpeg.so的共享库(已检查过soname,它是libffmpeg)

共享库也没有放在project / lib / armeabi / libffmpeg.so上

编译后,我尝试编译我的项目并链接它。虽然我的.cpp编译好了,但我得到了许多未定义的引用。

这是我的构建脚本:

NDK=/cygdrive/c/Gabriel/Desenvolvimento/SDKs/Android/android-ndk-r4-crystax
PLATFORM=$NDK/build/platforms/android-8/arch-arm/
PREBUILT=$NDK/build/prebuilt/windows/arm-eabi-4.4.0


function build_one
{

./configure --target-os=linux \
    --prefix=$PREFIX \
    --enable-cross-compile \
    --extra-libs="-lgcc" \
    --arch=arm \
    --cc=$PREBUILT/bin/arm-eabi-gcc \
    --cross-prefix=$PREBUILT/bin/arm-eabi- \
    --nm=$PREBUILT/bin/arm-eabi-nm \
    --sysroot=$PLATFORM \
    --extra-cflags=" -O2 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums  -fno-strict-aliasing -finline-limit=300 $OPTIMIZE_CFLAGS " \
    --disable-shared \
    --enable-static \
    --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -nostdlib -lc -lm -ldl -llog" \
    --disable-stripping \
    --disable-debug \
    --disable-symver \
    --disable-ffprobe \
    --disable-devices \
    --disable-avfilter \
    --disable-swscale \
    --disable-ffplay \
    --disable-ffserver \
    --disable-network \
        (many more ...)
    --enable-asm \
    $ADDITIONAL_CONFIGURE_FLAG

#make clean
make  -j4 install

$PREBUILT/bin/arm-eabi-ar d libavcodec/libavcodec.a inverse.o

$PREBUILT/bin/arm-eabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -soname libffmpeg.so -shared -nostdlib  -z,noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a  -lc -lm -lz -ldl -llog  --warn-once  --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-eabi/4.4.0/libgcc.a

}

#arm v5
CPU=armv5te
OPTIMIZE_CFLAGS="-marm -march=$CPU"
PREFIX=./android/$CPU 
ADDITIONAL_CONFIGURE_FLAG=
build_one

这是我的android.mk:

LOCAL_PATH := $(call my-dir)

#declare the prebuilt library
include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg-prebuilt
LOCAL_SRC_FILES := $(LOCAL_PATH)/ffmpeg/android/armv5te/libffmpeg.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/android/armv5te/include
LOCAL_PRELINK_MODULE := true 
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := audiocodec
LOCAL_SRC_FILES := ffmpeg_audio.cpp
LOCAL_SHARED_LIBRARY := libffmpeg
LOCAL_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/android/armv5te/include
LOCAL_LDLIBS    := -llog -ljnigraphics -lz -lm $(LOCAL_PATH)/ffmpeg/android/armv5te/libffmpeg.so
include $(BUILD_SHARED_LIBRARY)

结果:

Compile++ thumb: audiocodec <= /cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFM
PEG/jni/ffmpeg_audio.cpp
SharedLibrary  : libaudiocodec.so
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_r
eadSamples':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:172: u
ndefined reference to `avcodec_decode_audio3(AVCodecContext*, short*, int*, AVPa
cket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:178: u
ndefined reference to `av_read_frame(AVFormatContext*, AVPacket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_s
eekToPosMS':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:147: u
ndefined reference to `av_rescale_q(long long, AVRational, AVRational)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:150: u
ndefined reference to `av_seek_frame(AVFormatContext*, int, long long, int)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:151: u
ndefined reference to `avcodec_flush_buffers(AVCodecContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:152: u
ndefined reference to `av_read_frame(AVFormatContext*, AVPacket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_c
loseFile':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:82: un
defined reference to `avcodec_close(AVCodecContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:83: un
defined reference to `av_free(void*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:84: un
defined reference to `av_close_input_file(AVFormatContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `Java_gabriel_audioslower_pro_ffmpegDecoder_o
penAudioFile':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:37: un
defined reference to `av_open_input_file(AVFormatContext**, char const*, AVInput
Format*, int, AVFormatParameters*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:44: un
defined reference to `av_find_stream_info(AVFormatContext*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:52: un
defined reference to `avcodec_find_decoder(CodecID)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:60: un
defined reference to `avcodec_open(AVCodecContext*, AVCodec*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:67: un
defined reference to `av_malloc(unsigned int)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:70: un
defined reference to `av_read_frame(AVFormatContext*, AVPacket*)'
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeabi/objs/audi
ocodec/ffmpeg_audio.o: In function `JNI_OnLoad':
/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/jni/ffmpeg_audio.cpp:25: un
defined reference to `av_register_all()'
collect2: ld returned 1 exit status
make: *** [/cygdrive/c/Gabriel/Desenvolvimento/Workspace/FFMPEG/obj/local/armeab
i/libaudiocodec.so] Error 1

有趣的是,来自ffmpeg的一些函数,如av_register_all(),现在显示在未定义的引用列表中。

我有什么想法可以解决它?我花了3天时间试图让事情发生.. 谢谢!

2 个答案:

答案 0 :(得分:5)

尝试添加

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

到你的makefile。

答案 1 :(得分:4)

也许您忘了将ffmpeg标头包装为C:

extern "C"
{
#include "avcodec.h"
}