Description: Backport changes for the libav 9 API
 Also replace loading of libavcodec and libavutil via dlopen by linking against
 it.
Author: Sebastian Ramacher <sramacher@debian.org>
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 <cstdio>
 
 #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 <cstdio>
+#include <cstdarg>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavutil/mem.h>
+}
 
 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 <libavcodec/avcodec.h>
 // AVPacket was declared in avformat.h before April 2009
 #if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(52, 25, 0)
-#include "libavformat/avformat.h"
+#include <libavformat/avformat.h>
 #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 <libavcodec/...h>
 # Also add libavutil, so ffmpeg headers can #include "log.h".