2013-07-22 328 views
0

我编译常委会通过我的Android MK使用的ffmpeg liberary与Android NDK如下:错误:未定义的引用 'av_free_packet(AVPacket *)' 时使用NDK编译的ffmpeg

LOCAL_PATH := $(call my-dir) 
    DEFINES += -DTARGET_POSIX \ 
       -DTARGET_LINUX \ 
      -D_LINUX \ 
      -DTARGET_ANDROID \ 
      -D__STDC_CONSTANT_MACROS 

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libavcodec 
    LOCAL_SRC_FILES := lib/lib/libavcodec.so 
    include $(PREBUILT_SHARED_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libavfilter 
    LOCAL_SRC_FILES := lib/lib/libavfilter.so 
    include $(PREBUILT_SHARED_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libavformat 
    LOCAL_SRC_FILES := lib/lib/libavformat.so 
    include $(PREBUILT_SHARED_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libavutil 
    LOCAL_SRC_FILES := lib/lib/libavutil.so 
    include $(PREBUILT_SHARED_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libpostproc 
    LOCAL_SRC_FILES := lib/lib/libpostproc.so 
    include $(PREBUILT_SHARED_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libswresample 
    LOCAL_SRC_FILES := lib/lib/libswresample.so 
    include $(PREBUILT_SHARED_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE := libswscale 
    LOCAL_SRC_FILES := lib/lib/libswscale.so 
    include $(PREBUILT_SHARED_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE:= player 
    base := $(LOCAL_PATH) 
    LOCAL_SRC_FILES += cores/PlayDemux.cpp \ 
        cores/PlayDemuxFFmpeg.cpp \ 
        cores/PlayFactoryDemuxer.cpp 

    LOCAL_C_INCLUDES += $(LOCAL_PATH) \ 
      $(LOCAL_PATH)/lib \ 
      $(LOCAL_PATH)/lib/include \ 
      $(LOCAL_PATH)/cores/player \ 
    LOCAL_CPPFLAGS += -Wall -fexceptions $(DEFINES) 
    include $(BUILD_STATIC_LIBRARY) 

    include $(CLEAR_VARS) 
    LOCAL_MODULE:= testmain 

    LOCAL_SRC_FILES := \ 
     testmain.cpp \ 

    LOCAL_C_INCLUDES += $(LOCAL_PATH) \ 
       $(LOCAL_PATH)/lib 
    LOCAL_CPPFLAGS += -Wall -fexceptions $(DEFINES) 

    LOCAL_SHARED_LIBRARIES := libavcodec \ 
       libavformat \ 
       libavfilter \ 
       libavutil \ 
       libpostproc \ 
       libswscale \ 
       libswresample 

    LOCAL_STATIC_LIBRARIES := player 

    include $(BUILD_EXECUTABLE) 

但是当我做“NDK建造v = 1”,编译后,我得到了:

Install  : libavcodec.so => libs/armeabi-v7a/libavcodec.so 
    install -p /cygdrive/d/player/obj/local/armeabi-v7a/libavcodec.so /cygdrive/d/player/libs/armeabi-v7a/libavcodec.so 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded D:/player/libs/armeabi-v7a/libavcodec.so 
    Install  : libavfilter.so => libs/armeabi-v7a/libavfilter.so 
    install -p /cygdrive/d/player/obj/local/armeabi-v7a/libavfilter.so /cygdrive/d/player/libs/armeabi-v7a/libavfilter.so 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded D:/player/libs/armeabi-v7a/libavfilter.so 
    Install  : libavformat.so => libs/armeabi-v7a/libavformat.so 
    install -p /cygdrive/d/player/obj/local/armeabi-v7a/libavformat.so /cygdrive/d/player/libs/armeabi-v7a/libavformat.so 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded D:/player/libs/armeabi-v7a/libavformat.so 
    Install  : libavutil.so => libs/armeabi-v7a/libavutil.so 
    install -p /cygdrive/d/player/obj/local/armeabi-v7a/libavutil.so /cygdrive/d/player/libs/armeabi-v7a/libavutil.so 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded D:/player/libs/armeabi-v7a/libavutil.so 
    Install  : libpostproc.so => libs/armeabi-v7a/libpostproc.so 
    install -p /cygdrive/d/player/obj/local/armeabi-v7a/libpostproc.so /cygdrive/d/player/libs/armeabi-v7a/libpostproc.so 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded D:/player/libs/armeabi-v7a/libpostproc.so 
    Install  : libswresample.so => libs/armeabi-v7a/libswresample.so 
    install -p /cygdrive/d/player/obj/local/armeabi-v7a/libswresample.so /cygdrive/d/player/libs/armeabi-v7a/libswresample.so 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded D:/player/libs/armeabi-v7a/libswresample.so 
    Install  : libswscale.so => libs/armeabi-v7a/libswscale.so 
    install -p /cygdrive/d/player/obj/local/armeabi-v7a/libswscale.so /cygdrive/d/player/libs/armeabi-v7a/libswscale.so 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded D:/player/libs/armeabi-v7a/libswscale.so 
    Executable  : testmain 
    /cygdrive/d/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/arm-linux-androideabi-g++ -Wl,--gc-sections -Wl,-z,nocopyreloc --sysroot=D:/android/android-ndk-r8e/platforms/android-14/arch-arm D:/player/obj/local/armeabi-v7a/objs/testmain/testmain.o D:/player/obj/local/armeabi-v7a/libplayer.a D:/android/android-ndk-r8e/sources/cxx-stl/stlport/libs/armeabi-v7a/libstlport_static.a -lgcc D:/player/obj/local/armeabi-v7a/libavcodec.so D:/player/obj/local/armeabi-v7a/libavformat.so D:/player/obj/local/armeabi-v7a/libavfilter.so D:/player/obj/local/armeabi-v7a/libavutil.so D:/player/obj/local/armeabi-v7a/libpostproc.so D:/player/obj/local/armeabi-v7a/libswscale.so D:/player/obj/local/armeabi-v7a/libswresample.so -no-canonical-prefixes -march=armv7-a -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -lc -lm -o D:/player/obj/local/armeabi-v7a/testmain 
    D:/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: D:/player/obj/local/armeabi-v7a/libplayer.a(PlayDemuxFFmpeg.o): in function PlayDemuxFFmpeg::Flush():D:/player/jni/lib/DllAvCodec.h:144: error: undefined reference to 'av_free_packet(AVPacket*)' 

使用I'm视窗7 + cygwin的+ NDKR8,但LIB“libavcodec.so,libavfilter.so,libavformat.so,libavutil .so,libpostproc.so,libswresample.so,libswscale.so“是使用”ubuntu + NDK8“与独立的NDK独立编译的。 ,我在头文件中包含extern“c”代码。

那么,如何纠正错误?

我DLLavcodec.h是:

#pragma once 
#include "DllAvUtil.h" 

extern "C" { 
    #include <libavcodec/avcodec.h> 
} 


class DllAvCodec : public DllAvCodecInterface 
{ 
public: 
    static CCriticalSection m_critSection; 

    virtual ~DllAvCodec() {} 
    virtual void avcodec_register_all() 
    { 
    ::avcodec_register_all(); 
    } 
    virtual void avcodec_flush_buffers(AVCodecContext *avctx) { ::avcodec_flush_buffers(avctx); } 
    virtual int avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) 
    { 
    return ::avcodec_open2(avctx, codec, options); 
    } 
    virtual int avcodec_open2_dont_call(AVCodecContext *avctx, AVCodec *codec, AVDictionary **options) { *(volatile int *)0x0 = 0; return 0; } 
    virtual int avcodec_close_dont_call(AVCodecContext *avctx) { *(volatile int *)0x0 = 0; return 0; } 
    virtual AVCodec *avcodec_find_decoder(enum CodecID id) { return ::avcodec_find_decoder(id); } 
    virtual AVCodec *avcodec_find_encoder(enum CodecID id) { return ::avcodec_find_encoder(id); } 
    virtual int avcodec_close(AVCodecContext *avctx) 
    { 
    return ::avcodec_close(avctx); 
    } 
    virtual AVFrame *avcodec_alloc_frame() { return ::avcodec_alloc_frame(); } 
    virtual int avpicture_fill(AVPicture *picture, uint8_t *ptr, PixelFormat pix_fmt, int width, int height) { return ::avpicture_fill(picture, ptr, pix_fmt, width, height); } 
    virtual int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, AVPacket *avpkt) { return ::avcodec_decode_video2(avctx, picture, got_picture_ptr, avpkt); } 
    virtual int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, int *got_frame_ptr, AVPacket *avpkt) { return ::avcodec_decode_audio4(avctx, frame, got_frame_ptr, avpkt); } 
    virtual int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, AVPacket *avpkt) { return ::avcodec_decode_subtitle2(avctx, sub, got_sub_ptr, avpkt); } 
    virtual int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, const short *samples) { return ::avcodec_encode_audio(avctx, buf, buf_size, samples); } 
    virtual int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr) { return ::avcodec_encode_audio2(avctx, avpkt, frame, got_packet_ptr); } 
    virtual int avpicture_get_size(PixelFormat pix_fmt, int width, int height) { return ::avpicture_get_size(pix_fmt, width, height); } 
    virtual AVCodecContext *avcodec_alloc_context3(AVCodec *codec) { return ::avcodec_alloc_context3(codec); } 
    virtual void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { ::avcodec_string(buf, buf_size, enc, encode); } 
    virtual void avcodec_get_context_defaults3(AVCodecContext *s, AVCodec *codec) { ::avcodec_get_context_defaults3(s, codec); } 

    virtual AVCodecParserContext *av_parser_init(int codec_id) { return ::av_parser_init(codec_id); } 
    virtual int av_parser_parse2(AVCodecParserContext *s,AVCodecContext *avctx, uint8_t **poutbuf, int *poutbuf_size, 
        const uint8_t *buf, int buf_size, 
        int64_t pts, int64_t dts, int64_t pos) 
    { 
    return ::av_parser_parse2(s, avctx, poutbuf, poutbuf_size, buf, buf_size, pts, dts, pos); 
    } 
    virtual void av_parser_close(AVCodecParserContext *s) { ::av_parser_close(s); } 

    virtual AVBitStreamFilterContext *av_bitstream_filter_init(const char *name) { return ::av_bitstream_filter_init(name); } 
    virtual int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, 
    AVCodecContext *avctx, const char *args, 
    uint8_t **poutbuf, int *poutbuf_size, 
    const uint8_t *buf, int buf_size, int keyframe) { return ::av_bitstream_filter_filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe); } 
    virtual void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc) { ::av_bitstream_filter_close(bsfc); } 

    virtual void avpicture_free(AVPicture *picture) { ::avpicture_free(picture); } 
    virtual void av_free_packet(AVPacket *pkt) { ::av_free_packet(pkt); } 
    virtual int avpicture_alloc(AVPicture *picture, PixelFormat pix_fmt, int width, int height) { return ::avpicture_alloc(picture, pix_fmt, width, height); } 
    virtual int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic) { return ::avcodec_default_get_buffer(s, pic); } 
    virtual void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic) { ::avcodec_default_release_buffer(s, pic); } 
    virtual enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat *fmt) { return ::avcodec_default_get_format(s, fmt); } 
    virtual AVCodec *av_codec_next(AVCodec *c) { return ::av_codec_next(c); } 

    virtual int av_dup_packet(AVPacket *pkt) { return ::av_dup_packet(pkt); } 
    virtual void av_init_packet(AVPacket *pkt) { return ::av_init_packet(pkt); } 
    virtual int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels, enum AVSampleFormat sample_fmt, const uint8_t *buf, int buf_size, int align) { return ::avcodec_fill_audio_frame(frame, nb_channels, sample_fmt, buf, buf_size, align); } 
    virtual void avcodec_free_frame(AVFrame **frame) { return ::avcodec_free_frame(frame); }; 
}; 
+0

