错误:使用 NDK 编译 FFMPEG 时未定义对'av_free_packet(AVPacket*)'的引用
error: undefined reference to 'av_free_packet(AVPacket*)' when use NDK to compile ffmpeg
我编译了我的cpp,通过我的ANDROID MK使用带有ANDROID NDK的ffmpeg liberary,如下所示:
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 build 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*)'
我使用的是windows 7+cygwin+NDKR8,但ffmpeg的lib"libavcodec.so,libavfilter.so,libavformat.so,libavutil.so,librpostdoc.so,libswresample.so,libswscale.so"是用NDK的独立方法使用"ubuntu+NDK8"编译的。我在头文件中包含了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); };
};
我做了一个小实验。我认为问题仍然存在于extern "C"
。您发布了DllAvCodec.h文件,但我担心在PlayDemuxFFmpeg.cpp中,您在没有extern "C"
包装的情况下#include
了ffmpeg标头(可能不在cpp文件中,而是在>DllAvCodec.h之前包含的一个标头中)。
请尝试重新排列库:
LOCAL_SHARED_LIBRARIES :=
libavformat
libavcodec
libavfilter
libavutil
libpostproc
libswscale
libswresample
相关文章:
- 尝试构建"lock-free"数据结构C++
- 调用 free() 有时会导致程序崩溃
- Valgrind 大小为 8 且地址 0x5b7e520 的读取无效,在大小为 16 的块内为 0 字节 free'd
- 为什么 free() 函数不将内存返回给操作系统?
- "fast"或"normal"在"free(): invalid next size (fast)"中是什么意思?
- 逻辑'double free or corruption (fasttop)'错误
- 无法将Omnetpp::cPacket强制转换为Inet::Packet
- emplace_back和push_back给出错误'double free or corruption (fasttop)'尽管定义了复制和移动构造函数
- free():在有效指针异常中-使用流读取巨大文件时
- C-Free and MySQL connect
- 为什么FREE块堆这么大
- std::free线程安全吗
- 为什么'allocate in one library and free in the other'是错误的
- C++ 调用析构函数后动态模板队列"double free or corruption (out)"
- 不断得到分段错误和free()无效指针
- C++: free(): 无效的下一个大小(快速)
- 在 malloc 之后检查 &在调用 free() 之前
- free():在 C++ 中的 tcache 2 中检测到双重释放
- free():仅在一种情况下指针无效
- std::vector using back(), pop_back(), push_back(), 得到'double free or corruption'错误