Package: mplayer
Version: 1.2-1
Severity: important
Tags: patch
User: [email protected]
Usertags: ffmpeg2.9

Dear Maintainer,

your package fails to build with the upcoming ffmpeg 2.9.
This bug will become release-critical at some point when the
ffmpeg2.9 transition gets closer.

Attached is a patch replacing the deprecated functionality.
It also works with ffmpeg 2.8.
Please apply this patch and forward it upstream, if necessary.

These changes are non-trivial and should be runtime-tested.

Best regards,
Andreas

diff --git a/debian/patches/0103_svn37447.patch b/debian/patches/0103_svn37447.patch
new file mode 100644
index 0000000..b511b5a
--- /dev/null
+++ b/debian/patches/0103_svn37447.patch
@@ -0,0 +1,34 @@
+From: rtogni
+Date: Fri, 14 Aug 2015 19:30:34 +0000
+Subject: [PATCH] Replace deprecated avctx->request_channels with
+ request_channel_layout
+
+Origin: svn://svn.mplayerhq.hu/mplayer/trunk@37447
+---
+ libmpcodecs/ad_ffmpeg.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c
+index 3abbf64..6def3bd 100644
+--- a/libmpcodecs/ad_ffmpeg.c
++++ b/libmpcodecs/ad_ffmpeg.c
+@@ -46,6 +46,7 @@ LIBAD_EXTERN(ffmpeg)
+ 
+ #include "libavcodec/avcodec.h"
+ #include "libavutil/dict.h"
++#include "libavutil/channel_layout.h"
+ 
+ struct adctx {
+     int last_samplerate;
+@@ -127,7 +128,7 @@ static int init(sh_audio_t *sh_audio)
+ 	lavc_context->bits_per_coded_sample = sh_audio->wf->wBitsPerSample;
+     }
+     lavc_context->channel_layout = sh_audio->channel_layout;
+-    lavc_context->request_channels = audio_output_channels;
++    lavc_context->request_channel_layout = av_get_default_channel_layout(audio_output_channels);
+     lavc_context->codec_tag = sh_audio->format; //FOURCC
+     lavc_context->codec_id = lavc_codec->id; // not sure if required, imho not --A'rpi
+ 
+-- 
+2.5.0
+
diff --git a/debian/patches/0104_svn37451.patch b/debian/patches/0104_svn37451.patch
new file mode 100644
index 0000000..7409000
--- /dev/null
+++ b/debian/patches/0104_svn37451.patch
@@ -0,0 +1,167 @@
+From: rtogni
+Date: Mon, 17 Aug 2015 21:18:31 +0000
+Subject: [PATCH] Replace deprecated avcodec resamples with libswresample
+ in af_lavcresample
+
+Origin: svn://svn.mplayerhq.hu/mplayer/trunk@37451
+---
+ libaf/af_lavcresample.c | 102 +++++++++++++++++++-----------------------------
+ 1 file changed, 41 insertions(+), 61 deletions(-)
+
+diff --git a/libaf/af_lavcresample.c b/libaf/af_lavcresample.c
+index a69e7de..fd7fe0c 100644
+--- a/libaf/af_lavcresample.c
++++ b/libaf/af_lavcresample.c
+@@ -25,15 +25,20 @@
+ 
+ #include "config.h"
+ #include "af.h"
+-#include "libavcodec/avcodec.h"
+ #include "libavutil/rational.h"
++#include "libswresample/swresample.h"
++#include "libavutil/channel_layout.h"
++#include "libavutil/opt.h"
++#include "libavutil/mem.h"
++#include "libavutil/common.h"
+ 
+ // Data for specific instances of this filter
+ typedef struct af_resample_s{
+-    struct AVResampleContext *avrctx;
+-    int16_t *in[AF_NCH];
++    struct SwrContext *swrctx;
++    uint8_t *in[1];
++    uint8_t *tmp[1];
+     int in_alloc;
+-    int index;
++    int tmp_alloc;
+ 
+     int filter_length;
+     int linear;
+@@ -70,8 +75,19 @@ static int control(struct af_instance_s* af, int cmd, void* arg)
+ 
+     if (s->ctx_out_rate != af->data->rate || s->ctx_in_rate != data->rate || s->ctx_filter_size != s->filter_length ||
+         s->ctx_phase_shift != s->phase_shift || s->ctx_linear != s->linear || s->ctx_cutoff != s->cutoff) {
+-        if(s->avrctx) av_resample_close(s->avrctx);
+-        s->avrctx= av_resample_init(af->data->rate, /*in_rate*/data->rate, s->filter_length, s->phase_shift, s->linear, s->cutoff);
++        swr_free(&s->swrctx);
++        if((s->swrctx=swr_alloc()) == NULL) return AF_ERROR;
++        av_opt_set_int(s->swrctx, "out_sample_rate", af->data->rate, 0);
++        av_opt_set_int(s->swrctx, "in_sample_rate", data->rate, 0);
++        av_opt_set_int(s->swrctx, "filter_size", s->filter_length, 0);
++        av_opt_set_int(s->swrctx, "phase_shift", s->phase_shift, 0);
++        av_opt_set_int(s->swrctx, "linear_interp", s->linear, 0);
++        av_opt_set_double(s->swrctx, "cutoff", s->cutoff, 0);
++        av_opt_set_sample_fmt(s->swrctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
++        av_opt_set_sample_fmt(s->swrctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
++        av_opt_set_int(s->swrctx, "in_channel_count", af->data->nch, 0);
++        av_opt_set_int(s->swrctx, "out_channel_count", af->data->nch, 0);
++        if(swr_init(s->swrctx) < 0) return AF_ERROR;
+         s->ctx_out_rate    = af->data->rate;
+         s->ctx_in_rate     = data->rate;
+         s->ctx_filter_size = s->filter_length;
+@@ -106,11 +122,10 @@ static void uninit(struct af_instance_s* af)
+         free(af->data->audio);
+     free(af->data);
+     if(af->setup){
+-        int i;
+         af_resample_t *s = af->setup;
+-        if(s->avrctx) av_resample_close(s->avrctx);
+-        for (i=0; i < AF_NCH; i++)
+-            free(s->in[i]);
++        swr_free(&s->swrctx);
++        av_free(s->in[0]);
++        av_free(s->tmp[0]);
+         free(s);
+     }
+ }
+@@ -119,71 +134,36 @@ static void uninit(struct af_instance_s* af)
+ static af_data_t* play(struct af_instance_s* af, af_data_t* data)
+ {
+   af_resample_t *s = af->setup;
+-  int i, j, consumed, ret;
+-  int16_t *in = (int16_t*)data->audio;
+-  int16_t *out;
++  int ret;
++  int8_t *in = (int8_t*)data->audio;
++  int8_t *out;
+   int chans   = data->nch;
+-  int in_len  = data->len/(2*chans);
++  int in_len  = data->len;
+   int out_len = in_len * af->mul + 10;
+-  int16_t tmp[AF_NCH][out_len];
+ 
+   if(AF_OK != RESIZE_LOCAL_BUFFER(af,data))
+       return NULL;
+ 
+-  out= (int16_t*)af->data->audio;
++  av_fast_malloc(&s->tmp[0], &s->tmp_alloc, FFALIGN(out_len,32));
++  if(s->tmp[0] == NULL) return NULL;
+ 
+-  out_len= FFMIN(out_len, af->data->len/(2*chans));
++  out= (int8_t*)af->data->audio;
+ 
+-  if(s->in_alloc < in_len + s->index){
+-      s->in_alloc= in_len + s->index;
+-      for(i=0; i<chans; i++){
+-          s->in[i]= realloc(s->in[i], s->in_alloc*sizeof(int16_t));
+-      }
+-  }
++  out_len= FFMIN(out_len, af->data->len);
+ 
+-  if(chans==1){
+-      memcpy(&s->in[0][s->index], in, in_len * sizeof(int16_t));
+-  }else if(chans==2){
+-      for(j=0; j<in_len; j++){
+-          s->in[0][j + s->index]= *(in++);
+-          s->in[1][j + s->index]= *(in++);
+-      }
+-  }else{
+-      for(j=0; j<in_len; j++){
+-          for(i=0; i<chans; i++){
+-              s->in[i][j + s->index]= *(in++);
+-          }
+-      }
+-  }
+-  in_len += s->index;
++  av_fast_malloc(&s->in[0], &s->in_alloc, FFALIGN(in_len,32));
++  if(s->in[0] == NULL) return NULL;
+ 
+-  for(i=0; i<chans; i++){
+-      ret= av_resample(s->avrctx, tmp[i], s->in[i], &consumed, in_len, out_len, i+1 == chans);
+-  }
+-  out_len= ret;
++  memcpy(s->in[0], in, in_len);
+ 
+-  s->index= in_len - consumed;
+-  for(i=0; i<chans; i++){
+-      memmove(s->in[i], s->in[i] + consumed, s->index*sizeof(int16_t));
+-  }
++  ret = swr_convert(s->swrctx, &s->tmp[0], out_len/chans/2, &s->in[0], in_len/chans/2);
++  if (ret < 0) return NULL;
++  out_len= ret*chans*2;
+ 
+-  if(chans==1){
+-      memcpy(out, tmp[0], out_len*sizeof(int16_t));
+-  }else if(chans==2){
+-      for(j=0; j<out_len; j++){
+-          *(out++)= tmp[0][j];
+-          *(out++)= tmp[1][j];
+-      }
+-  }else{
+-      for(j=0; j<out_len; j++){
+-          for(i=0; i<chans; i++){
+-              *(out++)= tmp[i][j];
+-          }
+-      }
+-  }
++  memcpy(out, s->tmp[0], out_len);
+ 
+   data->audio = af->data->audio;
+-  data->len   = out_len*chans*2;
++  data->len   = out_len;
+   data->rate  = af->data->rate;
+   return data;
+ }
+-- 
+2.5.0
+
diff --git a/debian/patches/0105_svn37453.patch b/debian/patches/0105_svn37453.patch
new file mode 100644
index 0000000..0584fbf
--- /dev/null
+++ b/debian/patches/0105_svn37453.patch
@@ -0,0 +1,93 @@
+From: rtogni
+Date: Sun, 23 Aug 2015 20:32:50 +0000
+Subject: [PATCH] Replace deprecated av_encode_video() with
+ av_encode_video2()
+
+Origin: svn://svn.mplayerhq.hu/mplayer/trunk@37453
+---
+ libmpcodecs/vf_lavc.c    | 12 +++++++++---
+ libmpcodecs/vf_mcdeint.c |  7 ++++++-
+ libmpcodecs/vf_uspp.c    |  7 ++++++-
+ 3 files changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/libmpcodecs/vf_lavc.c b/libmpcodecs/vf_lavc.c
+index 5e1b85f..62dcf91 100644
+--- a/libmpcodecs/vf_lavc.c
++++ b/libmpcodecs/vf_lavc.c
+@@ -86,6 +86,8 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+     mp_image_t* dmpi;
+     int out_size;
+     AVFrame *pic= vf->priv->pic;
++    int ret, got_pkt;
++    AVPacket pkt;
+ 
+     pic->data[0]=mpi->planes[0];
+     pic->data[1]=mpi->planes[1];
+@@ -94,10 +96,14 @@ static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+     pic->linesize[1]=mpi->stride[1];
+     pic->linesize[2]=mpi->stride[2];
+ 
+-    out_size = avcodec_encode_video(&lavc_venc_context,
+-	vf->priv->outbuf, vf->priv->outbuf_size, pic);
++    av_init_packet(&pkt);
++    pkt.data = vf->priv->outbuf;
++    pkt.size = vf->priv->outbuf_size;
++    ret = avcodec_encode_video2(&lavc_venc_context, &pkt, pic, &got_pkt);
+ 
+-    if(out_size<=0) return 1;
++    if(ret<=0) return 1;
++    if(!got_pkt) return 1;
++    out_size =  pkt.size;
+ 
+     dmpi=vf_get_image(vf->next,IMGFMT_MPEGPES,
+ 	MP_IMGTYPE_EXPORT, 0,
+diff --git a/libmpcodecs/vf_mcdeint.c b/libmpcodecs/vf_mcdeint.c
+index 6258d8b..1b2d1bb 100644
+--- a/libmpcodecs/vf_mcdeint.c
++++ b/libmpcodecs/vf_mcdeint.c
+@@ -92,6 +92,8 @@ struct vf_priv_s {
+ 
+ static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height){
+     int x, y, i;
++    int got_pkt;
++    AVPacket pkt;
+ 
+     for(i=0; i<3; i++){
+         p->frame->data[i]= src[i];
+@@ -101,7 +103,10 @@ static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int ds
+     p->avctx_enc->me_cmp=
+     p->avctx_enc->me_sub_cmp= FF_CMP_SAD /*| (p->parity ? FF_CMP_ODD : FF_CMP_EVEN)*/;
+     p->frame->quality= p->qp*FF_QP2LAMBDA;
+-    avcodec_encode_video(p->avctx_enc, p->outbuf, p->outbuf_size, p->frame);
++    av_init_packet(&pkt);
++    pkt.data = p->outbuf;
++    pkt.size = p->outbuf_size;
++    avcodec_encode_video2(p->avctx_enc, &pkt, p->frame, &got_pkt);
+     p->frame_dec = p->avctx_enc->coded_frame;
+ 
+     for(i=0; i<3; i++){
+diff --git a/libmpcodecs/vf_uspp.c b/libmpcodecs/vf_uspp.c
+index 18cb7fa..dd41700 100644
+--- a/libmpcodecs/vf_uspp.c
++++ b/libmpcodecs/vf_uspp.c
+@@ -177,11 +177,16 @@ static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int ds
+         const int x1= offset[i+count-1][0];
+         const int y1= offset[i+count-1][1];
+         int offset;
++        AVPacket pkt;
++        int ret, got_pkt;
+         p->frame->data[0]= p->src[0] + x1 + y1 * p->frame->linesize[0];
+         p->frame->data[1]= p->src[1] + x1/2 + y1/2 * p->frame->linesize[1];
+         p->frame->data[2]= p->src[2] + x1/2 + y1/2 * p->frame->linesize[2];
+ 
+-        avcodec_encode_video(p->avctx_enc[i], p->outbuf, p->outbuf_size, p->frame);
++        av_init_packet(&pkt);
++        pkt.data = p->outbuf;
++        pkt.size = p->outbuf_size;
++        avcodec_encode_video2(p->avctx_enc[i], &pkt, p->frame, &got_pkt);
+         p->frame_dec = p->avctx_enc[i]->coded_frame;
+ 
+         offset= (BLOCK-x1) + (BLOCK-y1)*p->frame_dec->linesize[0];
+-- 
+2.5.0
+
diff --git a/debian/patches/0106_svn37463.patch b/debian/patches/0106_svn37463.patch
new file mode 100644
index 0000000..0266627
--- /dev/null
+++ b/debian/patches/0106_svn37463.patch
@@ -0,0 +1,36 @@
+From: ib
+Date: Tue, 25 Aug 2015 10:19:53 +0000
+Subject: [PATCH] Add missing library swresample.
+
+This is necessary since r37451.
+
+Origin: svn://svn.mplayerhq.hu/mplayer/trunk@37463
+---
+ configure | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/configure b/configure
+index 21f712d..4dbcdf5 100755
+--- a/configure
++++ b/configure
+@@ -7090,13 +7090,13 @@ fi
+ if test "$ffmpeg_so" = auto ; then
+   ffmpeg_so=no
+   if $_pkg_config --exists libavutil ; then
+-    inc_ffmpeg=$($_pkg_config --cflags libswscale libavformat libavcodec libavutil)
+-    ld_tmp=$($_pkg_config --libs libswscale libavformat libavcodec libavutil)
++    inc_ffmpeg=$($_pkg_config --cflags libswscale libswresample libavformat libavcodec libavutil)
++    ld_tmp=$($_pkg_config --libs libswscale libswresample libavformat libavcodec libavutil)
+     header_check libavutil/avutil.h $inc_ffmpeg $ld_tmp &&
+       extra_cflags="$extra_cflags $inc_ffmpeg" &&
+       extra_ldflags="$extra_ldflags $ld_tmp" && ffmpeg_so=yes && ffmpeg=yes
+-  elif header_check libavutil/avutil.h -lswscale -lavformat -lavcodec -lavutil ; then
+-    extra_ldflags="$extra_ldflags -lswscale -lavformat -lavcodec -lavutil"
++  elif header_check libavutil/avutil.h -lswscale -lswresample -lavformat -lavcodec -lavutil ; then
++    extra_ldflags="$extra_ldflags -lswscale -lswresample -lavformat -lavcodec -lavutil"
+     ffmpeg_so=yes
+     ffmpeg=yes
+   fi
+-- 
+2.5.0
+
diff --git a/debian/patches/0107_svn37476.patch b/debian/patches/0107_svn37476.patch
new file mode 100644
index 0000000..1ed82ef
--- /dev/null
+++ b/debian/patches/0107_svn37476.patch
@@ -0,0 +1,333 @@
+From: rtogni
+Date: Sat, 5 Sep 2015 16:20:27 +0000
+Subject: [PATCH] Replace deprecated get_buffer, buffer_hints, and others
+
+This is needed to compile with latest FFmpeg
+
+Origin: svn://svn.mplayerhq.hu/mplayer/trunk@37476
+---
+ libmpcodecs/vd_ffmpeg.c | 211 +++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 164 insertions(+), 47 deletions(-)
+
+diff --git a/libmpcodecs/vd_ffmpeg.c b/libmpcodecs/vd_ffmpeg.c
+index 55f6fd0..2b28881 100644
+--- a/libmpcodecs/vd_ffmpeg.c
++++ b/libmpcodecs/vd_ffmpeg.c
+@@ -40,6 +40,7 @@
+ #if CONFIG_VDPAU
+ #include "libavcodec/vdpau.h"
+ #endif
++#include "libavutil/pixdesc.h"
+ 
+ static const vd_info_t info = {
+     "FFmpeg's libavcodec codec family",
+@@ -95,8 +96,11 @@ typedef struct {
+ 
+ #include "m_option.h"
+ 
+-static int get_buffer(AVCodecContext *avctx, AVFrame *pic);
++static int get_buffer(AVCodecContext *avctx, AVFrame *pic, int isreference);
++static int mpcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame);
++static int get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags);
+ static void release_buffer(AVCodecContext *avctx, AVFrame *pic);
++static void mpcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
+ static void draw_slice(struct AVCodecContext *s, const AVFrame *src, int offset[4],
+                        int y, int type, int height);
+ 
+@@ -269,19 +273,10 @@ static void set_dr_slice_settings(struct AVCodecContext *avctx, const AVCodec *l
+     if (lavc_param_vismv || (lavc_param_debug & (FF_DEBUG_VIS_MB_TYPE|FF_DEBUG_VIS_QP))) {
+         ctx->do_slices = ctx->do_dr1 = 0;
+     }
+-#ifndef CODEC_FLAG_EMU_EDGE
+-#define CODEC_FLAG_EMU_EDGE 0
+-#endif
+     if(ctx->do_dr1){
+-        avctx->flags |= CODEC_FLAG_EMU_EDGE;
+-        avctx->  reget_buffer =
+-        avctx->    get_buffer =     get_buffer;
+-        avctx->release_buffer = release_buffer;
++        avctx->get_buffer2 = get_buffer2;
+     } else if (lavc_codec->capabilities & CODEC_CAP_DR1) {
+-        avctx->flags &= ~CODEC_FLAG_EMU_EDGE;
+-        avctx->  reget_buffer = avcodec_default_reget_buffer;
+-        avctx->    get_buffer = avcodec_default_get_buffer;
+-        avctx->release_buffer = avcodec_default_release_buffer;
++        avctx->get_buffer2 = avcodec_default_get_buffer2;
+     }
+     avctx->slice_flags = 0;
+ }
+@@ -309,9 +304,7 @@ static void set_format_params(struct AVCodecContext *avctx,
+     if (IMGFMT_IS_HWACCEL(imgfmt)) {
+         ctx->do_dr1    = 1;
+         ctx->nonref_dr = 0;
+-        avctx->get_buffer      = get_buffer;
+-        avctx->release_buffer  = release_buffer;
+-        avctx->reget_buffer    = get_buffer;
++        avctx->get_buffer2 = get_buffer2;
+         mp_msg(MSGT_DECVIDEO, MSGL_V, IMGFMT_IS_XVMC(imgfmt) ?
+                MSGTR_MPCODECS_XVMCAcceleratedMPEG2 :
+                "[VD_FFMPEG] VDPAU accelerated decoding\n");
+@@ -384,7 +377,6 @@ static int init(sh_video_t *sh){
+ #endif
+     avctx->flags2|= lavc_param_fast;
+     avctx->codec_tag= sh->format;
+-    avctx->stream_codec_tag= sh->video.fccHandler;
+     avctx->idct_algo= lavc_param_idct_algo;
+     avctx->error_concealment= lavc_param_error_concealment;
+     avctx->debug= lavc_param_debug;
+@@ -668,7 +660,7 @@ static int init_vo(sh_video_t *sh, enum AVPixelFormat pix_fmt, int ignore_aspect
+     return 0;
+ }
+ 
+-static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
++static int get_buffer(AVCodecContext *avctx, AVFrame *pic, int isreference){
+     sh_video_t *sh = avctx->opaque;
+     vd_ffmpeg_ctx *ctx = sh->context;
+     mp_image_t *mpi=NULL;
+@@ -677,27 +669,12 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
+     int width = FFMAX(avctx->width,  -(-avctx->coded_width  >> avctx->lowres));
+     int height= FFMAX(avctx->height, -(-avctx->coded_height >> avctx->lowres));
+     // special case to handle reget_buffer
+-    if (pic->opaque && pic->data[0] && (!pic->buffer_hints || pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE))
++    if (pic->opaque && pic->data[0])
+         return 0;
+     avcodec_align_dimensions(avctx, &width, &height);
+ //printf("get_buffer %d %d %d\n", pic->reference, ctx->ip_count, ctx->b_count);
+ 
+-    if (pic->buffer_hints) {
+-        mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "Buffer hints: %u\n", pic->buffer_hints);
+-        type = MP_IMGTYPE_TEMP;
+-        if (pic->buffer_hints & FF_BUFFER_HINTS_READABLE)
+-            flags |= MP_IMGFLAG_READABLE;
+-        if (pic->buffer_hints & FF_BUFFER_HINTS_PRESERVE ||
+-            pic->buffer_hints & FF_BUFFER_HINTS_REUSABLE) {
+-            ctx->ip_count++;
+-            type = MP_IMGTYPE_IP;
+-            flags |= MP_IMGFLAG_PRESERVE;
+-        }
+-        flags|=(avctx->skip_idct<=AVDISCARD_DEFAULT && avctx->skip_frame<=AVDISCARD_DEFAULT && ctx->do_slices) ?
+-                 MP_IMGFLAG_DRAW_CALLBACK:0;
+-        mp_msg(MSGT_DECVIDEO, MSGL_DBG2, type == MP_IMGTYPE_IP ? "using IP\n" : "using TEMP\n");
+-    } else {
+-        if(!pic->reference){
++        if(!isreference){
+             ctx->b_count++;
+             flags|=(avctx->skip_idct<=AVDISCARD_DEFAULT && avctx->skip_frame<=AVDISCARD_DEFAULT && ctx->do_slices) ?
+                      MP_IMGFLAG_DRAW_CALLBACK:0;
+@@ -711,18 +688,16 @@ static int get_buffer(AVCodecContext *avctx, AVFrame *pic){
+         }else{
+             type= MP_IMGTYPE_IP;
+         }
+-    }
+ 
+     if (ctx->nonref_dr) {
+         if (flags & MP_IMGFLAG_PRESERVE)
+-            return avcodec_default_get_buffer(avctx, pic);
++            return mpcodec_default_get_buffer(avctx, pic);
+         // Use NUMBERED since for e.g. TEMP vos assume there will
+         // be no other frames between the get_image and matching put_image.
+         type = MP_IMGTYPE_NUMBERED;
+     }
+ 
+     if(init_vo(sh, avctx->pix_fmt, 1) < 0){
+-        avctx->release_buffer= avcodec_default_release_buffer;
+         goto disable_dr1;
+     }
+ 
+@@ -822,20 +797,17 @@ else if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
+ else
+     printf(".");
+ #endif
+-    pic->type= FF_BUFFER_TYPE_USER;
+     return 0;
+ 
+ disable_dr1:
+     ctx->do_dr1 = 0;
+     // For frame-multithreading these contexts aren't
+     // the same and must both be updated.
+-    ctx->avctx->get_buffer   =
+-    avctx->get_buffer        = avcodec_default_get_buffer;
+-    ctx->avctx->reget_buffer =
+-    avctx->reget_buffer      = avcodec_default_reget_buffer;
++    ctx->avctx->get_buffer2   =
++    avctx->get_buffer2 = avcodec_default_get_buffer2;
+     if (pic->data[0])
+-        release_buffer(avctx, pic);
+-    return avctx->get_buffer(avctx, pic);
++        mpcodec_default_release_buffer(avctx, pic);
++    return avctx->get_buffer2(avctx, pic,0);
+ }
+ 
+ static void release_buffer(struct AVCodecContext *avctx, AVFrame *pic){
+@@ -843,8 +815,8 @@ static void release_buffer(struct AVCodecContext *avctx, AVFrame *pic){
+     sh_video_t *sh = avctx->opaque;
+     vd_ffmpeg_ctx *ctx = sh->context;
+     int i;
+-    if (pic->type != FF_BUFFER_TYPE_USER) {
+-        avcodec_default_release_buffer(avctx, pic);
++    if (pic->opaque == NULL) {
++        mpcodec_default_release_buffer(avctx, pic);
+         return;
+     }
+ 
+@@ -954,7 +926,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
+     // even when we do dr we might actually get a buffer we had
+     // FFmpeg allocate - this mostly happens with nonref_dr.
+     // Ensure we treat it correctly.
+-    dr1= ctx->do_dr1 && pic->type == FF_BUFFER_TYPE_USER;
++    dr1= ctx->do_dr1 && pic->opaque != NULL;
+     if(ret<0) mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error while decoding frame!\n");
+ //printf("repeat: %d\n", pic->repeat_pict);
+ //-- vstats generation
+@@ -1128,3 +1100,148 @@ static enum AVPixelFormat get_format(struct AVCodecContext *avctx,
+     set_format_params(avctx, selected_format);
+     return selected_format;
+ }
++
++
++/*
++ FFWrapper
++*/
++static int mpcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
++{
++    return avcodec_default_get_buffer2(avctx, frame, 0);
++}
++
++static void mpcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)
++{
++    av_frame_unref(pic);
++}
++
++typedef struct CompatReleaseBufPriv {
++    AVCodecContext avctx;
++    AVFrame frame;
++    uint8_t avframe_padding[1024]; // hack to allow linking to a avutil with larger AVFrame
++} CompatReleaseBufPriv;
++
++static void compat_free_buffer(void *opaque, uint8_t *data)
++{
++    CompatReleaseBufPriv *priv = opaque;
++    release_buffer(&priv->avctx, &priv->frame);
++    av_freep(&priv);
++}
++
++static void compat_release_buffer(void *opaque, uint8_t *data)
++{
++    AVBufferRef *buf = opaque;
++    av_buffer_unref(&buf);
++}
++
++static int get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags)
++{
++    /*
++     * Wrap an old get_buffer()-allocated buffer in a bunch of AVBuffers.
++     * We wrap each plane in its own AVBuffer. Each of those has a reference to
++     * a dummy AVBuffer as its private data, unreffing it on free.
++     * When all the planes are freed, the dummy buffer's free callback calls
++     * release_buffer().
++     */
++    CompatReleaseBufPriv *priv = NULL;
++    AVBufferRef *dummy_buf = NULL;
++    int planes, i, ret;
++
++    ret = get_buffer(avctx, frame, flags & AV_GET_BUFFER_FLAG_REF);
++    if (ret < 0)
++        return ret;
++
++    /* return if the buffers are already set up
++     * this would happen e.g. when a custom get_buffer() calls
++     * avcodec_default_get_buffer
++     */
++    if (frame->buf[0])
++        goto end0;
++
++    priv = av_mallocz(sizeof(*priv));
++    if (!priv) {
++        ret = AVERROR(ENOMEM);
++        goto fail;
++    }
++    priv->avctx = *avctx;
++    priv->frame = *frame;
++
++    dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, priv, 0);
++    if (!dummy_buf) {
++        ret = AVERROR(ENOMEM);
++        goto fail;
++    }
++
++#define WRAP_PLANE(ref_out, data, data_size)                            \
++do {                                                                    \
++    AVBufferRef *dummy_ref = av_buffer_ref(dummy_buf);                  \
++    if (!dummy_ref) {                                                   \
++        ret = AVERROR(ENOMEM);                                          \
++        goto fail;                                                      \
++    }                                                                   \
++    ref_out = av_buffer_create(data, data_size, compat_release_buffer,  \
++                               dummy_ref, 0);                           \
++    if (!ref_out) {                                                     \
++        av_buffer_unref(&dummy_ref);                                    \
++        av_frame_unref(frame);                                          \
++        ret = AVERROR(ENOMEM);                                          \
++        goto fail;                                                      \
++    }                                                                   \
++} while (0)
++
++    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
++        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
++
++        planes = av_pix_fmt_count_planes(frame->format);
++        /* workaround for AVHWAccel plane count of 0, buf[0] is used as
++           check for allocated buffers: make libavcodec happy */
++        if (desc && desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
++            planes = 1;
++        if (!desc || planes <= 0) {
++            ret = AVERROR(EINVAL);
++            goto fail;
++        }
++
++        for (i = 0; i < planes; i++) {
++            int v_shift    = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
++            int plane_size = (frame->height >> v_shift) * frame->linesize[i];
++
++            WRAP_PLANE(frame->buf[i], frame->data[i], plane_size);
++        }
++    } else {
++        int planar = av_sample_fmt_is_planar(frame->format);
++        planes = planar ? avctx->channels : 1;
++
++        if (planes > FF_ARRAY_ELEMS(frame->buf)) {
++            frame->nb_extended_buf = planes - FF_ARRAY_ELEMS(frame->buf);
++            frame->extended_buf = av_malloc_array(sizeof(*frame->extended_buf),
++                                            frame->nb_extended_buf);
++            if (!frame->extended_buf) {
++                ret = AVERROR(ENOMEM);
++                goto fail;
++            }
++        }
++
++        for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++)
++            WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]);
++
++        for (i = 0; i < frame->nb_extended_buf; i++)
++            WRAP_PLANE(frame->extended_buf[i],
++                       frame->extended_data[i + FF_ARRAY_ELEMS(frame->buf)],
++                       frame->linesize[0]);
++    }
++
++    av_buffer_unref(&dummy_buf);
++
++end0:
++    frame->width  = avctx->width;
++    frame->height = avctx->height;
++
++    return 0;
++
++fail:
++    release_buffer(avctx, frame);
++    av_freep(&priv);
++    av_buffer_unref(&dummy_buf);
++    return ret;
++}
+-- 
+2.6.1
+
diff --git a/debian/patches/series b/debian/patches/series
index 0e7fb1b..a24225c 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,5 +3,10 @@
 0100_svn37545.patch
 0101_svn37548.patch
 0102_svn37549.patch
+0103_svn37447.patch
+0104_svn37451.patch
+0105_svn37453.patch
+0106_svn37463.patch
+0107_svn37476.patch
 0200_Hurd_PATH_MAX.patch
 0201_PATH_MAX_HURD.patch

Reply via email to