请发布'DllAvCodec.h'文件。恐怕有些'extern“C”'仍然丢失。 –

+0

好吧,DllAvCodec.h张贴 – wolfz

回答

2

我做了一个小实验。我相信问题仍在extern "C"。你贴DllAvCodec.h文件,但恐怕在PlayDemuxFFmpeg.cpp#include没有extern "C"包装ffmpeg的报头(也许不是在CPP文件,但在头一个,它之前,DllAvCodec包括.h)。

+1

是的!我发现一个包含头部没有extern“C”之前DllAvCodec.h谢谢! – wolfz

+1

@Alex Cohn你可以看到这个问题,我真的很挣扎从最后一个星期:http://stackoverflow.com/questions/36745535/ffmpeg-main-function-in-android-studio – Spartan

0

请尝试重新洗牌库:

LOCAL_SHARED_LIBRARIES := \ 
      libavformat \ 
      libavcodec \ 
      libavfilter \ 
      libavutil \ 
      libpostproc \ 
      libswscale \ 
      libswresample 
+0

我重新编译了ffmpeg库,但仍然错误:未定义引用'av_free_packet(AVPacket *)' – wolfz

+0

但我转储该symbole:arm-linux-androideabi-nm lib/lib/libavcodec。 a | grep av_free_packet 00000770 T av_free_packet U av_free_packet – wolfz

+0

您重新编译了**什么**? –

-1

这是因为该方法av_free_packet(AVPacket *)在文件中avcodec.h失踪。 请确认它是否存在。

+0

不,“undefined reference”意味着方法_(实际上,函数,因为ffmpeg是用C编写的,没有C++对象/方法)_是声明,并且编译器在头文件中找到它,但链接程序在库中找不到它。 –

相关问题