Description: Backport changes for the libav 9 API Also replace loading of libavcodec and libavutil via dlopen by linking against it. Author: Sebastian Ramacher Bug-Debian: http://bugs.debian.org/720824 Last-Update: 2013-09-12 --- a/plugins/video/H.263-1998/h263-1998.cxx +++ b/plugins/video/H.263-1998/h263-1998.cxx @@ -216,7 +216,7 @@ return false; } - m_context = FFMPEGLibraryInstance.AvcodecAllocContext(); + m_context = FFMPEGLibraryInstance.AvcodecAllocContext(m_codec); if (m_context == NULL) { PTRACE(1, m_prefix, "Failed to allocate context for encoder"); return false; @@ -312,6 +312,7 @@ return; } +#ifdef CODEC_FLAG_H263P_UMV if (STRCMPI(option, H263_ANNEX_D) == 0) { // Annex D: Unrestructed Motion Vectors // Level 2+ @@ -322,6 +323,7 @@ m_context->flags &= ~CODEC_FLAG_H263P_UMV; return; } +#endif #if 0 // DO NOT ENABLE THIS FLAG. FFMPEG IS NOT THREAD_SAFE WHEN THIS FLAG IS SET if (STRCMPI(option, H263_ANNEX_F) == 0) { @@ -356,6 +358,7 @@ return; } +#ifdef CODEC_FLAG_H263P_SLICE_STRUCT if (STRCMPI(option, H263_ANNEX_K) == 0) { // Annex K: Slice Structure // does not work with eyeBeam @@ -365,7 +368,9 @@ m_context->flags &= ~CODEC_FLAG_H263P_SLICE_STRUCT; return; } +#endif +#ifdef CODEC_FLAG_H263P_AIV if (STRCMPI(option, H263_ANNEX_S) == 0) { // Annex S: Alternative INTER VLC mode // does not work with eyeBeam @@ -375,6 +380,7 @@ m_context->flags &= ~CODEC_FLAG_H263P_AIV; return; } +#endif if (STRCMPI(option, PLUGINCODEC_MEDIA_PACKETIZATION) == 0 || STRCMPI(option, PLUGINCODEC_MEDIA_PACKETIZATIONS) == 0) { @@ -450,15 +456,6 @@ PTRACE(5, m_prefix, "qmax set to " << m_context->qmax); PTRACE(5, m_prefix, "payload size set to " << m_context->rtp_payload_size); - #define CODEC_TRACER_FLAG(tracer, flag) \ - PTRACE(4, m_prefix, #flag " is " << ((m_context->flags & flag) ? "enabled" : "disabled")); - CODEC_TRACER_FLAG(tracer, CODEC_FLAG_H263P_UMV); - CODEC_TRACER_FLAG(tracer, CODEC_FLAG_OBMC); - CODEC_TRACER_FLAG(tracer, CODEC_FLAG_AC_PRED); - CODEC_TRACER_FLAG(tracer, CODEC_FLAG_H263P_SLICE_STRUCT) - CODEC_TRACER_FLAG(tracer, CODEC_FLAG_LOOP_FILTER); - CODEC_TRACER_FLAG(tracer, CODEC_FLAG_H263P_AIV); - return FFMPEGLibraryInstance.AvcodecOpen(m_context, m_codec) == 0; } @@ -521,7 +518,7 @@ // Need to copy to local buffer to guarantee 16 byte alignment memcpy(m_inputFrame->data[0], OPAL_VIDEO_FRAME_DATA_PTR(header), header->width*header->height*3/2); - m_inputFrame->pict_type = (flags & PluginCodec_CoderForceIFrame) ? FF_I_TYPE : AV_PICTURE_TYPE_NONE; + m_inputFrame->pict_type = (flags & PluginCodec_CoderForceIFrame) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_NONE; /* m_inputFrame->pts = (int64_t)srcRTP.GetTimestamp()*m_context->time_base.den/m_context->time_base.num/VIDEO_CLOCKRATE; @@ -603,13 +600,19 @@ m_context->rtp_callback = &H263_RFC2190_EncoderContext::RTPCallBack; m_context->opaque = this; // used to separate out packets from different encode threads +#ifdef CODEC_FLAG_H263P_UMV m_context->flags &= ~CODEC_FLAG_H263P_UMV; +#endif m_context->flags &= ~CODEC_FLAG_4MV; #if LIBAVCODEC_RTP_MODE m_context->flags &= ~CODEC_FLAG_H263P_AIC; #endif +#ifdef CODEC_FLAG_H263P_AIV m_context->flags &= ~CODEC_FLAG_H263P_AIV; +#endif +#ifdef CODEC_FLAG_H263P_SLICE_STRUCT m_context->flags &= ~CODEC_FLAG_H263P_SLICE_STRUCT; +#endif return true; } @@ -658,7 +661,7 @@ return; } - m_context = FFMPEGLibraryInstance.AvcodecAllocContext(); + m_context = FFMPEGLibraryInstance.AvcodecAllocContext(m_codec); if (m_context == NULL) { PTRACE(1, m_prefix, "Failed to allocate context for decoder"); return; --- a/plugins/video/H.264/h264-x264.cxx +++ b/plugins/video/H.264/h264-x264.cxx @@ -48,6 +48,7 @@ #include "shared/h264frame.h" #include "shared/x264wrap.h" +#include #define MY_CODEC x264 // Name of codec (use C variable characters) #define MY_CODEC_LOG "x264" @@ -1067,18 +1068,17 @@ if ((m_codec = FFMPEGLibraryInstance.AvcodecFindDecoder(CODEC_ID_H264)) == NULL) return false; - if ((m_context = FFMPEGLibraryInstance.AvcodecAllocContext()) == NULL) + if ((m_context = FFMPEGLibraryInstance.AvcodecAllocContext(m_codec)) == NULL) return false; m_context->workaround_bugs = FF_BUG_AUTODETECT; - m_context->error_recognition = FF_ER_AGGRESSIVE; m_context->idct_algo = FF_IDCT_H264; m_context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; m_context->flags = CODEC_FLAG_INPUT_PRESERVED | CODEC_FLAG_EMU_EDGE; - m_context->flags2 = CODEC_FLAG2_BRDO | - CODEC_FLAG2_MEMC_ONLY | + m_context->flags2 = CODEC_FLAG2_SKIP_RD | +#ifdef CODEC_FLAG2_DROP_FRAME_TIMECODE CODEC_FLAG2_DROP_FRAME_TIMECODE | - CODEC_FLAG2_SKIP_RD | +#endif CODEC_FLAG2_CHUNKS; if ((m_picture = FFMPEGLibraryInstance.AvcodecAllocFrame()) == NULL) --- a/plugins/video/MPEG4-ffmpeg/mpeg4.cxx +++ b/plugins/video/MPEG4-ffmpeg/mpeg4.cxx @@ -589,17 +589,14 @@ m_avpicture->quality = m_videoQMin; #ifdef USE_ORIG - m_avcontext->flags |= CODEC_FLAG_PART; // data partitioning m_avcontext->flags |= CODEC_FLAG_4MV; // 4 motion vectors #else m_avcontext->max_b_frames=0; /*don't use b frames*/ m_avcontext->flags|=CODEC_FLAG_AC_PRED; - m_avcontext->flags|=CODEC_FLAG_H263P_UMV; /*c->flags|=CODEC_FLAG_QPEL;*/ /*don't enable this one: this forces profile_level to advanced simple profile */ m_avcontext->flags|=CODEC_FLAG_4MV; m_avcontext->flags|=CODEC_FLAG_GMC; m_avcontext->flags|=CODEC_FLAG_LOOP_FILTER; - m_avcontext->flags|=CODEC_FLAG_H263P_SLICE_STRUCT; #endif m_avcontext->opaque = this; // for use in RTP callback } @@ -691,7 +688,12 @@ bool MPEG4EncoderContext::OpenCodec() { - m_avcontext = FFMPEGLibraryInstance.AvcodecAllocContext(); + if((m_avcodec = FFMPEGLibraryInstance.AvcodecFindEncoder(CODEC_ID_MPEG4)) == NULL){ + PTRACE(1, "MPEG4", "Encoder not found"); + return false; + } + + m_avcontext = FFMPEGLibraryInstance.AvcodecAllocContext(m_avcodec); if (m_avcontext == NULL) { PTRACE(1, "MPEG4", "Encoder failed to allocate context for encoder"); return false; @@ -703,11 +705,6 @@ return false; } - if((m_avcodec = FFMPEGLibraryInstance.AvcodecFindEncoder(CODEC_ID_MPEG4)) == NULL){ - PTRACE(1, "MPEG4", "Encoder not found"); - return false; - } - #if PLUGINCODEC_TRACING // debugging flags if (PTRACE_CHECK(4)) { @@ -804,7 +801,7 @@ // Should the next frame be an I-Frame? if ((flags & PluginCodec_CoderForceIFrame) || (m_frameNum == 0)) { - m_avpicture->pict_type = FF_I_TYPE; + m_avpicture->pict_type = AV_PICTURE_TYPE_I; } else // No IFrame requested, let avcodec decide what to do { @@ -1325,7 +1322,6 @@ void MPEG4DecoderContext::SetStaticDecodingParams() { m_avcontext->flags |= CODEC_FLAG_4MV; - m_avcontext->flags |= CODEC_FLAG_PART; m_avcontext->workaround_bugs = 0; // no workaround for buggy implementations } @@ -1399,7 +1395,7 @@ return false; } - m_avcontext = FFMPEGLibraryInstance.AvcodecAllocContext(); + m_avcontext = FFMPEGLibraryInstance.AvcodecAllocContext(m_avcodec); if (m_avcontext == NULL) { PTRACE(1, "MPEG4", "Decoder failed to allocate context"); return false; --- a/plugins/video/common/dyna.cxx +++ b/plugins/video/common/dyna.cxx @@ -38,6 +38,13 @@ * Matthias Schneider (ma30002000@yahoo.de) */ #include "dyna.h" +#include +#include + +extern "C" { +#include +#include +} bool DynaLink::Open(const char *name) { @@ -228,101 +235,15 @@ m_libAvutil.Close(); } -#define CHECK_AVUTIL(name, func) \ - (seperateLibAvutil ? \ - m_libAvutil.GetFunction(name, (DynaLink::Function &)func) : \ - m_libAvcodec.GetFunction(name, (DynaLink::Function &)func) \ - ) \ - - bool FFMPEGLibrary::Load() { WaitAndSignal m(processLock); if (IsLoaded()) return true; - bool seperateLibAvutil = false; - -#ifdef LIBAVCODEC_LIB_NAME - if (m_libAvcodec.Open(LIBAVCODEC_LIB_NAME)) - seperateLibAvutil = true; - else -#endif - if (m_libAvcodec.Open("libavcodec")) - seperateLibAvutil = false; - else if (m_libAvcodec.Open("avcodec-" AV_STRINGIFY(LIBAVCODEC_VERSION_MAJOR))) - seperateLibAvutil = true; - else { - PTRACE(1, m_codecString, "Failed to load FFMPEG libavcodec library"); - return false; - } - - if (seperateLibAvutil && - !( -#ifdef LIBAVUTIL_LIB_NAME - m_libAvutil.Open(LIBAVUTIL_LIB_NAME) || -#endif - m_libAvutil.Open("libavutil") || - m_libAvutil.Open("avutil-" AV_STRINGIFY(LIBAVUTIL_VERSION_MAJOR)) - ) ) { - PTRACE(1, m_codecString, "Failed to load FFMPEG libavutil library"); - return false; - } - - strcpy(m_libAvcodec.m_codecString, m_codecString); - strcpy(m_libAvutil.m_codecString, m_codecString); - - if (!m_libAvcodec.GetFunction("avcodec_init", (DynaLink::Function &)Favcodec_init)) - return false; - - if (!m_libAvcodec.GetFunction("av_init_packet", (DynaLink::Function &)Fav_init_packet)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_register_all", (DynaLink::Function &)Favcodec_register_all)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_find_encoder", (DynaLink::Function &)Favcodec_find_encoder)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_find_decoder", (DynaLink::Function &)Favcodec_find_decoder)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_alloc_context", (DynaLink::Function &)Favcodec_alloc_context)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_alloc_frame", (DynaLink::Function &)Favcodec_alloc_frame)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_open", (DynaLink::Function &)Favcodec_open)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_close", (DynaLink::Function &)Favcodec_close)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_encode_video", (DynaLink::Function &)Favcodec_encode_video)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_decode_video2", (DynaLink::Function &)Favcodec_decode_video)) - return false; - - if (!m_libAvcodec.GetFunction("avcodec_set_dimensions", (DynaLink::Function &)Favcodec_set_dimensions)) - return false; - - if (!CHECK_AVUTIL("av_free", Favcodec_free)) - return false; - - if(!m_libAvcodec.GetFunction("avcodec_version", (DynaLink::Function &)Favcodec_version)) - return false; - - if (!CHECK_AVUTIL("av_log_set_level", FAv_log_set_level)) - return false; - - if (!CHECK_AVUTIL("av_log_set_callback", FAv_log_set_callback)) - return false; - // must be called before using avcodec lib - unsigned libVer = Favcodec_version(); + unsigned libVer = avcodec_version(); if (libVer != LIBAVCODEC_VERSION_INT) { PTRACE(2, m_codecString, "Warning: compiled against libavcodec headers from version " << LIBAVCODEC_VERSION_MAJOR << '.' << LIBAVCODEC_VERSION_MINOR << '.' << LIBAVCODEC_VERSION_MICRO @@ -334,8 +255,7 @@ << (libVer >> 16) << ((libVer>>8) & 0xff) << (libVer & 0xff)); } - Favcodec_init(); - Favcodec_register_all (); + avcodec_register_all(); #if PLUGINCODEC_TRACING AvLogSetLevel(AV_LOG_DEBUG); @@ -350,49 +270,49 @@ AVCodec *FFMPEGLibrary::AvcodecFindEncoder(enum CodecID id) { - return Favcodec_find_encoder(id); + return avcodec_find_encoder(id); } AVCodec *FFMPEGLibrary::AvcodecFindDecoder(enum CodecID id) { WaitAndSignal m(processLock); - return Favcodec_find_decoder(id); + return avcodec_find_decoder(id); } -AVCodecContext *FFMPEGLibrary::AvcodecAllocContext(void) +AVCodecContext *FFMPEGLibrary::AvcodecAllocContext(AVCodec *codec) { WaitAndSignal m(processLock); - return Favcodec_alloc_context(); + return avcodec_alloc_context3(codec); } AVFrame *FFMPEGLibrary::AvcodecAllocFrame(void) { WaitAndSignal m(processLock); - return Favcodec_alloc_frame(); + return avcodec_alloc_frame(); } int FFMPEGLibrary::AvcodecOpen(AVCodecContext *ctx, AVCodec *codec) { WaitAndSignal m(processLock); - return Favcodec_open(ctx, codec); + return avcodec_open2(ctx, codec, NULL); } int FFMPEGLibrary::AvcodecClose(AVCodecContext *ctx) { WaitAndSignal m(processLock); - return Favcodec_close(ctx); + return avcodec_close(ctx); } int FFMPEGLibrary::AvcodecEncodeVideo(AVCodecContext *ctx, BYTE *buf, int buf_size, const AVFrame *pict) { int res; - res = Favcodec_encode_video(ctx, buf, buf_size, pict); + res = avcodec_encode_video(ctx, buf, buf_size, pict); PTRACE(6, m_codecString, "DYNA\tEncoded into " << res << " bytes, max " << buf_size); return res; @@ -401,35 +321,35 @@ int FFMPEGLibrary::AvcodecDecodeVideo(AVCodecContext *ctx, AVFrame *pict, int *got_picture_ptr, BYTE *buf, int buf_size) { AVPacket avpkt; - Fav_init_packet(&avpkt); + av_init_packet(&avpkt); avpkt.data = buf; avpkt.size = buf_size; - return Favcodec_decode_video(ctx, pict, got_picture_ptr, &avpkt); + return avcodec_decode_video2(ctx, pict, got_picture_ptr, &avpkt); } void FFMPEGLibrary::AvcodecFree(void * ptr) { WaitAndSignal m(processLock); - Favcodec_free(ptr); + av_free(ptr); } void FFMPEGLibrary::AvSetDimensions(AVCodecContext *s, int width, int height) { WaitAndSignal m(processLock); - Favcodec_set_dimensions(s, width, height); + avcodec_set_dimensions(s, width, height); } void FFMPEGLibrary::AvLogSetLevel(int level) { - FAv_log_set_level(level); + av_log_set_level(level); } void FFMPEGLibrary::AvLogSetCallback(void (*callback)(void*, int, const char*, va_list)) { - FAv_log_set_callback(callback); + av_log_set_callback(callback); } bool FFMPEGLibrary::IsLoaded() --- a/plugins/video/common/dyna.h +++ b/plugins/video/common/dyna.h @@ -95,7 +95,7 @@ AVCodec *AvcodecFindEncoder(enum CodecID id); AVCodec *AvcodecFindDecoder(enum CodecID id); - AVCodecContext *AvcodecAllocContext(void); + AVCodecContext *AvcodecAllocContext(AVCodec*); AVFrame *AvcodecAllocFrame(void); int AvcodecOpen(AVCodecContext *ctx, AVCodec *codec); int AvcodecClose(AVCodecContext *ctx); @@ -120,26 +120,6 @@ CodecID m_codec; char m_codecString[32]; - void (*Favcodec_init)(void); - void (*Fav_init_packet)(AVPacket *pkt); - - void (*Favcodec_register_all)(void); - AVCodec *(*Favcodec_find_encoder)(enum CodecID id); - AVCodec *(*Favcodec_find_decoder)(enum CodecID id); - AVCodecContext *(*Favcodec_alloc_context)(void); - AVFrame *(*Favcodec_alloc_frame)(void); - int (*Favcodec_open)(AVCodecContext *ctx, AVCodec *codec); - int (*Favcodec_close)(AVCodecContext *ctx); - int (*Favcodec_encode_video)(AVCodecContext *ctx, BYTE *buf, int buf_size, const AVFrame *pict); - int (*Favcodec_decode_video)(AVCodecContext *ctx, AVFrame *pict, int *got_picture_ptr, AVPacket *avpkt); - unsigned (*Favcodec_version)(void); - void (*Favcodec_set_dimensions)(AVCodecContext *ctx, int width, int height); - - void (*Favcodec_free)(void *); - - void (*FAv_log_set_level)(int level); - void (*FAv_log_set_callback)(void (*callback)(void*, int, const char*, va_list)); - bool m_isLoadedOK; }; --- a/plugins/video/common/ffmpeg.h +++ b/plugins/video/common/ffmpeg.h @@ -45,11 +45,13 @@ #include "platform.h" -#include "libavcodec/avcodec.h" +extern "C" { +#include // AVPacket was declared in avformat.h before April 2009 #if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(52, 25, 0) -#include "libavformat/avformat.h" +#include #endif +} #ifndef LIBAVCODEC_VERSION_INT #error Libavcodec include is not correct --- a/plugins/video/H.263-1998/Makefile.in +++ b/plugins/video/H.263-1998/Makefile.in @@ -34,8 +34,8 @@ $(COMMONDIR)/mpi.cxx \ $(COMMONDIR)/dyna.cxx -CFLAGS += @LIBAVCODEC_CFLAGS@ -I$(COMMONDIR) -LIBS += @DL_LIBS@ +CFLAGS += @LIBAVCODEC_CFLAGS@ @LIBAVUTIL_CFLAGS@ -I$(COMMONDIR) +LIBS += @DL_LIBS@ @LIBAVCODEC_LIBS@ @LIBAVUTIL_LIBS@ HAVE_LIBAVCODEC_RTP_MODE=@HAVE_LIBAVCODEC_RTP_MODE@ ifeq ($(HAVE_LIBAVCODEC_RTP_MODE),yes) --- a/plugins/video/H.264/Makefile.in +++ b/plugins/video/H.264/Makefile.in @@ -34,8 +34,8 @@ $(SHAREDDIR)/x264wrap.cxx \ $(COMMONDIR)/dyna.cxx \ -CFLAGS += @LIBAVCODEC_CFLAGS@ -I$(COMMONDIR) -DLIB_DIR='"$(libdir)"' -DVC_PLUGIN_DIR='"@VC_PLUGIN_DIR@"' -LIBS += @DL_LIBS@ +CFLAGS += @LIBAVCODEC_CFLAGS@ @LIBAVUTIL_CFLAGS@ -I$(COMMONDIR) -DLIB_DIR='"$(libdir)"' -DVC_PLUGIN_DIR='"@VC_PLUGIN_DIR@"' +LIBS += @DL_LIBS@ @LIBAVCODEC_LIBS@ @LIBAVUTIL_LIBS@ IS_H264_LICENSED:=@IS_H264_LICENSED@ ifeq ($(IS_H264_LICENSED),yes) --- a/plugins/video/MPEG4-ffmpeg/Makefile.in +++ b/plugins/video/MPEG4-ffmpeg/Makefile.in @@ -30,8 +30,8 @@ SRCDIR := . SRCS := mpeg4.cxx $(COMMONDIR)/dyna.cxx -CFLAGS += @LIBAVCODEC_CFLAGS@ -I$(COMMONDIR) -LIBS += @DL_LIBS@ +CFLAGS += @LIBAVCODEC_CFLAGS@ @LIBAVUTIL_CFLAGS@ -I$(COMMONDIR) +LIBS += @DL_LIBS@ @LIBAVCODEC_LIBS@ @LIBAVUTIL_LIBS@ # Add LIBAVCODEC_SOURCE_DIR to the include path so we can #include # Also add libavutil, so ffmpeg headers can #include "log.h".