]> git.sesse.net Git - ffmpeg/commitdiff
lavc decoders: work with refcounted frames.
authorAnton Khirnov <anton@khirnov.net>
Wed, 21 Nov 2012 20:34:46 +0000 (21:34 +0100)
committerAnton Khirnov <anton@khirnov.net>
Fri, 8 Mar 2013 06:38:30 +0000 (07:38 +0100)
239 files changed:
doc/multithreading.txt
libavcodec/4xm.c
libavcodec/8bps.c
libavcodec/8svx.c
libavcodec/aacdec.c
libavcodec/aasc.c
libavcodec/ac3dec.c
libavcodec/adpcm.c
libavcodec/adxdec.c
libavcodec/alac.c
libavcodec/alsdec.c
libavcodec/amrnbdec.c
libavcodec/amrwbdec.c
libavcodec/anm.c
libavcodec/ansi.c
libavcodec/apedec.c
libavcodec/asvdec.c
libavcodec/atrac1.c
libavcodec/atrac3.c
libavcodec/aura.c
libavcodec/avcodec.h
libavcodec/avs.c
libavcodec/bethsoftvideo.c
libavcodec/bfi.c
libavcodec/bink.c
libavcodec/binkaudio.c
libavcodec/bmp.c
libavcodec/bmv.c
libavcodec/c93.c
libavcodec/cavs.c
libavcodec/cavsdec.c
libavcodec/cdgraphics.c
libavcodec/cdxl.c
libavcodec/cinepak.c
libavcodec/cljr.c
libavcodec/cllc.c
libavcodec/cngdec.c
libavcodec/cook.c
libavcodec/cscd.c
libavcodec/cyuv.c
libavcodec/dcadec.c
libavcodec/dfa.c
libavcodec/dnxhddec.c
libavcodec/dpcm.c
libavcodec/dpx.c
libavcodec/dsicinav.c
libavcodec/dvdec.c
libavcodec/dxa.c
libavcodec/dxtory.c
libavcodec/dxva2_h264.c
libavcodec/eacmv.c
libavcodec/eamad.c
libavcodec/eatgq.c
libavcodec/eatgv.c
libavcodec/eatqi.c
libavcodec/error_resilience.c
libavcodec/escape124.c
libavcodec/ffv1.c
libavcodec/ffv1.h
libavcodec/ffv1dec.c
libavcodec/flacdec.c
libavcodec/flashsv.c
libavcodec/flicvideo.c
libavcodec/fraps.c
libavcodec/frwu.c
libavcodec/g722dec.c
libavcodec/g723_1.c
libavcodec/g726.c
libavcodec/gifdec.c
libavcodec/gsmdec.c
libavcodec/h261dec.c
libavcodec/h263.c
libavcodec/h263dec.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_cabac.c
libavcodec/h264_cavlc.c
libavcodec/h264_direct.c
libavcodec/h264_loopfilter.c
libavcodec/h264_mb_template.c
libavcodec/h264_mc_template.c
libavcodec/h264_mvpred.h
libavcodec/h264_refs.c
libavcodec/huffyuvdec.c
libavcodec/idcinvideo.c
libavcodec/iff.c
libavcodec/imc.c
libavcodec/indeo2.c
libavcodec/indeo3.c
libavcodec/internal.h
libavcodec/interplayvideo.c
libavcodec/intrax8.c
libavcodec/ituh263dec.c
libavcodec/ituh263enc.c
libavcodec/ivi_common.c
libavcodec/ivi_common.h
libavcodec/jvdec.c
libavcodec/kgv1dec.c
libavcodec/kmvc.c
libavcodec/lagarith.c
libavcodec/lcldec.c
libavcodec/libgsm.c
libavcodec/libilbc.c
libavcodec/libopencore-amr.c
libavcodec/libopenjpegdec.c
libavcodec/libopusdec.c
libavcodec/libschroedingerdec.c
libavcodec/libspeexdec.c
libavcodec/libvpxdec.c
libavcodec/ljpegenc.c
libavcodec/loco.c
libavcodec/mace.c
libavcodec/mdec.c
libavcodec/mimic.c
libavcodec/mjpegbdec.c
libavcodec/mjpegdec.c
libavcodec/mlpdec.c
libavcodec/mmvideo.c
libavcodec/motion_est.c
libavcodec/motionpixels.c
libavcodec/mpc7.c
libavcodec/mpc8.c
libavcodec/mpeg12.c
libavcodec/mpeg4video.c
libavcodec/mpeg4videodec.c
libavcodec/mpeg4videoenc.c
libavcodec/mpegaudiodec.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h
libavcodec/mpegvideo_enc.c
libavcodec/mpegvideo_motion.c
libavcodec/mpegvideo_xvmc.c
libavcodec/msmpeg4.c
libavcodec/msrle.c
libavcodec/mss1.c
libavcodec/mss2.c
libavcodec/mss3.c
libavcodec/mss4.c
libavcodec/msvideo1.c
libavcodec/mxpegdec.c
libavcodec/nellymoserdec.c
libavcodec/nuv.c
libavcodec/options.c
libavcodec/options_table.h
libavcodec/pcm-mpeg.c
libavcodec/pcm.c
libavcodec/pcx.c
libavcodec/pictordec.c
libavcodec/pngdec.c
libavcodec/pnm.c
libavcodec/pnm.h
libavcodec/pnmdec.c
libavcodec/proresdec.c
libavcodec/pthread.c
libavcodec/ptx.c
libavcodec/qcelpdec.c
libavcodec/qdm2.c
libavcodec/qdrw.c
libavcodec/qpeg.c
libavcodec/qtrle.c
libavcodec/r210dec.c
libavcodec/ra144dec.c
libavcodec/ra288.c
libavcodec/ralf.c
libavcodec/rawdec.c
libavcodec/rl2.c
libavcodec/roqvideodec.c
libavcodec/roqvideoenc.c
libavcodec/rpza.c
libavcodec/rv10.c
libavcodec/rv30.c
libavcodec/rv34.c
libavcodec/rv40.c
libavcodec/s302m.c
libavcodec/sgidec.c
libavcodec/shorten.c
libavcodec/sipr.c
libavcodec/smacker.c
libavcodec/smc.c
libavcodec/sunrast.c
libavcodec/svq1dec.c
libavcodec/svq1enc.c
libavcodec/svq3.c
libavcodec/takdec.c
libavcodec/targa.c
libavcodec/thread.h
libavcodec/tiertexseqv.c
libavcodec/tiff.c
libavcodec/tmv.c
libavcodec/truemotion1.c
libavcodec/truemotion2.c
libavcodec/truespeech.c
libavcodec/tscc.c
libavcodec/tscc2.c
libavcodec/tta.c
libavcodec/twinvq.c
libavcodec/txd.c
libavcodec/ulti.c
libavcodec/utils.c
libavcodec/utvideo.h
libavcodec/utvideodec.c
libavcodec/v210dec.c
libavcodec/v210x.c
libavcodec/v410dec.c
libavcodec/vaapi_h264.c
libavcodec/vb.c
libavcodec/vble.c
libavcodec/vc1dec.c
libavcodec/vcr1.c
libavcodec/vdpau.c
libavcodec/vdpau_h264.c
libavcodec/version.h
libavcodec/vmdav.c
libavcodec/vmnc.c
libavcodec/vorbisdec.c
libavcodec/vp3.c
libavcodec/vp5.c
libavcodec/vp56.c
libavcodec/vp56.h
libavcodec/vp56data.h
libavcodec/vp6.c
libavcodec/vp8.c
libavcodec/vp8.h
libavcodec/vqavideo.c
libavcodec/wavpack.c
libavcodec/wmadec.c
libavcodec/wmalosslessdec.c
libavcodec/wmaprodec.c
libavcodec/wmavoice.c
libavcodec/wmv2dec.c
libavcodec/wnv1.c
libavcodec/ws-snd1.c
libavcodec/xan.c
libavcodec/xl.c
libavcodec/xwddec.c
libavcodec/xxan.c
libavcodec/yop.c
libavcodec/zerocodec.c
libavcodec/zmbv.c

index b72bc1607947d708e2876815c2983ef0425d5d25..9b27b108c6163b5d864033d4a4d6d76012913dc5 100644 (file)
@@ -57,6 +57,11 @@ which re-allocates them for other threads.
 Add CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little
 speed gain at this point but it should work.
 
+If there are inter-frame dependencies, so the codec calls
+ff_thread_report/await_progress(), set AVCodecInternal.allocate_progress. The
+frames must then be freed with ff_thread_release_buffer().
+Otherwise leave it at zero and decode directly into the user-supplied frames.
+
 Call ff_thread_report_progress() after some part of the current picture has decoded.
 A good place to put this is where draw_horiz_band() is called - add this if it isn't
 called anywhere, as it's useful too and the implementation is trivial when you're
index 82f8417f0e16c284d87c32446f3291da2d9cafa7..e34fa1ddc6c41cf2c52b0d2d5912b117b834256f 100644 (file)
@@ -24,6 +24,7 @@
  * 4XM codec.
  */
 
+#include "libavutil/frame.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
@@ -131,7 +132,7 @@ typedef struct CFrameBuffer {
 typedef struct FourXContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame *current_picture, *last_picture;
+    AVFrame *last_picture;
     GetBitContext pre_gb;          ///< ac/dc prefix
     GetBitContext gb;
     GetByteContext g;
@@ -256,15 +257,15 @@ static av_cold void init_vlcs(FourXContext *f)
     }
 }
 
-static void init_mv(FourXContext *f)
+static void init_mv(FourXContext *f, int linesize)
 {
     int i;
 
     for (i = 0; i < 256; i++) {
         if (f->version > 1)
-            f->mv[i] = mv[i][0] + mv[i][1] * f->current_picture->linesize[0] / 2;
+            f->mv[i] = mv[i][0] + mv[i][1] * linesize / 2;
         else
-            f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * f->current_picture->linesize[0] / 2;
+            f->mv[i] = (i & 15) - 8 + ((i >> 4) - 8) * linesize / 2;
     }
 }
 
@@ -385,14 +386,15 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,
     }
 }
 
-static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
+static int decode_p_frame(FourXContext *f, AVFrame *frame,
+                          const uint8_t *buf, int length)
 {
     int x, y;
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
     uint16_t *src    = (uint16_t *)f->last_picture->data[0];
-    uint16_t *dst    = (uint16_t *)f->current_picture->data[0];
-    const int stride =             f->current_picture->linesize[0] >> 1;
+    uint16_t *dst    = (uint16_t *)frame->data[0];
+    const int stride =             frame->linesize[0] >> 1;
     unsigned int bitstream_size, bytestream_size, wordstream_size, extra,
                  bytestream_offset, wordstream_offset;
 
@@ -435,7 +437,7 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length)
     bytestream2_init(&f->g, buf + bytestream_offset,
                      length - bytestream_offset);
 
-    init_mv(f);
+    init_mv(f, frame->linesize[0]);
 
     for (y = 0; y < height; y += 8) {
         for (x = 0; x < width; x += 8)
@@ -494,12 +496,12 @@ static int decode_i_block(FourXContext *f, int16_t *block)
     return 0;
 }
 
-static inline void idct_put(FourXContext *f, int x, int y)
+static inline void idct_put(FourXContext *f, AVFrame *frame, int x, int y)
 {
     int16_t (*block)[64] = f->block;
-    int stride           = f->current_picture->linesize[0] >> 1;
+    int stride           = frame->linesize[0] >> 1;
     int i;
-    uint16_t *dst = ((uint16_t*)f->current_picture->data[0]) + y * stride + x;
+    uint16_t *dst = ((uint16_t*)frame->data[0]) + y * stride + x;
 
     for (i = 0; i < 4; i++) {
         block[i][0] += 0x80 * 8 * 8;
@@ -647,14 +649,14 @@ static int mix(int c0, int c1)
     return red / 3 * 1024 + green / 3 * 32 + blue / 3;
 }
 
-static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
+static int decode_i2_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length)
 {
     int x, y, x2, y2;
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
     const int mbs    = (FFALIGN(width, 16) >> 4) * (FFALIGN(height, 16) >> 4);
-    uint16_t *dst    = (uint16_t*)f->current_picture->data[0];
-    const int stride =            f->current_picture->linesize[0]>>1;
+    uint16_t *dst    = (uint16_t*)frame->data[0];
+    const int stride =            frame->linesize[0]>>1;
     GetByteContext g3;
 
     if (length < mbs * 8) {
@@ -693,7 +695,7 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length)
     return 0;
 }
 
-static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
+static int decode_i_frame(FourXContext *f, AVFrame *frame, const uint8_t *buf, int length)
 {
     int x, y, ret;
     const int width  = f->avctx->width;
@@ -747,7 +749,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length)
             if ((ret = decode_i_mb(f)) < 0)
                 return ret;
 
-            idct_put(f, x, y);
+            idct_put(f, frame, x, y);
         }
     }
 
@@ -764,7 +766,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     int buf_size          = avpkt->size;
     FourXContext *const f = avctx->priv_data;
     AVFrame *picture      = data;
-    AVFrame *p;
     int i, frame_4cc, frame_size, ret;
 
     frame_4cc = AV_RL32(buf);
@@ -825,43 +826,34 @@ static int decode_frame(AVCodecContext *avctx, void *data,
         frame_size = buf_size - 12;
     }
 
-    FFSWAP(AVFrame*, f->current_picture, f->last_picture);
-
-    p                  = f->current_picture;
-    avctx->coded_frame = p;
-
     // alternatively we would have to use our own buffer management
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 1;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, picture, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     if (frame_4cc == AV_RL32("ifr2")) {
-        p->pict_type = AV_PICTURE_TYPE_I;
-        if ((ret = decode_i2_frame(f, buf - 4, frame_size + 4)) < 0)
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        if ((ret = decode_i2_frame(f, picture, buf - 4, frame_size + 4)) < 0)
             return ret;
     } else if (frame_4cc == AV_RL32("ifrm")) {
-        p->pict_type = AV_PICTURE_TYPE_I;
-        if ((ret = decode_i_frame(f, buf, frame_size)) < 0)
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        if ((ret = decode_i_frame(f, picture, buf, frame_size)) < 0)
             return ret;
     } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
         if (!f->last_picture->data[0]) {
-            f->last_picture->reference = 1;
-            if ((ret = ff_get_buffer(avctx, f->last_picture)) < 0) {
+            if ((ret = ff_get_buffer(avctx, f->last_picture,
+                                     AV_GET_BUFFER_FLAG_REF)) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return ret;
             }
             memset(f->last_picture->data[0], 0, avctx->height * FFABS(f->last_picture->linesize[0]));
         }
 
-        p->pict_type = AV_PICTURE_TYPE_P;
-        if ((ret = decode_p_frame(f, buf, frame_size)) < 0)
+        picture->pict_type = AV_PICTURE_TYPE_P;
+        if ((ret = decode_p_frame(f, picture, buf, frame_size)) < 0)
             return ret;
     } else if (frame_4cc == AV_RL32("snd_")) {
         av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
@@ -871,9 +863,11 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                buf_size);
     }
 
-    p->key_frame = p->pict_type == AV_PICTURE_TYPE_I;
+    picture->key_frame = picture->pict_type == AV_PICTURE_TYPE_I;
 
-    *picture   = *p;
+    av_frame_unref(f->last_picture);
+    if ((ret = av_frame_ref(f->last_picture, picture)) < 0)
+        return ret;
     *got_frame = 1;
 
     emms_c();
@@ -900,13 +894,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
     else
         avctx->pix_fmt = AV_PIX_FMT_BGR555;
 
-    f->current_picture = avcodec_alloc_frame();
-    f->last_picture    = avcodec_alloc_frame();
-    if (!f->current_picture || !f->last_picture) {
-        avcodec_free_frame(&f->current_picture);
-        avcodec_free_frame(&f->last_picture);
+    f->last_picture = av_frame_alloc();
+    if (!f->last_picture)
         return AVERROR(ENOMEM);
-    }
 
     return 0;
 }
@@ -924,12 +914,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
         f->cfrm[i].allocated_size = 0;
     }
     ff_free_vlc(&f->pre_vlc);
-    if (f->current_picture->data[0])
-        avctx->release_buffer(avctx, f->current_picture);
-    if (f->last_picture->data[0])
-        avctx->release_buffer(avctx, f->last_picture);
-    avcodec_free_frame(&f->current_picture);
-    avcodec_free_frame(&f->last_picture);
+    av_frame_free(&f->last_picture);
 
     return 0;
 }
index ceed13f5b81c621d776ea9c442ee9e8bebf8ac7d..fcb7b2bfcddf544958bd20e73adfdf41cc37ef28 100644 (file)
@@ -46,7 +46,6 @@ static const enum AVPixelFormat pixfmt_rgb24[] = {
 
 typedef struct EightBpsContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     unsigned char planes;
     unsigned char planemap[4];
@@ -57,6 +56,7 @@ typedef struct EightBpsContext {
 static int decode_frame(AVCodecContext *avctx, void *data,
                         int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     EightBpsContext * const c = avctx->priv_data;
@@ -71,12 +71,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     unsigned char *planemap = c->planemap;
     int ret;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference    = 0;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -96,8 +91,8 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 
         /* Decode a plane */
         for (row = 0; row < height; row++) {
-            pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p];
-            pixptr_end = pixptr + c->pic.linesize[0];
+            pixptr = frame->data[0] + row * frame->linesize[0] + planemap[p];
+            pixptr_end = pixptr + frame->linesize[0];
             dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2));
             /* Decode a row of this plane */
             while (dlen > 0) {
@@ -134,15 +129,14 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                                                      AV_PKT_DATA_PALETTE,
                                                      NULL);
         if (pal) {
-            c->pic.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
             memcpy(c->pal, pal, AVPALETTE_SIZE);
         }
 
-        memcpy (c->pic.data[1], c->pal, AVPALETTE_SIZE);
+        memcpy (frame->data[1], c->pal, AVPALETTE_SIZE);
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -153,7 +147,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     EightBpsContext * const c = avctx->priv_data;
 
     c->avctx       = avctx;
-    c->pic.data[0] = NULL;
 
     switch (avctx->bits_per_coded_sample) {
     case 8:
@@ -192,23 +185,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    EightBpsContext * const c = avctx->priv_data;
-
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    return 0;
-}
-
 AVCodec ff_eightbps_decoder = {
     .name           = "8bps",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_8BPS,
     .priv_data_size = sizeof(EightBpsContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
index 4f2a8971e79bfa3978ab0fa327a412cf8bfc312d..94eb319d3d7f0b6768fe4492ae5ba3f5d55b1b11 100644 (file)
@@ -137,7 +137,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = buf_size * (is_compr + 1);
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index e044f9ab65993b21676c149b6d085ab5b1689091..43a6029ef4e1f78ba3000928125085438d4c47ca 100644 (file)
@@ -179,8 +179,9 @@ static int frame_configure_elements(AVCodecContext *avctx)
     }
 
     /* get output buffer */
+    av_frame_unref(ac->frame);
     ac->frame->nb_samples = 2048;
-    if ((ret = ff_get_buffer(avctx, ac->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 5fcdfc01949545754a014363559eeef7c852a068..bce27c0e10e08c863683b88cbc32fa2f0626e93f 100644 (file)
 #include <string.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "msrledec.h"
 
 typedef struct AascContext {
     AVCodecContext *avctx;
     GetByteContext gb;
-    AVFrame frame;
+    AVFrame *frame;
 } AascContext;
 
 static av_cold int aasc_decode_init(AVCodecContext *avctx)
@@ -45,6 +46,10 @@ static av_cold int aasc_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -57,9 +62,7 @@ static int aasc_decode_frame(AVCodecContext *avctx,
     AascContext *s     = avctx->priv_data;
     int compr, i, stride, ret;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -71,13 +74,13 @@ static int aasc_decode_frame(AVCodecContext *avctx,
     case 0:
         stride = (avctx->width * 3 + 3) & ~3;
         for (i = avctx->height - 1; i >= 0; i--) {
-            memcpy(s->frame.data[0] + i * s->frame.linesize[0], buf, avctx->width * 3);
+            memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * 3);
             buf += stride;
         }
         break;
     case 1:
         bytestream2_init(&s->gb, buf, buf_size);
-        ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb);
+        ff_msrle_decode(avctx, (AVPicture*)s->frame, 8, &s->gb);
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr);
@@ -85,7 +88,8 @@ static int aasc_decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -95,9 +99,7 @@ static av_cold int aasc_decode_end(AVCodecContext *avctx)
 {
     AascContext *s = avctx->priv_data;
 
-    /* release the last frame */
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
index f8f058477f4a6636909d7450c0b6dd380ba301c6..407940d19da6a90ae47ec9179197bd1105ac810e 100644 (file)
@@ -1371,7 +1371,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = s->num_blocks * 256;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index becb480c403955fdb8b0efc1a5756ec7b70ad9f8..3e93bee20e10ba7fe5c221c670fc247a92b61b99 100644 (file)
@@ -609,7 +609,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = nb_samples;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index ea409931246598dd71eabce15d059d02fecc65e8..52216867cc31a38be27ce1320ba05a2fa04e0bf0 100644 (file)
@@ -141,7 +141,7 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = num_blocks * BLOCK_SAMPLES;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 0c5bdd3e4513c4b59e9c1f24df6842d7f4732bc3..ddf78d91081412943697407008b02bd8b4a0817b 100644 (file)
@@ -283,7 +283,7 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index,
     if (!alac->nb_samples) {
         /* get output buffer */
         frame->nb_samples = output_samples;
-        if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
index 622522aaa6add2547ce6d9e424a292890d9129cf..f87c94425bef1e9af8b1414f13974051f97341fd 100644 (file)
@@ -1462,7 +1462,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
 
     /* get output buffer */
     frame->nb_samples = ctx->cur_frame_length;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 237d47b7cbc446dcd54472b20623f084e83ba1d1..20c1896ec3fb17ba5e34ff528f9df7a366694f3e 100644 (file)
@@ -945,7 +945,7 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = AMR_BLOCK_SIZE;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index cf137e046aa82cc27e3ad312b3faeee1d5f98cb3..354b039025166d78b9a17f6fb58782f809c5d45a 100644 (file)
@@ -1092,7 +1092,7 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 4 * AMRWB_SFR_SIZE_16k;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index af148a6fd0f452ba18339cf1c17e159babfdc4e2..9f1cc397f97d5de1b1cc6d927ae1dec70d51f867 100644 (file)
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct AnmContext {
-    AVFrame frame;
+    AVFrame *frame;
     int palette[AVPALETTE_COUNT];
     GetByteContext gb;
     int x;  ///< x coordinate position
@@ -41,7 +42,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    s->frame.reference = 1;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
     if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256)
         return AVERROR_INVALIDDATA;
@@ -113,12 +117,12 @@ static int decode_frame(AVCodecContext *avctx,
     uint8_t *dst, *dst_end;
     int count, ret;
 
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0){
+    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    dst     = s->frame.data[0];
-    dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height;
+    dst     = s->frame->data[0];
+    dst_end = s->frame->data[0] + s->frame->linesize[0]*avctx->height;
 
     bytestream2_init(&s->gb, avpkt->data, buf_size);
 
@@ -136,7 +140,7 @@ static int decode_frame(AVCodecContext *avctx,
     do {
         /* if statements are ordered by probability */
 #define OP(gb, pixel, count) \
-    op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])
+    op(&dst, dst_end, (gb), (pixel), (count), &s->x, avctx->width, s->frame->linesize[0])
 
         int type = bytestream2_get_byte(&s->gb);
         count = type & 0x7F;
@@ -168,18 +172,20 @@ static int decode_frame(AVCodecContext *avctx,
         }
     } while (bytestream2_get_bytes_left(&s->gb) > 0);
 
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     return buf_size;
 }
 
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     AnmContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+
+    av_frame_free(&s->frame);
     return 0;
 }
 
index 0b2e93d74bd29cba5196bc38b7a40289df12367a..b99826b3a5cd20fc302425ed15d01bdfbb88ca95 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "libavutil/common.h"
+#include "libavutil/frame.h"
 #include "libavutil/lfg.h"
 #include "avcodec.h"
 #include "cga_data.h"
@@ -49,7 +50,7 @@ static const uint8_t ansi_to_cga[16] = {
 };
 
 typedef struct {
-    AVFrame frame;
+    AVFrame *frame;
     int x;                /**< x cursor position (pixels) */
     int y;                /**< y cursor position (pixels) */
     int sx;               /**< saved x cursor position (pixels) */
@@ -77,6 +78,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
     AnsiContext *s = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     /* defaults */
     s->font        = ff_vga16_font;
     s->font_height = 16;
@@ -101,11 +106,11 @@ static void hscroll(AVCodecContext *avctx)
 
     i = 0;
     for (; i < avctx->height - s->font_height; i++)
-        memcpy(s->frame.data[0] + i * s->frame.linesize[0],
-               s->frame.data[0] + (i + s->font_height) * s->frame.linesize[0],
+        memcpy(s->frame->data[0] + i * s->frame->linesize[0],
+               s->frame->data[0] + (i + s->font_height) * s->frame->linesize[0],
                avctx->width);
     for (; i < avctx->height; i++)
-        memset(s->frame.data[0] + i * s->frame.linesize[0],
+        memset(s->frame->data[0] + i * s->frame->linesize[0],
             DEFAULT_BG_COLOR, avctx->width);
 }
 
@@ -114,7 +119,7 @@ static void erase_line(AVCodecContext * avctx, int xoffset, int xlength)
     AnsiContext *s = avctx->priv_data;
     int i;
     for (i = 0; i < s->font_height; i++)
-        memset(s->frame.data[0] + (s->y + i)*s->frame.linesize[0] + xoffset,
+        memset(s->frame->data[0] + (s->y + i)*s->frame->linesize[0] + xoffset,
             DEFAULT_BG_COLOR, xlength);
 }
 
@@ -123,7 +128,7 @@ static void erase_screen(AVCodecContext *avctx)
     AnsiContext *s = avctx->priv_data;
     int i;
     for (i = 0; i < avctx->height; i++)
-        memset(s->frame.data[0] + i * s->frame.linesize[0], DEFAULT_BG_COLOR, avctx->width);
+        memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width);
     s->x = s->y = 0;
 }
 
@@ -144,8 +149,8 @@ static void draw_char(AVCodecContext *avctx, int c)
         FFSWAP(int, fg, bg);
     if ((s->attributes & ATTR_CONCEALED))
         fg = bg;
-    ff_draw_pc_font(s->frame.data[0] + s->y * s->frame.linesize[0] + s->x,
-                    s->frame.linesize[0], s->font, s->font_height, c, fg, bg);
+    ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
+                    s->frame->linesize[0], s->font, s->font_height, c, fg, bg);
     s->x += FONT_WIDTH;
     if (s->x >= avctx->width) {
         s->x = 0;
@@ -220,17 +225,16 @@ static int execute_code(AVCodecContext * avctx, int c)
             av_log_ask_for_sample(avctx, "unsupported screen mode\n");
         }
         if (width != avctx->width || height != avctx->height) {
-            if (s->frame.data[0])
-                avctx->release_buffer(avctx, &s->frame);
+            av_frame_unref(s->frame);
             avcodec_set_dimensions(avctx, width, height);
-            ret = ff_get_buffer(avctx, &s->frame);
+            ret = ff_get_buffer(avctx, s->frame, AV_GET_BUFFER_FLAG_REF);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return ret;
             }
-            s->frame.pict_type           = AV_PICTURE_TYPE_I;
-            s->frame.palette_has_changed = 1;
-            memcpy(s->frame.data[1], ff_cga_palette, 16 * 4);
+            s->frame->pict_type           = AV_PICTURE_TYPE_I;
+            s->frame->palette_has_changed = 1;
+            memcpy(s->frame->data[1], ff_cga_palette, 16 * 4);
             erase_screen(avctx);
         } else if (c == 'l') {
             erase_screen(avctx);
@@ -241,13 +245,13 @@ static int execute_code(AVCodecContext * avctx, int c)
         case 0:
             erase_line(avctx, s->x, avctx->width - s->x);
             if (s->y < avctx->height - s->font_height)
-                memset(s->frame.data[0] + (s->y + s->font_height)*s->frame.linesize[0],
-                    DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame.linesize[0]);
+                memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0],
+                    DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]);
             break;
         case 1:
             erase_line(avctx, 0, s->x);
             if (s->y > 0)
-                memset(s->frame.data[0], DEFAULT_BG_COLOR, s->y * s->frame.linesize[0]);
+                memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]);
             break;
         case 2:
             erase_screen(avctx);
@@ -320,19 +324,19 @@ static int decode_frame(AVCodecContext *avctx,
     const uint8_t *buf_end   = buf+buf_size;
     int ret, i, count;
 
-    ret = avctx->reget_buffer(avctx, &s->frame);
+    ret = ff_reget_buffer(avctx, s->frame);
     if (ret < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
     if (!avctx->frame_number) {
-        memset(s->frame.data[0], 0, avctx->height * FFABS(s->frame.linesize[0]));
-        memset(s->frame.data[1], 0, AVPALETTE_SIZE);
+        memset(s->frame->data[0], 0, avctx->height * FFABS(s->frame->linesize[0]));
+        memset(s->frame->data[1], 0, AVPALETTE_SIZE);
     }
 
-    s->frame.pict_type           = AV_PICTURE_TYPE_I;
-    s->frame.palette_has_changed = 1;
-    memcpy(s->frame.data[1], ff_cga_palette, 16 * 4);
+    s->frame->pict_type           = AV_PICTURE_TYPE_I;
+    s->frame->palette_has_changed = 1;
+    memcpy(s->frame->data[1], ff_cga_palette, 16 * 4);
 
     while(buf < buf_end) {
         switch(s->state) {
@@ -416,15 +420,16 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
     return buf_size;
 }
 
 static av_cold int decode_close(AVCodecContext *avctx)
 {
     AnsiContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+
+    av_frame_free(&s->frame);
     return 0;
 }
 
index f3635836d0ce3f4679dfbe934e2594158106686b..60227a04e9cad65625f43a8b2943b41caf8da5eb 100644 (file)
@@ -907,7 +907,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = blockstodecode;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index a3adde9356dbedd908376bf90ed8dc944684e152..a1246877a76e82874279c414694d53307f9cee75 100644 (file)
@@ -183,14 +183,14 @@ static inline int decode_mb(ASV1Context *a, int16_t block[6][64])
     return 0;
 }
 
-static inline void idct_put(ASV1Context *a, int mb_x, int mb_y)
+static inline void idct_put(ASV1Context *a, AVFrame *frame, int mb_x, int mb_y)
 {
     int16_t (*block)[64] = a->block;
-    int linesize         = a->picture.linesize[0];
+    int linesize         = frame->linesize[0];
 
-    uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
-    uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
 
     a->dsp.idct_put(dest_y                 , linesize, block[0]);
     a->dsp.idct_put(dest_y              + 8, linesize, block[1]);
@@ -198,8 +198,8 @@ static inline void idct_put(ASV1Context *a, int mb_x, int mb_y)
     a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
 
     if (!(a->avctx->flags&CODEC_FLAG_GRAY)) {
-        a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
-        a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
+        a->dsp.idct_put(dest_cb, frame->linesize[1], block[4]);
+        a->dsp.idct_put(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
@@ -210,15 +210,10 @@ static int decode_frame(AVCodecContext *avctx,
     ASV1Context * const a = avctx->priv_data;
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
-    AVFrame *picture      = data;
-    AVFrame * const p     = &a->picture;
+    AVFrame * const p     = data;
     int mb_x, mb_y, ret;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -245,7 +240,7 @@ static int decode_frame(AVCodecContext *avctx,
             if ((ret = decode_mb(a, a->block)) < 0)
                 return ret;
 
-            idct_put(a, mb_x, mb_y);
+            idct_put(a, p, mb_x, mb_y);
         }
     }
 
@@ -255,7 +250,7 @@ static int decode_frame(AVCodecContext *avctx,
             if ((ret = decode_mb(a, a->block)) < 0)
                 return ret;
 
-            idct_put(a, mb_x, mb_y);
+            idct_put(a, p, mb_x, mb_y);
         }
     }
 
@@ -265,11 +260,10 @@ static int decode_frame(AVCodecContext *avctx,
             if ((ret = decode_mb(a, a->block)) < 0)
                 return ret;
 
-            idct_put(a, mb_x, mb_y);
+            idct_put(a, p, mb_x, mb_y);
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     emms_c();
@@ -280,7 +274,6 @@ static int decode_frame(AVCodecContext *avctx,
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     ASV1Context * const a = avctx->priv_data;
-    AVFrame *p            = &a->picture;
     const int scale       = avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2;
     int i;
 
@@ -304,11 +297,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
         a->intra_matrix[i] = 64 * scale * ff_mpeg1_default_intra_matrix[index] / a->inv_qscale;
     }
 
-    p->qstride      = a->mb_width;
-    p->qscale_table = av_malloc(p->qstride * a->mb_height);
-    p->quality      = (32 * scale + a->inv_qscale / 2) / a->inv_qscale;
-    memset(p->qscale_table, p->quality, p->qstride * a->mb_height);
-
     return 0;
 }
 
@@ -317,12 +305,8 @@ static av_cold int decode_end(AVCodecContext *avctx)
     ASV1Context * const a = avctx->priv_data;
 
     av_freep(&a->bitstream_buffer);
-    av_freep(&a->picture.qscale_table);
     a->bitstream_buffer_size = 0;
 
-    if (a->picture.data[0])
-        avctx->release_buffer(avctx, &a->picture);
-
     return 0;
 }
 
index 9c265464fe03d8771546daa1615a254b155fe8a3..c829898ddb5e4593401cf01bea4385b94a483992 100644 (file)
@@ -287,7 +287,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = AT1_SU_SAMPLES;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 0474268f465b1cc88959ece3b7a7e35996d4f3b4..6b4165780c11b8a8c428aec54d34c1ddb21524df 100644 (file)
@@ -812,7 +812,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = SAMPLES_PER_FRAME;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 7256dc82747c15060e4612c8e238b7cc9a4cffc5..b51aedeccf12ae4a38fad2a79213dc6af85c7f82 100644 (file)
 #include "internal.h"
 #include "libavutil/internal.h"
 
-typedef struct AuraDecodeContext {
-    AVCodecContext *avctx;
-    AVFrame frame;
-} AuraDecodeContext;
-
 static av_cold int aura_decode_init(AVCodecContext *avctx)
 {
-    AuraDecodeContext *s = avctx->priv_data;
-
-    s->avctx = avctx;
     /* width needs to be divisible by 4 for this codec to work */
     if (avctx->width & 0x3)
         return AVERROR(EINVAL);
@@ -49,7 +41,7 @@ static int aura_decode_frame(AVCodecContext *avctx,
                              void *data, int *got_frame,
                              AVPacket *pkt)
 {
-    AuraDecodeContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     uint8_t *Y, *U, *V;
     uint8_t val;
     int x, y, ret;
@@ -67,19 +59,14 @@ static int aura_decode_frame(AVCodecContext *avctx,
     /* pixel data starts 48 bytes in, after 3x16-byte tables */
     buf += 48;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-    s->frame.reference = 0;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    Y = s->frame.data[0];
-    U = s->frame.data[1];
-    V = s->frame.data[2];
+    Y = frame->data[0];
+    U = frame->data[1];
+    V = frame->data[2];
 
     /* iterate through each line in the height */
     for (y = 0; y < avctx->height; y++) {
@@ -102,34 +89,21 @@ static int aura_decode_frame(AVCodecContext *avctx,
             Y[1] = Y[ 0] + delta_table[val & 0xF];
             Y   += 2; U++; V++;
         }
-        Y += s->frame.linesize[0] -  avctx->width;
-        U += s->frame.linesize[1] - (avctx->width >> 1);
-        V += s->frame.linesize[2] - (avctx->width >> 1);
+        Y += frame->linesize[0] -  avctx->width;
+        U += frame->linesize[1] - (avctx->width >> 1);
+        V += frame->linesize[2] - (avctx->width >> 1);
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return pkt->size;
 }
 
-static av_cold int aura_decode_end(AVCodecContext *avctx)
-{
-    AuraDecodeContext *s = avctx->priv_data;
-
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    return 0;
-}
-
 AVCodec ff_aura2_decoder = {
     .name           = "aura2",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AURA2,
-    .priv_data_size = sizeof(AuraDecodeContext),
     .init           = aura_decode_init,
-    .close          = aura_decode_end,
     .decode         = aura_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Auravision Aura 2"),
index 33f37e5e2f2cde2223ea1da63c3bf247cdf5acad..b3bdb61bbd7cf2a7f91f3ed29eda57045e52743b 100644 (file)
@@ -823,6 +823,7 @@ typedef struct AVPanScan{
 #define FF_QSCALE_TYPE_H264  2
 #define FF_QSCALE_TYPE_VP56  3
 
+#if FF_API_GET_BUFFER
 #define FF_BUFFER_TYPE_INTERNAL 1
 #define FF_BUFFER_TYPE_USER     2 ///< direct rendering buffers (image is (de)allocated by user)
 #define FF_BUFFER_TYPE_SHARED   4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
@@ -832,6 +833,12 @@ typedef struct AVPanScan{
 #define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
 #define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
 #define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
+#endif
+
+/**
+ * The decoder will keep a reference to the frame and may reuse it later.
+ */
+#define AV_GET_BUFFER_FLAG_REF (1 << 0)
 
 /**
  * @defgroup lavc_packet AVPacket
@@ -1859,6 +1866,7 @@ typedef struct AVCodecContext {
      */
     enum AVSampleFormat request_sample_fmt;
 
+#if FF_API_GET_BUFFER
     /**
      * Called at the beginning of each frame to get a buffer for it.
      *
@@ -1918,7 +1926,10 @@ typedef struct AVCodecContext {
      *
      * - encoding: unused
      * - decoding: Set by libavcodec, user can override.
+     *
+     * @deprecated use get_buffer2()
      */
+    attribute_deprecated
     int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
 
     /**
@@ -1929,7 +1940,10 @@ typedef struct AVCodecContext {
      * but not by more than one thread at once, so does not need to be reentrant.
      * - encoding: unused
      * - decoding: Set by libavcodec, user can override.
+     *
+     * @deprecated custom freeing callbacks should be set from get_buffer2()
      */
+    attribute_deprecated
     void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
 
     /**
@@ -1944,8 +1958,100 @@ typedef struct AVCodecContext {
      * - encoding: unused
      * - decoding: Set by libavcodec, user can override.
      */
+    attribute_deprecated
     int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
+#endif
 
+    /**
+     * This callback is called at the beginning of each frame to get data
+     * buffer(s) for it. There may be one contiguous buffer for all the data or
+     * there may be a buffer per each data plane or anything in between. Each
+     * buffer must be reference-counted using the AVBuffer API.
+     *
+     * The following fields will be set in the frame before this callback is
+     * called:
+     * - format
+     * - width, height (video only)
+     * - sample_rate, channel_layout, nb_samples (audio only)
+     * Their values may differ from the corresponding values in
+     * AVCodecContext. This callback must use the frame values, not the codec
+     * context values, to calculate the required buffer size.
+     *
+     * This callback must fill the following fields in the frame:
+     * - data[]
+     * - linesize[]
+     * - extended_data:
+     *   * if the data is planar audio with more than 8 channels, then this
+     *     callback must allocate and fill extended_data to contain all pointers
+     *     to all data planes. data[] must hold as many pointers as it can.
+     *     extended_data must be allocated with av_malloc() and will be freed in
+     *     av_frame_unref().
+     *   * otherwise exended_data must point to data
+     * - buf[] must contain references to the buffers that contain the frame
+     *   data.
+     * - extended_buf and nb_extended_buf must be allocated with av_malloc() by
+     *   this callback and filled with the extra buffers if there are more
+     *   buffers than buf[] can hold. extended_buf will be freed in
+     *   av_frame_unref().
+     *
+     * If CODEC_CAP_DR1 is not set then get_buffer2() must call
+     * avcodec_default_get_buffer2() instead of providing buffers allocated by
+     * some other means.
+     *
+     * Each data plane must be aligned to the maximum required by the target
+     * CPU.
+     *
+     * @see avcodec_default_get_buffer2()
+     *
+     * Video:
+     *
+     * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused
+     * (read and/or written to if it is writable) later by libavcodec.
+     *
+     * If CODEC_FLAG_EMU_EDGE is not set in s->flags, the buffer must contain an
+     * edge of the size returned by avcodec_get_edge_width() on all sides.
+     *
+     * avcodec_align_dimensions2() should be used to find the required width and
+     * height, as they normally need to be rounded up to the next multiple of 16.
+     *
+     * If frame multithreading is used and thread_safe_callbacks is set,
+     * this callback may be called from a different thread, but not from more
+     * than one at once. Does not need to be reentrant.
+     *
+     * @see avcodec_align_dimensions2()
+     *
+     * Audio:
+     *
+     * Decoders request a buffer of a particular size by setting
+     * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may,
+     * however, utilize only part of the buffer by setting AVFrame.nb_samples
+     * to a smaller value in the output frame.
+     *
+     * As a convenience, av_samples_get_buffer_size() and
+     * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2()
+     * functions to find the required data size and to fill data pointers and
+     * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
+     * since all planes must be the same size.
+     *
+     * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
+     *
+     * - encoding: unused
+     * - decoding: Set by libavcodec, user can override.
+     */
+    int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
+
+    /**
+     * If non-zero, the decoded audio and video frames returned from
+     * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted
+     * and are valid indefinitely. The caller must free them with
+     * av_frame_unref() when they are not needed anymore.
+     * Otherwise, the decoded frames must not be freed by the caller and are
+     * only valid until the next decode call.
+     *
+     * - encoding: unused
+     * - decoding: set by the caller before avcodec_open2().
+     */
+    int refcounted_frames;
 
     /* - encoding parameters */
     float qcompress;  ///< amount of qscale change between easy & hard scenes (0.0-1.0)
@@ -3209,9 +3315,18 @@ AVCodec *avcodec_find_decoder(enum AVCodecID id);
  */
 AVCodec *avcodec_find_decoder_by_name(const char *name);
 
-int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
-void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
-int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+#if FF_API_GET_BUFFER
+attribute_deprecated int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
+attribute_deprecated void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
+attribute_deprecated int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+#endif
+
+/**
+ * The default callback for AVCodecContext.get_buffer2(). It is made public so
+ * it can be called by custom get_buffer2() implementations for decoders without
+ * CODEC_CAP_DR1 set.
+ */
+int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags);
 
 /**
  * Return the amount of padding in pixels which the get_buffer callback must
@@ -4147,8 +4262,6 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
  */
 void avcodec_flush_buffers(AVCodecContext *avctx);
 
-void avcodec_default_free_buffers(AVCodecContext *s);
-
 /**
  * Return codec bits per sample.
  *
index 71b8b0c2837224528c5765c954b78d8683e369ba..45cb4484d6a8316f4395ddde4a5d37d78841cddf 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 
 
 typedef struct {
@@ -59,11 +60,10 @@ avs_decode_frame(AVCodecContext * avctx,
     AvsBlockType type;
     GetBitContext change_map;
 
-    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
-    p->reference = 1;
     p->pict_type = AV_PICTURE_TYPE_P;
     p->key_frame = 0;
 
@@ -149,7 +149,8 @@ avs_decode_frame(AVCodecContext * avctx,
             align_get_bits(&change_map);
     }
 
-    *picture   = avs->picture;
+    if ((ret = av_frame_ref(picture, &avs->picture)) < 0)
+        return ret;
     *got_frame = 1;
 
     return buf_size;
@@ -165,8 +166,7 @@ static av_cold int avs_decode_init(AVCodecContext * avctx)
 static av_cold int avs_decode_end(AVCodecContext *avctx)
 {
     AvsContext *s = avctx->priv_data;
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
+    av_frame_unref(&s->picture);
     return 0;
 }
 
index d0b34fdbe4287b8abd87f8d0e27ce2ff6de4205a..73145701ff6c082d211b2bb316022918064f3b66 100644 (file)
@@ -31,6 +31,7 @@
 #include "avcodec.h"
 #include "bethsoftvideo.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct BethsoftvidContext {
     AVFrame frame;
@@ -40,9 +41,6 @@ typedef struct BethsoftvidContext {
 static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
 {
     BethsoftvidContext *vid = avctx->priv_data;
-    vid->frame.reference = 1;
-    vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
-        FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     return 0;
 }
@@ -75,7 +73,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
     int code, ret;
     int yoffset;
 
-    if ((ret = avctx->reget_buffer(avctx, &vid->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &vid->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -136,8 +134,10 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
     }
     end:
 
+    if ((ret = av_frame_ref(data, &vid->frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = vid->frame;
 
     return avpkt->size;
 }
@@ -145,8 +145,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx,
 static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx)
 {
     BethsoftvidContext * vid = avctx->priv_data;
-    if(vid->frame.data[0])
-        avctx->release_buffer(avctx, &vid->frame);
+    av_frame_unref(&vid->frame);
     return 0;
 }
 
index 1971c0c8554ad8e206a993422932c44cd9437828..10544c5569f4362f6d530bf70b0ae9bac7945110 100644 (file)
@@ -33,7 +33,6 @@
 
 typedef struct BFIContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     uint8_t *dst;
 } BFIContext;
 
@@ -48,6 +47,7 @@ static av_cold int bfi_decode_init(AVCodecContext *avctx)
 static int bfi_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     GetByteContext g;
     int buf_size    = avpkt->size;
     BFIContext *bfi = avctx->priv_data;
@@ -57,12 +57,7 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
     uint32_t *pal;
     int i, j, ret, height = avctx->height;
 
-    if (bfi->frame.data[0])
-        avctx->release_buffer(avctx, &bfi->frame);
-
-    bfi->frame.reference = 1;
-
-    if ((ret = ff_get_buffer(avctx, &bfi->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -71,14 +66,14 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
 
     /* Set frame parameters and palette, if necessary */
     if (!avctx->frame_number) {
-        bfi->frame.pict_type = AV_PICTURE_TYPE_I;
-        bfi->frame.key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
         /* Setting the palette */
         if (avctx->extradata_size > 768) {
             av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n");
             return AVERROR_INVALIDDATA;
         }
-        pal = (uint32_t *)bfi->frame.data[1];
+        pal = (uint32_t *)frame->data[1];
         for (i = 0; i < avctx->extradata_size / 3; i++) {
             int shift = 16;
             *pal = 0;
@@ -87,10 +82,10 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
                          (avctx->extradata[i * 3 + j] >> 4)) << shift;
             pal++;
         }
-        bfi->frame.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
     } else {
-        bfi->frame.pict_type = AV_PICTURE_TYPE_P;
-        bfi->frame.key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
     }
 
     bytestream2_skip(&g, 4); // Unpacked size, not required.
@@ -158,22 +153,20 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     src = bfi->dst;
-    dst = bfi->frame.data[0];
+    dst = frame->data[0];
     while (height--) {
         memcpy(dst, src, avctx->width);
         src += avctx->width;
-        dst += bfi->frame.linesize[0];
+        dst += frame->linesize[0];
     }
     *got_frame = 1;
-    *(AVFrame *)data = bfi->frame;
+
     return buf_size;
 }
 
 static av_cold int bfi_decode_close(AVCodecContext *avctx)
 {
     BFIContext *bfi = avctx->priv_data;
-    if (bfi->frame.data[0])
-        avctx->release_buffer(avctx, &bfi->frame);
     av_free(bfi->dst);
     return 0;
 }
index 033e9bf0a1f2c21a45c9698de00f7ab0640dce1d..22e13c33dd8d3759432a2b272a5ec78752b49e93 100644 (file)
@@ -113,7 +113,7 @@ typedef struct BinkContext {
     AVCodecContext *avctx;
     DSPContext     dsp;
     BinkDSPContext bdsp;
-    AVFrame        *pic, *last;
+    AVFrame        *last;
     int            version;              ///< internal Bink file version
     int            has_alpha;
     int            swap_planes;
@@ -792,8 +792,8 @@ static inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stri
         memcpy(dst + i*stride, tmp + i*8, 8);
 }
 
-static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
-                              int is_key, int is_chroma)
+static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
+                              int plane_idx, int is_key, int is_chroma)
 {
     int blk, ret;
     int i, j, bx, by;
@@ -807,13 +807,13 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
     int ybias = is_key ? -15 : 0;
     int qp;
 
-    const int stride = c->pic->linesize[plane_idx];
+    const int stride = frame->linesize[plane_idx];
     int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;
     int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
 
     binkb_init_bundles(c);
-    ref_start = c->pic->data[plane_idx];
-    ref_end   = c->pic->data[plane_idx] + (bh * c->pic->linesize[plane_idx] + bw) * 8;
+    ref_start = frame->data[plane_idx];
+    ref_end   = frame->data[plane_idx] + (bh * frame->linesize[plane_idx] + bw) * 8;
 
     for (i = 0; i < 64; i++)
         coordmap[i] = (i & 7) + (i >> 3) * stride;
@@ -824,7 +824,7 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
                 return ret;
         }
 
-        dst  = c->pic->data[plane_idx]  + 8*by*stride;
+        dst  = frame->data[plane_idx]  + 8*by*stride;
         for (bx = 0; bx < bw; bx++, dst += 8) {
             blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES);
             switch (blk) {
@@ -938,8 +938,8 @@ static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
     return 0;
 }
 
-static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
-                             int is_chroma)
+static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb,
+                             int plane_idx, int is_chroma)
 {
     int blk, ret;
     int i, j, bx, by;
@@ -952,7 +952,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
     LOCAL_ALIGNED_16(int32_t, dctblock, [64]);
     int coordmap[64];
 
-    const int stride = c->pic->linesize[plane_idx];
+    const int stride = frame->linesize[plane_idx];
     int bw = is_chroma ? (c->avctx->width  + 15) >> 4 : (c->avctx->width  + 7) >> 3;
     int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3;
     int width = c->avctx->width >> is_chroma;
@@ -962,7 +962,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
         read_bundle(gb, c, i);
 
     ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx]
-                                        : c->pic->data[plane_idx];
+                                         : frame->data[plane_idx];
     ref_end   = ref_start
                 + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8;
 
@@ -991,9 +991,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
 
         if (by == bh)
             break;
-        dst  = c->pic->data[plane_idx]  + 8*by*stride;
+        dst  = frame->data[plane_idx]  + 8*by*stride;
         prev = (c->last->data[plane_idx] ? c->last->data[plane_idx]
-                                         : c->pic->data[plane_idx]) + 8*by*stride;
+                                         : frame->data[plane_idx]) + 8*by*stride;
         for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) {
             blk = get_value(c, BINK_SRC_BLOCK_TYPES);
             // 16x16 block type on odd line means part of the already decoded block, so skip it
@@ -1165,30 +1165,30 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx,
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
 {
     BinkContext * const c = avctx->priv_data;
+    AVFrame *frame = data;
     GetBitContext gb;
     int plane, plane_idx, ret;
     int bits_count = pkt->size << 3;
 
     if (c->version > 'b') {
-        if(c->pic->data[0])
-            avctx->release_buffer(avctx, c->pic);
-
-        if ((ret = ff_get_buffer(avctx, c->pic)) < 0) {
+        if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
     } else {
-        if ((ret = avctx->reget_buffer(avctx, c->pic)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, c->last)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
+        if ((ret = av_frame_ref(frame, c->last)) < 0)
+            return ret;
     }
 
     init_get_bits(&gb, pkt->data, bits_count);
     if (c->has_alpha) {
         if (c->version >= 'i')
             skip_bits_long(&gb, 32);
-        if ((ret = bink_decode_plane(c, &gb, 3, 0)) < 0)
+        if ((ret = bink_decode_plane(c, frame, &gb, 3, 0)) < 0)
             return ret;
     }
     if (c->version >= 'i')
@@ -1198,10 +1198,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3);
 
         if (c->version > 'b') {
-            if ((ret = bink_decode_plane(c, &gb, plane_idx, !!plane)) < 0)
+            if ((ret = bink_decode_plane(c, frame, &gb, plane_idx, !!plane)) < 0)
                 return ret;
         } else {
-            if ((ret = binkb_decode_plane(c, &gb, plane_idx,
+            if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx,
                                           !avctx->frame_number, !!plane)) < 0)
                 return ret;
         }
@@ -1210,11 +1210,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     }
     emms_c();
 
-    *got_frame = 1;
-    *(AVFrame*)data = *c->pic;
+    if (c->version > 'b') {
+        av_frame_unref(c->last);
+        if ((ret = av_frame_ref(c->last, frame)) < 0)
+            return ret;
+    }
 
-    if (c->version > 'b')
-        FFSWAP(AVFrame*, c->pic, c->last);
+    *got_frame = 1;
 
     /* always report that the buffer was completely consumed */
     return pkt->size;
@@ -1293,13 +1295,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
     }
     c->avctx = avctx;
 
-    c->pic  = avcodec_alloc_frame();
-    c->last = avcodec_alloc_frame();
-    if (!c->pic || !c->last) {
-        avcodec_free_frame(&c->pic);
-        avcodec_free_frame(&c->last);
+    c->last = av_frame_alloc();
+    if (!c->last)
         return AVERROR(ENOMEM);
-    }
 
     if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
         return ret;
@@ -1325,12 +1323,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     BinkContext * const c = avctx->priv_data;
 
-    if (c->pic->data[0])
-        avctx->release_buffer(avctx, c->pic);
-    if (c->last->data[0])
-        avctx->release_buffer(avctx, c->last);
-    avcodec_free_frame(&c->pic);
-    avcodec_free_frame(&c->last);
+    av_frame_free(&c->last);
 
     free_bundles(c);
     return 0;
index dea1ffae5037885d9354884693135dc93c2bff86..1e34ab95fdcf7018ee34a5df93844c5cd3b6b26e 100644 (file)
@@ -318,7 +318,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = s->frame_len;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 5ca73baa4f0fbdb70f3c392674aaf66707bb28a9..899fc8a1dca8fb6a57620be8ad371a73f1991b78 100644 (file)
 #include "internal.h"
 #include "msrledec.h"
 
-static av_cold int bmp_decode_init(AVCodecContext *avctx)
-{
-    BMPContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
 static int bmp_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    BMPContext *s      = avctx->priv_data;
-    AVFrame *picture   = data;
-    AVFrame *p         = &s->picture;
+    AVFrame *p         = data;
     unsigned int fsize, hsize;
     int width, height;
     unsigned int depth;
@@ -205,11 +193,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -350,29 +334,15 @@ static int bmp_decode_frame(AVCodecContext *avctx,
         }
     }
 
-    *picture = s->picture;
     *got_frame = 1;
 
     return buf_size;
 }
 
-static av_cold int bmp_decode_end(AVCodecContext *avctx)
-{
-    BMPContext* c = avctx->priv_data;
-
-    if (c->picture.data[0])
-        avctx->release_buffer(avctx, &c->picture);
-
-    return 0;
-}
-
 AVCodec ff_bmp_decoder = {
     .name           = "bmp",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BMP,
-    .priv_data_size = sizeof(BMPContext),
-    .init           = bmp_decode_init,
-    .close          = bmp_decode_end,
     .decode         = bmp_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"),
index 75c550f3f5406b3707f08db3b0bf50220a230f3e..b6b685b5569fa27ebb2ac12922832aa7c78ee43f 100644 (file)
@@ -43,7 +43,6 @@ enum BMVFlags{
 
 typedef struct BMVDecContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     uint8_t *frame, frame_base[SCREEN_WIDE * (SCREEN_HIGH + 1)];
     uint32_t pal[256];
@@ -198,6 +197,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *pkt)
 {
     BMVDecContext * const c = avctx->priv_data;
+    AVFrame *frame = data;
     int type, scr_off;
     int i, ret;
     uint8_t *srcptr, *outptr;
@@ -240,11 +240,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         scr_off = 0;
     }
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 3;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -254,20 +250,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
-    c->pic.palette_has_changed = type & BMV_PALETTE;
+    memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
+    frame->palette_has_changed = type & BMV_PALETTE;
 
-    outptr = c->pic.data[0];
+    outptr = frame->data[0];
     srcptr = c->frame;
 
     for (i = 0; i < avctx->height; i++) {
         memcpy(outptr, srcptr, avctx->width);
         srcptr += avctx->width;
-        outptr += c->pic.linesize[0];
+        outptr += frame->linesize[0];
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return pkt->size;
@@ -285,16 +280,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    BMVDecContext *c = avctx->priv_data;
-
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    return 0;
-}
-
 static const int bmv_aud_mults[16] = {
     16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32
 };
@@ -328,7 +313,7 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = total_blocks * 32;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -356,7 +341,6 @@ AVCodec ff_bmv_video_decoder = {
     .id             = AV_CODEC_ID_BMV_VIDEO,
     .priv_data_size = sizeof(BMVDecContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
index b7205855bb3089dcf584a4b7d7f49e2a96157d75..750941e02142d3975c93de4767840e437ea90044 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct {
     AVFrame pictures[2];
@@ -55,10 +56,9 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     C93DecoderContext * const c93 = avctx->priv_data;
 
-    if (c93->pictures[0].data[0])
-        avctx->release_buffer(avctx, &c93->pictures[0]);
-    if (c93->pictures[1].data[0])
-        avctx->release_buffer(avctx, &c93->pictures[1]);
+    av_frame_unref(&c93->pictures[0]);
+    av_frame_unref(&c93->pictures[1]);
+
     return 0;
 }
 
@@ -120,17 +120,13 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     C93DecoderContext * const c93 = avctx->priv_data;
     AVFrame * const newpic = &c93->pictures[c93->currentpic];
     AVFrame * const oldpic = &c93->pictures[c93->currentpic^1];
-    AVFrame *picture = data;
     GetByteContext gb;
     uint8_t *out;
     int stride, ret, i, x, y, b, bt = 0;
 
     c93->currentpic ^= 1;
 
-    newpic->reference = 1;
-    newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                         FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    if ((ret = avctx->reget_buffer(avctx, newpic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, newpic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -239,7 +235,8 @@ static int decode_frame(AVCodecContext *avctx, void *data,
             memcpy(newpic->data[1], oldpic->data[1], 256 * 4);
     }
 
-    *picture = *newpic;
+    if ((ret = av_frame_ref(data, newpic)) < 0)
+        return ret;
     *got_frame = 1;
 
     return buf_size;
index e6315bc29183c1c9709647daa57e2ae5458bdb6c..abd4bacddad8898b202cb054812e88a3023508aa 100644 (file)
@@ -736,9 +736,9 @@ av_cold int ff_cavs_init(AVCodecContext *avctx) {
     h->avctx = avctx;
     avctx->pix_fmt= AV_PIX_FMT_YUV420P;
 
-    h->cur.f    = avcodec_alloc_frame();
-    h->DPB[0].f = avcodec_alloc_frame();
-    h->DPB[1].f = avcodec_alloc_frame();
+    h->cur.f    = av_frame_alloc();
+    h->DPB[0].f = av_frame_alloc();
+    h->DPB[1].f = av_frame_alloc();
     if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {
         ff_cavs_end(avctx);
         return AVERROR(ENOMEM);
@@ -769,15 +769,9 @@ av_cold int ff_cavs_init(AVCodecContext *avctx) {
 av_cold int ff_cavs_end(AVCodecContext *avctx) {
     AVSContext *h = avctx->priv_data;
 
-    if (h->cur.f->data[0])
-        avctx->release_buffer(avctx, h->cur.f);
-    if (h->DPB[0].f->data[0])
-        avctx->release_buffer(avctx, h->DPB[0].f);
-    if (h->DPB[1].f->data[0])
-        avctx->release_buffer(avctx, h->DPB[1].f);
-    avcodec_free_frame(&h->cur.f);
-    avcodec_free_frame(&h->DPB[0].f);
-    avcodec_free_frame(&h->DPB[1].f);
+    av_frame_free(&h->cur.f);
+    av_frame_free(&h->DPB[0].f);
+    av_frame_free(&h->DPB[1].f);
 
     av_free(h->top_qp);
     av_free(h->top_mv[0]);
index b841f48d131fabab21b1d37be84a46e90d31ddcb..fbc21c4d818c59988cddeaeb1426f6402e247146 100644 (file)
@@ -931,6 +931,8 @@ static int decode_pic(AVSContext *h)
     int skip_count    = -1;
     enum cavs_mb mb_type;
 
+    av_frame_unref(h->cur.f);
+
     skip_bits(&h->gb, 16);//bbv_dwlay
     if (h->stc == PIC_PB_START_CODE) {
         h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I;
@@ -956,11 +958,9 @@ static int decode_pic(AVSContext *h)
         if (h->stream_revision > 0)
             skip_bits(&h->gb, 1); //marker_bit
     }
-    /* release last B frame */
-    if (h->cur.f->data[0])
-        h->avctx->release_buffer(h->avctx, h->cur.f);
 
-    ff_get_buffer(h->avctx, h->cur.f);
+    ff_get_buffer(h->avctx, h->cur.f, h->cur.f->pict_type == AV_PICTURE_TYPE_B ?
+                  0 : AV_GET_BUFFER_FLAG_REF);
 
     if (!h->edge_emu_buffer) {
         int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32);
@@ -1056,8 +1056,7 @@ static int decode_pic(AVSContext *h)
         } while (ff_cavs_next_mb(h));
     }
     if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
-        if (h->DPB[1].f->data[0])
-            h->avctx->release_buffer(h->avctx, h->DPB[1].f);
+        av_frame_unref(h->DPB[1].f);
         FFSWAP(AVSFrame, h->cur, h->DPB[1]);
         FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]);
     }
@@ -1119,19 +1118,15 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     AVSContext *h      = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    AVFrame *picture   = data;
     uint32_t stc       = -1;
-    int input_size;
+    int input_size, ret;
     const uint8_t *buf_end;
     const uint8_t *buf_ptr;
 
     if (buf_size == 0) {
         if (!h->low_delay && h->DPB[0].f->data[0]) {
             *got_frame = 1;
-            *picture = *h->DPB[0].f;
-            if (h->cur.f->data[0])
-                avctx->release_buffer(avctx, h->cur.f);
-            FFSWAP(AVSFrame, h->cur, h->DPB[0]);
+            av_frame_move_ref(data, h->DPB[0].f);
         }
         return 0;
     }
@@ -1150,10 +1145,8 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             break;
         case PIC_I_START_CODE:
             if (!h->got_keyframe) {
-                if(h->DPB[0].f->data[0])
-                    avctx->release_buffer(avctx, h->DPB[0].f);
-                if(h->DPB[1].f->data[0])
-                    avctx->release_buffer(avctx, h->DPB[1].f);
+                av_frame_unref(h->DPB[0].f);
+                av_frame_unref(h->DPB[1].f);
                 h->got_keyframe = 1;
             }
         case PIC_PB_START_CODE:
@@ -1167,12 +1160,14 @@ static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             *got_frame = 1;
             if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
                 if (h->DPB[1].f->data[0]) {
-                    *picture = *h->DPB[1].f;
+                    if ((ret = av_frame_ref(data, h->DPB[1].f)) < 0)
+                        return ret;
                 } else {
                     *got_frame = 0;
                 }
-            } else
-                *picture = *h->cur.f;
+            } else {
+                av_frame_move_ref(data, h->cur.f);
+            }
             break;
         case EXT_START_CODE:
             //mpeg_decode_extension(avctx, buf_ptr, input_size);
index 9f402cae217c07dfc1c46d106f00d57862e02525..8be14602c356b69beeaa87ef7101c9d1afe04ae5 100644 (file)
 #define CDG_PALETTE_SIZE          16
 
 typedef struct CDGraphicsContext {
-    AVFrame frame;
+    AVFrame *frame;
     int hscroll;
     int vscroll;
 } CDGraphicsContext;
 
-static void cdg_init_frame(AVFrame *frame)
-{
-    avcodec_get_frame_defaults(frame);
-    frame->reference = 3;
-    frame->buffer_hints = FF_BUFFER_HINTS_VALID    |
-                          FF_BUFFER_HINTS_READABLE |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-}
-
 static av_cold int cdg_decode_init(AVCodecContext *avctx)
 {
     CDGraphicsContext *cc = avctx->priv_data;
 
-    cdg_init_frame(&cc->frame);
+    cc->frame = av_frame_alloc();
+    if (!cc->frame)
+        return AVERROR(ENOMEM);
 
     avctx->width   = CDG_FULL_WIDTH;
     avctx->height  = CDG_FULL_HEIGHT;
@@ -95,8 +87,8 @@ static av_cold int cdg_decode_init(AVCodecContext *avctx)
 static void cdg_border_preset(CDGraphicsContext *cc, uint8_t *data)
 {
     int y;
-    int lsize    = cc->frame.linesize[0];
-    uint8_t *buf = cc->frame.data[0];
+    int lsize    = cc->frame->linesize[0];
+    uint8_t *buf = cc->frame->data[0];
     int color    = data[0] & 0x0F;
 
     if (!(data[1] & 0x0F)) {
@@ -120,7 +112,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low)
     uint16_t color;
     int i;
     int array_offset  = low ? 0 : 8;
-    uint32_t *palette = (uint32_t *) cc->frame.data[1];
+    uint32_t *palette = (uint32_t *) cc->frame->data[1];
 
     for (i = 0; i < 8; i++) {
         color = (data[2 * i] << 6) + (data[2 * i + 1] & 0x3F);
@@ -129,7 +121,7 @@ static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low)
         b = ((color     ) & 0x000F) * 17;
         palette[i + array_offset] = r << 16 | g << 8 | b;
     }
-    cc->frame.palette_has_changed = 1;
+    cc->frame->palette_has_changed = 1;
 }
 
 static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b)
@@ -138,8 +130,8 @@ static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b)
     int color;
     int x, y;
     int ai;
-    int stride   = cc->frame.linesize[0];
-    uint8_t *buf = cc->frame.data[0];
+    int stride   = cc->frame->linesize[0];
+    uint8_t *buf = cc->frame->data[0];
 
     ri = (data[2] & 0x1F) * CDG_TILE_HEIGHT + cc->vscroll;
     ci = (data[3] & 0x3F) * CDG_TILE_WIDTH  + cc->hscroll;
@@ -210,8 +202,8 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data,
     int color;
     int hscmd, h_off, hinc, vscmd, v_off, vinc;
     int y;
-    int stride   = cc->frame.linesize[0];
-    uint8_t *in  = cc->frame.data[0];
+    int stride   = cc->frame->linesize[0];
+    uint8_t *in  = cc->frame->data[0];
     uint8_t *out = new_frame->data[0];
 
     color =  data[0] & 0x0F;
@@ -239,7 +231,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data,
     if (!hinc && !vinc)
         return;
 
-    memcpy(new_frame->data[1], cc->frame.data[1], CDG_PALETTE_SIZE * 4);
+    memcpy(new_frame->data[1], cc->frame->data[1], CDG_PALETTE_SIZE * 4);
 
     for (y = FFMAX(0, vinc); y < FFMIN(CDG_FULL_HEIGHT + vinc, CDG_FULL_HEIGHT); y++)
         memcpy(out + FFMAX(0, hinc) + stride * y,
@@ -274,7 +266,7 @@ static int cdg_decode_frame(AVCodecContext *avctx,
     int ret;
     uint8_t command, inst;
     uint8_t cdg_data[CDG_DATA_SIZE];
-    AVFrame new_frame;
+    AVFrame *frame = data;
     CDGraphicsContext *cc = avctx->priv_data;
 
     if (buf_size < CDG_MINIMUM_PKT_SIZE) {
@@ -282,13 +274,13 @@ static int cdg_decode_frame(AVCodecContext *avctx,
         return AVERROR(EINVAL);
     }
 
-    ret = avctx->reget_buffer(avctx, &cc->frame);
+    ret = ff_reget_buffer(avctx, cc->frame);
     if (ret) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
     if (!avctx->frame_number)
-        memset(cc->frame.data[0], 0, cc->frame.linesize[0] * avctx->height);
+        memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);
 
     command = bytestream_get_byte(&buf);
     inst    = bytestream_get_byte(&buf);
@@ -300,8 +292,8 @@ static int cdg_decode_frame(AVCodecContext *avctx,
         switch (inst) {
         case CDG_INST_MEMORY_PRESET:
             if (!(cdg_data[1] & 0x0F))
-                memset(cc->frame.data[0], cdg_data[0] & 0x0F,
-                       cc->frame.linesize[0] * CDG_FULL_HEIGHT);
+                memset(cc->frame->data[0], cdg_data[0] & 0x0F,
+                       cc->frame->linesize[0] * CDG_FULL_HEIGHT);
             break;
         case CDG_INST_LOAD_PAL_LO:
         case CDG_INST_LOAD_PAL_HIGH:
@@ -335,28 +327,33 @@ static int cdg_decode_frame(AVCodecContext *avctx,
                 return AVERROR(EINVAL);
             }
 
-            cdg_init_frame(&new_frame);
-            ret = ff_get_buffer(avctx, &new_frame);
+            ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
             if (ret) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return ret;
             }
 
-            cdg_scroll(cc, cdg_data, &new_frame, inst == CDG_INST_SCROLL_COPY);
-            avctx->release_buffer(avctx, &cc->frame);
-            cc->frame = new_frame;
+            cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY);
+            av_frame_unref(cc->frame);
+            ret = av_frame_ref(cc->frame, frame);
+            if (ret < 0)
+                return ret;
             break;
         default:
             break;
         }
 
+        if (!frame->data[0]) {
+            ret = av_frame_ref(frame, cc->frame);
+            if (ret < 0)
+                return ret;
+        }
         *got_frame = 1;
     } else {
         *got_frame = 0;
         buf_size   = 0;
     }
 
-    *(AVFrame *) data = cc->frame;
     return buf_size;
 }
 
@@ -364,8 +361,7 @@ static av_cold int cdg_decode_end(AVCodecContext *avctx)
 {
     CDGraphicsContext *cc = avctx->priv_data;
 
-    if (cc->frame.data[0])
-        avctx->release_buffer(avctx, &cc->frame);
+    av_frame_free(&cc->frame);
 
     return 0;
 }
index 0b3d59cb80cabb321341a67166b6b09698cd39bc..465867c098b8547c00b606572e53787bc7a58789 100644 (file)
@@ -49,7 +49,6 @@ static av_cold int cdxl_decode_init(AVCodecContext *avctx)
 {
     CDXLVideoContext *c = avctx->priv_data;
 
-    avcodec_get_frame_defaults(&c->frame);
     c->new_video_size = 0;
     c->avctx          = avctx;
 
@@ -113,15 +112,15 @@ static void import_format(CDXLVideoContext *c, int linesize, uint8_t *out)
     }
 }
 
-static void cdxl_decode_rgb(CDXLVideoContext *c)
+static void cdxl_decode_rgb(CDXLVideoContext *c, AVFrame *frame)
 {
-    uint32_t *new_palette = (uint32_t *)c->frame.data[1];
+    uint32_t *new_palette = (uint32_t *)frame->data[1];
 
     import_palette(c, new_palette);
-    import_format(c, c->frame.linesize[0], c->frame.data[0]);
+    import_format(c, frame->linesize[0], frame->data[0]);
 }
 
-static void cdxl_decode_ham6(CDXLVideoContext *c)
+static void cdxl_decode_ham6(CDXLVideoContext *c, AVFrame *frame)
 {
     AVCodecContext *avctx = c->avctx;
     uint32_t new_palette[16], r, g, b;
@@ -129,7 +128,7 @@ static void cdxl_decode_ham6(CDXLVideoContext *c)
     int x, y;
 
     ptr = c->new_video;
-    out = c->frame.data[0];
+    out = frame->data[0];
 
     import_palette(c, new_palette);
     import_format(c, avctx->width, c->new_video);
@@ -160,11 +159,11 @@ static void cdxl_decode_ham6(CDXLVideoContext *c)
             }
             AV_WL24(out + x * 3, r | g | b);
         }
-        out += c->frame.linesize[0];
+        out += frame->linesize[0];
     }
 }
 
-static void cdxl_decode_ham8(CDXLVideoContext *c)
+static void cdxl_decode_ham8(CDXLVideoContext *c, AVFrame *frame)
 {
     AVCodecContext *avctx = c->avctx;
     uint32_t new_palette[64], r, g, b;
@@ -172,7 +171,7 @@ static void cdxl_decode_ham8(CDXLVideoContext *c)
     int x, y;
 
     ptr = c->new_video;
-    out = c->frame.data[0];
+    out = frame->data[0];
 
     import_palette(c, new_palette);
     import_format(c, avctx->width, c->new_video);
@@ -203,7 +202,7 @@ static void cdxl_decode_ham8(CDXLVideoContext *c)
             }
             AV_WL24(out + x * 3, r | g | b);
         }
-        out += c->frame.linesize[0];
+        out += frame->linesize[0];
     }
 }
 
@@ -211,7 +210,7 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *pkt)
 {
     CDXLVideoContext *c = avctx->priv_data;
-    AVFrame * const p = &c->frame;
+    AVFrame * const p = data;
     int ret, w, h, encoding, aligned_width, buf_size = pkt->size;
     const uint8_t *buf = pkt->data;
 
@@ -259,11 +258,7 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_PATCHWELCOME;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -275,14 +270,13 @@ static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
         if (!c->new_video)
             return AVERROR(ENOMEM);
         if (c->bpp == 8)
-            cdxl_decode_ham8(c);
+            cdxl_decode_ham8(c, p);
         else
-            cdxl_decode_ham6(c);
+            cdxl_decode_ham6(c, p);
     } else {
-        cdxl_decode_rgb(c);
+        cdxl_decode_rgb(c, p);
     }
     *got_frame = 1;
-    *(AVFrame*)data = c->frame;
 
     return buf_size;
 }
@@ -292,8 +286,6 @@ static av_cold int cdxl_decode_end(AVCodecContext *avctx)
     CDXLVideoContext *c = avctx->priv_data;
 
     av_free(c->new_video);
-    if (c->frame.data[0])
-        avctx->release_buffer(avctx, &c->frame);
 
     return 0;
 }
index 9bf68634a9696350d3ba6cbb02b279e8a2246417..0c5d5b0f0d2c6a2ba25d33af8f00cb7eb4cce539 100644 (file)
@@ -37,6 +37,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 
 typedef struct {
@@ -429,10 +430,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     s->data = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame))) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame))) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -450,8 +448,10 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     if (s->palette_video)
         memcpy (s->frame.data[1], s->pal, AVPALETTE_SIZE);
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -461,8 +461,7 @@ static av_cold int cinepak_decode_end(AVCodecContext *avctx)
 {
     CinepakContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index 5168d345714b40192f7fe5f11f493d183bfa68eb..7e189cd12d2a7104de40d6c37710a2af5db53627 100644 (file)
 #include "internal.h"
 #include "put_bits.h"
 
-typedef struct CLJRContext {
-    AVFrame         picture;
-} CLJRContext;
-
-static av_cold int common_init(AVCodecContext *avctx)
-{
-    CLJRContext * const a = avctx->priv_data;
-
-    avctx->coded_frame = &a->picture;
-
-    return 0;
-}
-
 #if CONFIG_CLJR_DECODER
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
@@ -49,15 +36,10 @@ static int decode_frame(AVCodecContext *avctx,
 {
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
-    CLJRContext * const a = avctx->priv_data;
     GetBitContext gb;
-    AVFrame *picture = data;
-    AVFrame * const p = &a->picture;
+    AVFrame * const p = data;
     int x, y, ret;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
     if (avctx->height <= 0 || avctx->width <= 0) {
         av_log(avctx, AV_LOG_ERROR, "Invalid width or height\n");
         return AVERROR_INVALIDDATA;
@@ -69,8 +51,7 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -80,9 +61,9 @@ static int decode_frame(AVCodecContext *avctx,
     init_get_bits(&gb, buf, buf_size * 8);
 
     for (y = 0; y < avctx->height; y++) {
-        uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]];
-        uint8_t *cb   = &a->picture.data[1][y * a->picture.linesize[1]];
-        uint8_t *cr   = &a->picture.data[2][y * a->picture.linesize[2]];
+        uint8_t *luma = &p->data[0][y * p->linesize[0]];
+        uint8_t *cb   = &p->data[1][y * p->linesize[1]];
+        uint8_t *cr   = &p->data[2][y * p->linesize[2]];
         for (x = 0; x < avctx->width; x += 4) {
             luma[3] = get_bits(&gb, 5) << 3;
             luma[2] = get_bits(&gb, 5) << 3;
@@ -94,7 +75,6 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -103,15 +83,6 @@ static int decode_frame(AVCodecContext *avctx,
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     avctx->pix_fmt = AV_PIX_FMT_YUV411P;
-    return common_init(avctx);
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    CLJRContext *a = avctx->priv_data;
-
-    if (a->picture.data[0])
-        avctx->release_buffer(avctx, &a->picture);
     return 0;
 }
 
@@ -119,9 +90,7 @@ AVCodec ff_cljr_decoder = {
     .name           = "cljr",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CLJR,
-    .priv_data_size = sizeof(CLJRContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
@@ -129,6 +98,19 @@ AVCodec ff_cljr_decoder = {
 #endif
 
 #if CONFIG_CLJR_ENCODER
+typedef struct CLJRContext {
+    AVFrame         picture;
+} CLJRContext;
+
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    CLJRContext * const a = avctx->priv_data;
+
+    avctx->coded_frame = &a->picture;
+
+    return 0;
+}
+
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *p, int *got_packet)
 {
@@ -173,7 +155,7 @@ AVCodec ff_cljr_encoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_CLJR,
     .priv_data_size = sizeof(CLJRContext),
-    .init           = common_init,
+    .init           = encode_init,
     .encode2        = encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
                                                    AV_PIX_FMT_NONE },
index 30dc53c6e11b58bfbe696c36a7f12c030daf9af6..a6b51b398e7d3b73080af134353f20a55f1215d8 100644 (file)
@@ -271,18 +271,13 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_picture_ptr, AVPacket *avpkt)
 {
     CLLCContext *ctx = avctx->priv_data;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     uint8_t *src = avpkt->data;
     uint32_t info_tag, info_offset;
     int data_size;
     GetBitContext gb;
     int coding_type, ret;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    pic->reference = 0;
-
     /* Skip the INFO header if present */
     info_offset = 0;
     info_tag    = AV_RL32(src);
@@ -334,7 +329,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
         avctx->pix_fmt             = AV_PIX_FMT_RGB24;
         avctx->bits_per_raw_sample = 8;
 
-        ret = ff_get_buffer(avctx, pic);
+        ret = ff_get_buffer(avctx, pic, 0);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
             return ret;
@@ -349,7 +344,7 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
         avctx->pix_fmt             = AV_PIX_FMT_ARGB;
         avctx->bits_per_raw_sample = 8;
 
-        ret = ff_get_buffer(avctx, pic);
+        ret = ff_get_buffer(avctx, pic, 0);
         if (ret < 0) {
             av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
             return ret;
@@ -369,7 +364,6 @@ static int cllc_decode_frame(AVCodecContext *avctx, void *data,
     pic->pict_type = AV_PICTURE_TYPE_I;
 
     *got_picture_ptr = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
@@ -378,10 +372,6 @@ static av_cold int cllc_decode_close(AVCodecContext *avctx)
 {
     CLLCContext *ctx = avctx->priv_data;
 
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
     av_freep(&ctx->swapped_buf);
 
     return 0;
@@ -398,12 +388,6 @@ static av_cold int cllc_decode_init(AVCodecContext *avctx)
 
     ff_dsputil_init(&ctx->dsp, avctx);
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
-        return AVERROR(ENOMEM);
-    }
-
     return 0;
 }
 
index b47cda8974230e0a4bc12b8e4aca605f3a547f7d..a9b3ba0a757562847f54878c09a49c035fbf8326 100644 (file)
@@ -142,7 +142,7 @@ static int cng_decode_frame(AVCodecContext *avctx, void *data,
                                  p->excitation, avctx->frame_size, p->order);
 
     frame->nb_samples = avctx->frame_size;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index ba542c2e1e8656a4a42f5f3987ceb72479871dd0..135359bcd4a15b46da9bf34854656a4d7431ddba 100644 (file)
@@ -958,7 +958,7 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data,
     /* get output buffer */
     if (q->discarded_packets >= 2) {
         frame->nb_samples = q->samples_per_channel;
-        if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
index b982f5029c6a01405690c047a7cb2d2c5a6207eb..6b8d144f76fc24e050bcaf0f434238103f70f5d8 100644 (file)
@@ -31,7 +31,6 @@
 #include "libavutil/lzo.h"
 
 typedef struct {
-    AVFrame pic;
     int linelen, height, bpp;
     unsigned int decomp_size;
     unsigned char* decomp_buf;
@@ -150,12 +149,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
-                          FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -186,36 +180,35 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     // flip upside down, add difference frame
     if (buf[0] & 1) { // keyframe
-        c->pic.pict_type = AV_PICTURE_TYPE_I;
-        c->pic.key_frame = 1;
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        picture->key_frame = 1;
         switch (c->bpp) {
           case 16:
-              copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height);
+              copy_frame_16(picture, c->decomp_buf, c->linelen, c->height);
               break;
           case 32:
-              copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
+              copy_frame_32(picture, c->decomp_buf, c->linelen, c->height);
               break;
           default:
-              copy_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
+              copy_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4),
                                  c->linelen, c->height);
         }
     } else {
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
-        c->pic.key_frame = 0;
+        picture->pict_type = AV_PICTURE_TYPE_P;
+        picture->key_frame = 0;
         switch (c->bpp) {
           case 16:
-              add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height);
+              add_frame_16(picture, c->decomp_buf, c->linelen, c->height);
               break;
           case 32:
-              add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
+              add_frame_32(picture, c->decomp_buf, c->linelen, c->height);
               break;
           default:
-              add_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
+              add_frame_default(picture, c->decomp_buf, FFALIGN(c->linelen, 4),
                                 c->linelen, c->height);
         }
     }
 
-    *picture = c->pic;
     *got_frame = 1;
     return buf_size;
 }
@@ -234,7 +227,6 @@ static av_cold int decode_init(AVCodecContext *avctx) {
             return AVERROR_INVALIDDATA;
     }
     c->bpp = avctx->bits_per_coded_sample;
-    c->pic.data[0] = NULL;
     c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
     c->height = avctx->height;
     stride = c->linelen;
@@ -252,8 +244,6 @@ static av_cold int decode_init(AVCodecContext *avctx) {
 static av_cold int decode_end(AVCodecContext *avctx) {
     CamStudioContext *c = avctx->priv_data;
     av_freep(&c->decomp_buf);
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
     return 0;
 }
 
index 6b9d5b930785718e50dd41a805c40836934237ee..9011bc2cfdf5204faa37ea4f8fd21828963aa491 100644 (file)
@@ -40,7 +40,6 @@
 typedef struct CyuvDecodeContext {
     AVCodecContext *avctx;
     int width, height;
-    AVFrame frame;
 } CyuvDecodeContext;
 
 static av_cold int cyuv_decode_init(AVCodecContext *avctx)
@@ -65,6 +64,7 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     CyuvDecodeContext *s=avctx->priv_data;
+    AVFrame *frame = data;
 
     unsigned char *y_plane;
     unsigned char *u_plane;
@@ -101,26 +101,21 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
     /* pixel data starts 48 bytes in, after 3x16-byte tables */
     stream_ptr = 48;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-    s->frame.reference = 0;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    y_plane = s->frame.data[0];
-    u_plane = s->frame.data[1];
-    v_plane = s->frame.data[2];
+    y_plane = frame->data[0];
+    u_plane = frame->data[1];
+    v_plane = frame->data[2];
 
     /* iterate through each line in the height */
     for (y_ptr = 0, u_ptr = 0, v_ptr = 0;
-         y_ptr < (s->height * s->frame.linesize[0]);
-         y_ptr += s->frame.linesize[0] - s->width,
-         u_ptr += s->frame.linesize[1] - s->width / 4,
-         v_ptr += s->frame.linesize[2] - s->width / 4) {
+         y_ptr < (s->height * frame->linesize[0]);
+         y_ptr += frame->linesize[0] - s->width,
+         u_ptr += frame->linesize[1] - s->width / 4,
+         v_ptr += frame->linesize[2] - s->width / 4) {
 
         /* reset predictors */
         cur_byte = buf[stream_ptr++];
@@ -164,21 +159,10 @@ static int cyuv_decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data= s->frame;
 
     return buf_size;
 }
 
-static av_cold int cyuv_decode_end(AVCodecContext *avctx)
-{
-    CyuvDecodeContext *s = avctx->priv_data;
-
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    return 0;
-}
-
 #if CONFIG_AURA_DECODER
 AVCodec ff_aura_decoder = {
     .name           = "aura",
@@ -186,7 +170,6 @@ AVCodec ff_aura_decoder = {
     .id             = AV_CODEC_ID_AURA,
     .priv_data_size = sizeof(CyuvDecodeContext),
     .init           = cyuv_decode_init,
-    .close          = cyuv_decode_end,
     .decode         = cyuv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Auravision AURA"),
@@ -200,7 +183,6 @@ AVCodec ff_cyuv_decoder = {
     .id             = AV_CODEC_ID_CYUV,
     .priv_data_size = sizeof(CyuvDecodeContext),
     .init           = cyuv_decode_init,
-    .close          = cyuv_decode_end,
     .decode         = cyuv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Creative YUV (CYUV)"),
index efd07055ecd0bb8d37a4f07df8754b4309ba5daf..7a35fcc59dbc58fb33b73a2c7d0d6ab14483b2b4 100644 (file)
@@ -1836,7 +1836,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 256 * (s->sample_blocks / 8);
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 119be7066ce0bcf28158d020916bb65b1652845e..bbe4ce2888b3a4fe02680e7aa74edd28d0499628 100644 (file)
@@ -28,8 +28,6 @@
 #include "libavutil/mem.h"
 
 typedef struct DfaContext {
-    AVFrame pic;
-
     uint32_t pal[256];
     uint8_t *frame_buf;
 } DfaContext;
@@ -311,6 +309,7 @@ static int dfa_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     DfaContext *s = avctx->priv_data;
     GetByteContext gb;
     const uint8_t *buf = avpkt->data;
@@ -319,10 +318,7 @@ static int dfa_decode_frame(AVCodecContext *avctx,
     int ret;
     int i, pal_elems;
 
-    if (s->pic.data[0])
-        avctx->release_buffer(avctx, &s->pic);
-
-    if ((ret = ff_get_buffer(avctx, &s->pic))) {
+    if ((ret = ff_get_buffer(avctx, frame, 0))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -340,7 +336,7 @@ static int dfa_decode_frame(AVCodecContext *avctx,
                 s->pal[i] = bytestream2_get_be24(&gb) << 2;
                 s->pal[i] |= (s->pal[i] >> 6) & 0x333;
             }
-            s->pic.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
         } else if (chunk_type <= 9) {
             if (decoder[chunk_type - 2](&gb, s->frame_buf, avctx->width, avctx->height)) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding %s chunk\n",
@@ -355,16 +351,15 @@ static int dfa_decode_frame(AVCodecContext *avctx,
     }
 
     buf = s->frame_buf;
-    dst = s->pic.data[0];
+    dst = frame->data[0];
     for (i = 0; i < avctx->height; i++) {
         memcpy(dst, buf, avctx->width);
-        dst += s->pic.linesize[0];
+        dst += frame->linesize[0];
         buf += avctx->width;
     }
-    memcpy(s->pic.data[1], s->pal, sizeof(s->pal));
+    memcpy(frame->data[1], s->pal, sizeof(s->pal));
 
     *got_frame = 1;
-    *(AVFrame*)data = s->pic;
 
     return avpkt->size;
 }
@@ -373,9 +368,6 @@ static av_cold int dfa_decode_end(AVCodecContext *avctx)
 {
     DfaContext *s = avctx->priv_data;
 
-    if (s->pic.data[0])
-        avctx->release_buffer(avctx, &s->pic);
-
     av_freep(&s->frame_buf);
 
     return 0;
index cc8952b94d060e8cf32a7bf4808ca2a1af7aadda..ab6636cbc038cb3e99a5ac82493a6d85e72ffb6a 100644 (file)
@@ -34,7 +34,6 @@
 
 typedef struct DNXHDContext {
     AVCodecContext *avctx;
-    AVFrame picture;
     GetBitContext gb;
     int cid;                            ///< compression id
     unsigned int width, height;
@@ -63,9 +62,6 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
     DNXHDContext *ctx = avctx->priv_data;
 
     ctx->avctx = avctx;
-    avctx->coded_frame = &ctx->picture;
-    ctx->picture.type = AV_PICTURE_TYPE_I;
-    ctx->picture.key_frame = 1;
     return 0;
 }
 
@@ -100,7 +96,8 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
     return 0;
 }
 
-static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field)
+static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame,
+                               const uint8_t *buf, int buf_size, int first_field)
 {
     static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 };
     int i, cid;
@@ -114,8 +111,8 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si
     }
     if (buf[5] & 2) { /* interlaced */
         ctx->cur_field = buf[5] & 1;
-        ctx->picture.interlaced_frame = 1;
-        ctx->picture.top_field_first = first_field ^ ctx->cur_field;
+        frame->interlaced_frame = 1;
+        frame->top_field_first  = first_field ^ ctx->cur_field;
         av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field);
     }
 
@@ -158,11 +155,11 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si
 
     av_dlog(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height);
 
-    if ((ctx->height+15)>>4 == ctx->mb_height && ctx->picture.interlaced_frame)
+    if ((ctx->height+15)>>4 == ctx->mb_height && frame->interlaced_frame)
         ctx->height <<= 1;
 
     if (ctx->mb_height > 68 ||
-        (ctx->mb_height<<ctx->picture.interlaced_frame) > (ctx->height+15)>>4) {
+        (ctx->mb_height << frame->interlaced_frame) > (ctx->height+15)>>4) {
         av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big: %d\n", ctx->mb_height);
         return -1;
     }
@@ -262,11 +259,11 @@ static void dnxhd_decode_dct_block_10(DNXHDContext *ctx, int16_t *block,
     dnxhd_decode_dct_block(ctx, block, n, qscale, 6, 8, 4);
 }
 
-static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
+static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int y)
 {
     int shift1 = ctx->bit_depth == 10;
-    int dct_linesize_luma   = ctx->picture.linesize[0];
-    int dct_linesize_chroma = ctx->picture.linesize[1];
+    int dct_linesize_luma   = frame->linesize[0];
+    int dct_linesize_chroma = frame->linesize[1];
     uint8_t *dest_y, *dest_u, *dest_v;
     int dct_y_offset, dct_x_offset;
     int qscale, i;
@@ -279,19 +276,19 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
         ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale);
     }
 
-    if (ctx->picture.interlaced_frame) {
+    if (frame->interlaced_frame) {
         dct_linesize_luma   <<= 1;
         dct_linesize_chroma <<= 1;
     }
 
-    dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma)   << 4) + (x << (4 + shift1));
-    dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
-    dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
+    dest_y = frame->data[0] + ((y * dct_linesize_luma)   << 4) + (x << (4 + shift1));
+    dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
+    dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1));
 
     if (ctx->cur_field) {
-        dest_y += ctx->picture.linesize[0];
-        dest_u += ctx->picture.linesize[1];
-        dest_v += ctx->picture.linesize[2];
+        dest_y += frame->linesize[0];
+        dest_u += frame->linesize[1];
+        dest_v += frame->linesize[2];
     }
 
     dct_y_offset = dct_linesize_luma << 3;
@@ -312,7 +309,8 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
     return 0;
 }
 
-static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size)
+static int dnxhd_decode_macroblocks(DNXHDContext *ctx, AVFrame *frame,
+                                    const uint8_t *buf, int buf_size)
 {
     int x, y;
     for (y = 0; y < ctx->mb_height; y++) {
@@ -322,7 +320,7 @@ static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int b
         init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3);
         for (x = 0; x < ctx->mb_width; x++) {
             //START_TIMER;
-            dnxhd_decode_macroblock(ctx, x, y);
+            dnxhd_decode_macroblock(ctx, frame, x, y);
             //STOP_TIMER("decode macroblock");
         }
     }
@@ -337,11 +335,12 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     DNXHDContext *ctx = avctx->priv_data;
     AVFrame *picture = data;
     int first_field = 1;
+    int ret;
 
     av_dlog(avctx, "frame size %d\n", buf_size);
 
  decode_coding_unit:
-    if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0)
+    if (dnxhd_decode_header(ctx, picture, buf, buf_size, first_field) < 0)
         return -1;
 
     if ((avctx->width || avctx->height) &&
@@ -356,24 +355,23 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     avcodec_set_dimensions(avctx, ctx->width, ctx->height);
 
     if (first_field) {
-        if (ctx->picture.data[0])
-            avctx->release_buffer(avctx, &ctx->picture);
-        if (ff_get_buffer(avctx, &ctx->picture) < 0) {
+        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
+        picture->pict_type = AV_PICTURE_TYPE_I;
+        picture->key_frame = 1;
     }
 
-    dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280);
+    dnxhd_decode_macroblocks(ctx, picture, buf + 0x280, buf_size - 0x280);
 
-    if (first_field && ctx->picture.interlaced_frame) {
+    if (first_field && picture->interlaced_frame) {
         buf      += ctx->cid_table->coding_unit_size;
         buf_size -= ctx->cid_table->coding_unit_size;
         first_field = 0;
         goto decode_coding_unit;
     }
 
-    *picture = ctx->picture;
     *got_frame = 1;
     return buf_size;
 }
@@ -382,8 +380,6 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
 {
     DNXHDContext *ctx = avctx->priv_data;
 
-    if (ctx->picture.data[0])
-        avctx->release_buffer(avctx, &ctx->picture);
     ff_free_vlc(&ctx->ac_vlc);
     ff_free_vlc(&ctx->dc_vlc);
     ff_free_vlc(&ctx->run_vlc);
index abf3c84ea917cc6470dc5ec9792e8d3f10bcfe57..88b7bd8207701d2cbd7975342c4f0be7db673e01 100644 (file)
@@ -208,7 +208,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = out / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 0ad17203a0ef5d1cd4c9b485a789ac0c8a7c448c..c1e83046f666cbd05d3ac9696e1303ea69cc285f 100644 (file)
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct DPXContext {
-    AVFrame picture;
-} DPXContext;
-
-
 static unsigned int read32(const uint8_t **ptr, int is_big)
 {
     unsigned int temp;
@@ -58,9 +53,7 @@ static int decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
     int buf_size       = avpkt->size;
-    DPXContext *const s = avctx->priv_data;
-    AVFrame *picture  = data;
-    AVFrame *const p = &s->picture;
+    AVFrame *const p = data;
     uint8_t *ptr;
 
     unsigned int offset;
@@ -154,13 +147,11 @@ static int decode_frame(AVCodecContext *avctx,
             return AVERROR_INVALIDDATA;
     }
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
     if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
         return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -212,36 +203,15 @@ static int decode_frame(AVCodecContext *avctx,
             break;
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    DPXContext *s = avctx->priv_data;
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-    return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    DPXContext *s = avctx->priv_data;
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_dpx_decoder = {
     .name           = "dpx",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DPX,
-    .priv_data_size = sizeof(DPXContext),
-    .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .long_name      = NULL_IF_CONFIG_SMALL("DPX image"),
     .capabilities   = CODEC_CAP_DR1,
index 4da7d26670f4835e80e852f89d3ceb951282f583..39479546cccca50b078c4029bbe94a922fc5f01d 100644 (file)
@@ -281,10 +281,9 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
         break;
     }
 
-    cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &cin->frame)) {
+    if ((res = ff_reget_buffer(avctx, &cin->frame)) < 0) {
         av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
-        return -1;
+        return res;
     }
 
     memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
@@ -296,8 +295,10 @@ static int cinvideo_decode_frame(AVCodecContext *avctx,
 
     FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
 
+    if ((res = av_frame_ref(data, &cin->frame)) < 0)
+        return res;
+
     *got_frame = 1;
-    *(AVFrame *)data = cin->frame;
 
     return buf_size;
 }
@@ -307,8 +308,7 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
     CinVideoContext *cin = avctx->priv_data;
     int i;
 
-    if (cin->frame.data[0])
-        avctx->release_buffer(avctx, &cin->frame);
+    av_frame_unref(&cin->frame);
 
     for (i = 0; i < 3; ++i)
         av_free(cin->bitmap_table[i]);
@@ -341,7 +341,7 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = avpkt->size - cin->initial_decode_frame;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 441deadaab2ce2d29b92d5bd2f0ae4985c0504ec..cc9c232c6049f26641998212dbfab93fbc9e97f7 100644 (file)
@@ -326,16 +326,12 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
         return -1; /* NOTE: we only accept several full frames */
     }
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    s->picture.reference = 0;
     s->picture.key_frame = 1;
     s->picture.pict_type = AV_PICTURE_TYPE_I;
     avctx->pix_fmt   = s->sys->pix_fmt;
     avctx->time_base = s->sys->time_base;
     avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
-    if (ff_get_buffer(avctx, &s->picture) < 0) {
+    if (ff_get_buffer(avctx, &s->picture, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -350,7 +346,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
 
     /* return image */
     *got_frame = 1;
-    *(AVFrame*)data = s->picture;
+    av_frame_move_ref(data, &s->picture);
 
     /* Determine the codec's sample_aspect ratio from the packet */
     vsc_pack = buf + 80*5 + 48 + 5;
@@ -367,8 +363,7 @@ static int dvvideo_close(AVCodecContext *c)
 {
     DVVideoContext *s = c->priv_data;
 
-    if (s->picture.data[0])
-        c->release_buffer(c, &s->picture);
+    av_frame_unref(&s->picture);
 
     return 0;
 }
index cfc014a77b194686cb814c79e5d7261552cc3216..9e7f453b081069691ba7ebc9f11b71fbe34a2f94 100644 (file)
@@ -38,7 +38,7 @@
  * Decoder context
  */
 typedef struct DxaDecContext {
-    AVFrame pic, prev;
+    AVFrame prev;
 
     int dsize;
     uint8_t *decomp_buf;
@@ -48,12 +48,12 @@ typedef struct DxaDecContext {
 static const int shift1[6] = { 0, 8, 8, 8, 4, 4 };
 static const int shift2[6] = { 0, 0, 8, 4, 0, 4 };
 
-static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref)
+static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst,
+                     int stride, uint8_t *src, uint8_t *ref)
 {
     uint8_t *code, *data, *mv, *msk, *tmp, *tmp2;
     int i, j, k;
     int type, x, y, d, d2;
-    int stride = c->pic.linesize[0];
     uint32_t mask;
 
     code = src  + 12;
@@ -191,6 +191,7 @@ static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     DxaDecContext * const c = avctx->priv_data;
@@ -216,17 +217,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         buf_size -= 768+4;
     }
 
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
-    c->pic.palette_has_changed = pc;
+    memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
+    frame->palette_has_changed = pc;
 
-    outptr = c->pic.data[0];
+    outptr = frame->data[0];
     srcptr = c->decomp_buf;
     tmpptr = c->prev.data[0];
-    stride = c->pic.linesize[0];
+    stride = frame->linesize[0];
 
     if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L')
         compr = -1;
@@ -240,22 +241,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     }
     switch(compr){
     case -1:
-        c->pic.key_frame = 0;
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
         if(c->prev.data[0])
-            memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height);
+            memcpy(frame->data[0], c->prev.data[0], frame->linesize[0] * avctx->height);
         else{ // Should happen only when first frame is 'NULL'
-            memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height);
-            c->pic.key_frame = 1;
-            c->pic.pict_type = AV_PICTURE_TYPE_I;
+            memset(frame->data[0], 0, frame->linesize[0] * avctx->height);
+            frame->key_frame = 1;
+            frame->pict_type = AV_PICTURE_TYPE_I;
         }
         break;
     case 2:
     case 3:
     case 4:
     case 5:
-        c->pic.key_frame = !(compr & 1);
-        c->pic.pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
+        frame->key_frame = !(compr & 1);
+        frame->pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
         for(j = 0; j < avctx->height; j++){
             if(compr & 1){
                 for(i = 0; i < avctx->width; i++)
@@ -269,21 +270,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         break;
     case 12: // ScummVM coding
     case 13:
-        c->pic.key_frame = 0;
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
-        decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]);
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, c->prev.data[0]);
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]);
         return AVERROR_INVALIDDATA;
     }
 
-    FFSWAP(AVFrame, c->pic, c->prev);
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(&c->prev);
+    if ((ret = av_frame_ref(&c->prev, frame)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame*)data = c->prev;
 
     /* always report that the buffer was completely consumed */
     return orig_buf_size;
@@ -309,10 +309,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
     DxaDecContext * const c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
-    if(c->prev.data[0])
-        avctx->release_buffer(avctx, &c->prev);
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(&c->prev);
 
     return 0;
 }
index 30983f8056d3cb5611bc844551d1e25069785268..5b44f15d4fbebfad00932904d5c7ae4c29046fe2 100644 (file)
@@ -28,9 +28,6 @@
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     avctx->pix_fmt     = AV_PIX_FMT_YUV420P;
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -39,21 +36,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     int h, w;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *src = avpkt->data;
     uint8_t *Y1, *Y2, *U, *V;
     int ret;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < avctx->width * avctx->height * 3 / 2 + 16) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
         return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     pic->pict_type = AV_PICTURE_TYPE_I;
@@ -84,28 +77,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = *pic;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_dxtory_decoder = {
     .name           = "dxtory",
     .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_DXTORY,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
 };
index cd5084d685e2ab75a9bab61153a1db93827a80db..e71d9e36a1518a482f06f7341b4ec5e061afdc70 100644 (file)
@@ -69,15 +69,15 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
                                ff_dxva2_get_surface_index(ctx, r),
                                r->long_ref != 0);
 
-            if ((r->f.reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
+            if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)
                 pp->FieldOrderCntList[i][0] = r->field_poc[0];
-            if ((r->f.reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
+            if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)
                 pp->FieldOrderCntList[i][1] = r->field_poc[1];
 
             pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;
-            if (r->f.reference & PICT_TOP_FIELD)
+            if (r->reference & PICT_TOP_FIELD)
                 pp->UsedForReferenceFlags |= 1 << (2*i + 0);
-            if (r->f.reference & PICT_BOTTOM_FIELD)
+            if (r->reference & PICT_BOTTOM_FIELD)
                 pp->UsedForReferenceFlags |= 1 << (2*i + 1);
         } else {
             pp->RefFrameList[i].bPicEntry = 0xff;
@@ -230,7 +230,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
                 unsigned plane;
                 fill_picture_entry(&slice->RefPicList[list][i],
                                    ff_dxva2_get_surface_index(ctx, r),
-                                   r->f.reference == PICT_BOTTOM_FIELD);
+                                   r->reference == PICT_BOTTOM_FIELD);
                 for (plane = 0; plane < 3; plane++) {
                     int w, o;
                     if (plane == 0 && h->luma_weight_flag[list]) {
index 0dce066f1eee0187117d36db732cd7d1ad24a65b..cf19a85e5ae45e6f060a621a7ec85c9541b3f000 100644 (file)
@@ -36,9 +36,8 @@
 
 typedef struct CmvContext {
     AVCodecContext *avctx;
-    AVFrame frame;        ///< current
-    AVFrame last_frame;   ///< last
-    AVFrame last2_frame;  ///< second-last
+    AVFrame *last_frame;   ///< last
+    AVFrame *last2_frame;  ///< second-last
     int width, height;
     unsigned int palette[AVPALETTE_COUNT];
 } CmvContext;
@@ -47,16 +46,27 @@ static av_cold int cmv_decode_init(AVCodecContext *avctx){
     CmvContext *s = avctx->priv_data;
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+    s->last_frame  = av_frame_alloc();
+    s->last2_frame = av_frame_alloc();
+    if (!s->last_frame || !s->last2_frame) {
+        av_frame_free(&s->last_frame);
+        av_frame_free(&s->last2_frame);
+        return AVERROR(ENOMEM);
+    }
+
     return 0;
 }
 
-static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){
-    unsigned char *dst = s->frame.data[0];
+static void cmv_decode_intra(CmvContext * s, AVFrame *frame,
+                             const uint8_t *buf, const uint8_t *buf_end)
+{
+    unsigned char *dst = frame->data[0];
     int i;
 
     for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) {
         memcpy(dst, buf, s->avctx->width);
-        dst += s->frame.linesize[0];
+        dst += frame->linesize[0];
         buf += s->avctx->width;
     }
 }
@@ -80,7 +90,9 @@ static void cmv_motcomp(unsigned char *dst, int dst_stride,
     }
 }
 
-static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){
+static void cmv_decode_inter(CmvContext *s, AVFrame *frame, const uint8_t *buf,
+                             const uint8_t *buf_end)
+{
     const uint8_t *raw = buf + (s->avctx->width*s->avctx->height/16);
     int x,y,i;
 
@@ -88,28 +100,28 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t *
     for(y=0; y<s->avctx->height/4; y++)
     for(x=0; x<s->avctx->width/4 && buf_end - buf > i; x++) {
         if (buf[i]==0xFF) {
-            unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4;
+            unsigned char *dst = frame->data[0] + (y*4)*frame->linesize[0] + x*4;
             if (raw+16<buf_end && *raw==0xFF) { /* intra */
                 raw++;
                 memcpy(dst, raw, 4);
-                memcpy(dst+s->frame.linesize[0], raw+4, 4);
-                memcpy(dst+2*s->frame.linesize[0], raw+8, 4);
-                memcpy(dst+3*s->frame.linesize[0], raw+12, 4);
+                memcpy(dst +     frame->linesize[0], raw+4, 4);
+                memcpy(dst + 2 * frame->linesize[0], raw+8, 4);
+                memcpy(dst + 3 * frame->linesize[0], raw+12, 4);
                 raw+=16;
             }else if(raw<buf_end) {  /* inter using second-last frame as reference */
                 int xoffset = (*raw & 0xF) - 7;
                 int yoffset = ((*raw >> 4)) - 7;
-                if (s->last2_frame.data[0])
-                    cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
-                                s->last2_frame.data[0], s->last2_frame.linesize[0],
+                if (s->last2_frame->data[0])
+                    cmv_motcomp(frame->data[0], frame->linesize[0],
+                                s->last2_frame->data[0], s->last2_frame->linesize[0],
                                 x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height);
                 raw++;
             }
         }else{  /* inter using last frame as reference */
             int xoffset = (buf[i] & 0xF) - 7;
             int yoffset = ((buf[i] >> 4)) - 7;
-            cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
-                      s->last_frame.data[0], s->last_frame.linesize[0],
+            cmv_motcomp(frame->data[0], frame->linesize[0],
+                      s->last_frame->data[0], s->last_frame->linesize[0],
                       x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height);
         }
         i++;
@@ -154,6 +166,8 @@ static int cmv_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     CmvContext *s = avctx->priv_data;
     const uint8_t *buf_end = buf + buf_size;
+    AVFrame *frame = data;
+    int ret;
 
     if (buf_end - buf < EA_PREAMBLE_SIZE)
         return AVERROR_INVALIDDATA;
@@ -166,46 +180,39 @@ static int cmv_decode_frame(AVCodecContext *avctx,
     if (av_image_check_size(s->width, s->height, 0, s->avctx))
         return -1;
 
-    /* shuffle */
-    if (s->last2_frame.data[0])
-        avctx->release_buffer(avctx, &s->last2_frame);
-    FFSWAP(AVFrame, s->last_frame, s->last2_frame);
-    FFSWAP(AVFrame, s->frame, s->last_frame);
-
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if (ff_get_buffer(avctx, &s->frame)<0) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
 
     buf += EA_PREAMBLE_SIZE;
     if ((buf[0]&1)) {  // subtype
-        cmv_decode_inter(s, buf+2, buf_end);
-        s->frame.key_frame = 0;
-        s->frame.pict_type = AV_PICTURE_TYPE_P;
+        cmv_decode_inter(s, frame, buf+2, buf_end);
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
     }else{
-        s->frame.key_frame = 1;
-        s->frame.pict_type = AV_PICTURE_TYPE_I;
-        cmv_decode_intra(s, buf+2, buf_end);
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        cmv_decode_intra(s, frame, buf+2, buf_end);
     }
 
+    av_frame_unref(s->last2_frame);
+    av_frame_move_ref(s->last2_frame, s->last_frame);
+    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
 
 static av_cold int cmv_decode_end(AVCodecContext *avctx){
     CmvContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        s->avctx->release_buffer(avctx, &s->frame);
-    if (s->last_frame.data[0])
-        s->avctx->release_buffer(avctx, &s->last_frame);
-    if (s->last2_frame.data[0])
-        s->avctx->release_buffer(avctx, &s->last2_frame);
+
+    av_frame_free(&s->last_frame);
+    av_frame_free(&s->last2_frame);
 
     return 0;
 }
index f9b43a147b7c6f0f1384427cba59d918aa32769a..e666a45360d41eb96fa4db1389fcb37b5bc73480 100644 (file)
@@ -45,7 +45,6 @@
 typedef struct MadContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame frame;
     AVFrame last_frame;
     GetBitContext gb;
     void *bitstream_buf;
@@ -78,34 +77,36 @@ static inline void comp(unsigned char *dst, int dst_stride,
             dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add);
 }
 
-static inline void comp_block(MadContext *t, int mb_x, int mb_y,
+static inline void comp_block(MadContext *t, AVFrame *frame,
+                              int mb_x, int mb_y,
                               int j, int mv_x, int mv_y, int add)
 {
     if (j < 4) {
-        comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
-             t->frame.linesize[0],
+        comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+             frame->linesize[0],
              t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x,
              t->last_frame.linesize[0], add);
     } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
         int index = j - 3;
-        comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8,
-             t->frame.linesize[index],
+        comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8,
+             frame->linesize[index],
              t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2),
              t->last_frame.linesize[index], add);
     }
 }
 
-static inline void idct_put(MadContext *t, int16_t *block, int mb_x, int mb_y, int j)
+static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block,
+                            int mb_x, int mb_y, int j)
 {
     if (j < 4) {
         ff_ea_idct_put_c(
-            t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
-            t->frame.linesize[0], block);
+            frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+            frame->linesize[0], block);
     } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
         int index = j - 3;
         ff_ea_idct_put_c(
-            t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x*8,
-            t->frame.linesize[index], block);
+            frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x*8,
+            frame->linesize[index], block);
     }
 }
 
@@ -179,7 +180,7 @@ static int decode_motion(GetBitContext *gb)
     return value;
 }
 
-static void decode_mb(MadContext *s, int inter)
+static void decode_mb(MadContext *s, AVFrame *frame, int inter)
 {
     int mv_map = 0;
     int mv_x, mv_y;
@@ -199,11 +200,11 @@ static void decode_mb(MadContext *s, int inter)
     for (j=0; j<6; j++) {
         if (mv_map & (1<<j)) {  // mv_x and mv_y are guarded by mv_map
             int add = 2*decode_motion(&s->gb);
-            comp_block(s, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
+            comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
         } else {
             s->dsp.clear_block(s->block);
             decode_block_intra(s, s->block);
-            idct_put(s, s->block, s->mb_x, s->mb_y, j);
+            idct_put(s, frame, s->block, s->mb_x, s->mb_y, j);
         }
     }
 }
@@ -225,9 +226,10 @@ static int decode_frame(AVCodecContext *avctx,
     int buf_size       = avpkt->size;
     const uint8_t *buf_end = buf+buf_size;
     MadContext *s     = avctx->priv_data;
+    AVFrame *frame    = data;
     int width, height;
     int chunk_type;
-    int inter;
+    int inter, ret;
 
     if (buf_size < 17) {
         av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
@@ -251,16 +253,12 @@ static int decode_frame(AVCodecContext *avctx,
         if (av_image_check_size(width, height, 0, avctx) < 0)
             return -1;
         avcodec_set_dimensions(avctx, width, height);
-        if (s->frame.data[0])
-            avctx->release_buffer(avctx, &s->frame);
+        av_frame_unref(&s->last_frame);
     }
 
-    s->frame.reference = 1;
-    if (!s->frame.data[0]) {
-        if (ff_get_buffer(avctx, &s->frame) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
-        }
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
     }
 
     av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
@@ -272,13 +270,15 @@ static int decode_frame(AVCodecContext *avctx,
 
     for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
         for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
-            decode_mb(s, inter);
+            decode_mb(s, frame, inter);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
-    if (chunk_type != MADe_TAG)
-        FFSWAP(AVFrame, s->frame, s->last_frame);
+    if (chunk_type != MADe_TAG) {
+        av_frame_unref(&s->last_frame);
+        if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
+            return ret;
+    }
 
     return buf_size;
 }
@@ -286,10 +286,7 @@ static int decode_frame(AVCodecContext *avctx,
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     MadContext *t = avctx->priv_data;
-    if (t->frame.data[0])
-        avctx->release_buffer(avctx, &t->frame);
-    if (t->last_frame.data[0])
-        avctx->release_buffer(avctx, &t->last_frame);
+    av_frame_unref(&t->last_frame);
     av_free(t->bitstream_buf);
     return 0;
 }
index a020c529926629bfb551747f7ca2d2f84fc0e165..9495066effd3b422b06c8f889c5701945a86fe85 100644 (file)
@@ -39,7 +39,6 @@
 
 typedef struct TgqContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     int width, height;
     ScanTable scantable;
     int qtable[64];
@@ -105,21 +104,21 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb
     block[0] += 128 << 4;
 }
 
-static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64],
+static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame,
                             int mb_x, int mb_y)
 {
-    int linesize = s->frame.linesize[0];
-    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16 * linesize)             + mb_x * 16;
-    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8  * s->frame.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8  * s->frame.linesize[2]) + mb_x * 8;
+    int linesize = frame->linesize[0];
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16 * linesize)           + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8  * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8  * frame->linesize[2]) + mb_x * 8;
 
     ff_ea_idct_put_c(dest_y                   , linesize, block[0]);
     ff_ea_idct_put_c(dest_y                + 8, linesize, block[1]);
     ff_ea_idct_put_c(dest_y + 8 * linesize    , linesize, block[2]);
     ff_ea_idct_put_c(dest_y + 8 * linesize + 8, linesize, block[3]);
     if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
-         ff_ea_idct_put_c(dest_cb, s->frame.linesize[1], block[4]);
-         ff_ea_idct_put_c(dest_cr, s->frame.linesize[2], block[5]);
+         ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]);
+         ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
@@ -132,23 +131,24 @@ static inline void tgq_dconly(TgqContext *s, unsigned char *dst,
         memset(dst + j * dst_stride, level, 8);
 }
 
-static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8_t *dc)
+static void tgq_idct_put_mb_dconly(TgqContext *s, AVFrame *frame,
+                                   int mb_x, int mb_y, const int8_t *dc)
 {
-    int linesize = s->frame.linesize[0];
-    uint8_t *dest_y  = s->frame.data[0] + (mb_y * 16 * linesize)             + mb_x * 16;
-    uint8_t *dest_cb = s->frame.data[1] + (mb_y * 8  * s->frame.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = s->frame.data[2] + (mb_y * 8  * s->frame.linesize[2]) + mb_x * 8;
+    int linesize = frame->linesize[0];
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16 * linesize)             + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8  * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8  * frame->linesize[2]) + mb_x * 8;
     tgq_dconly(s, dest_y,                    linesize, dc[0]);
     tgq_dconly(s, dest_y                + 8, linesize, dc[1]);
     tgq_dconly(s, dest_y + 8 * linesize,     linesize, dc[2]);
     tgq_dconly(s, dest_y + 8 * linesize + 8, linesize, dc[3]);
     if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
-        tgq_dconly(s, dest_cb, s->frame.linesize[1], dc[4]);
-        tgq_dconly(s, dest_cr, s->frame.linesize[2], dc[5]);
+        tgq_dconly(s, dest_cb, frame->linesize[1], dc[4]);
+        tgq_dconly(s, dest_cr, frame->linesize[2], dc[5]);
     }
 }
 
-static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x)
+static void tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x)
 {
     int mode;
     int i;
@@ -160,7 +160,7 @@ static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x)
         init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8);
         for (i = 0; i < 6; i++)
             tgq_decode_block(s, s->block[i], &gb);
-        tgq_idct_put_mb(s, s->block, mb_x, mb_y);
+        tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y);
         bytestream2_skip(&s->gb, mode);
     } else {
         if (mode == 3) {
@@ -177,7 +177,7 @@ static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x)
         } else {
             av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
         }
-        tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc);
+        tgq_idct_put_mb_dconly(s, frame, mb_x, mb_y, dc);
     }
 }
 
@@ -199,6 +199,7 @@ static int tgq_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     TgqContext *s      = avctx->priv_data;
+    AVFrame *frame     = data;
     int x, y, ret;
     int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF;
 
@@ -217,47 +218,32 @@ static int tgq_decode_frame(AVCodecContext *avctx,
 
     if (s->avctx->width!=s->width || s->avctx->height!=s->height) {
         avcodec_set_dimensions(s->avctx, s->width, s->height);
-        if (s->frame.data[0])
-            avctx->release_buffer(avctx, &s->frame);
     }
     tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb));
     bytestream2_skip(&s->gb, 3);
 
-    if (!s->frame.data[0]) {
-        s->frame.key_frame = 1;
-        s->frame.pict_type = AV_PICTURE_TYPE_I;
-        s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-        if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return ret;
-        }
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
     }
+    frame->key_frame = 1;
+    frame->pict_type = AV_PICTURE_TYPE_I;
 
     for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++)
         for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++)
-            tgq_decode_mb(s, y, x);
+            tgq_decode_mb(s, frame, y, x);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return avpkt->size;
 }
 
-static av_cold int tgq_decode_end(AVCodecContext *avctx)
-{
-    TgqContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        s->avctx->release_buffer(avctx, &s->frame);
-    return 0;
-}
-
 AVCodec ff_eatgq_decoder = {
     .name           = "eatgq",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TGQ,
     .priv_data_size = sizeof(TgqContext),
     .init           = tgq_decode_init,
-    .close          = tgq_decode_end,
     .decode         = tgq_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGQ video"),
index 792eaf708e87076d820db9d883211bd6eef017d6..1e0ec60bc5d53f03413029356d710b3834853c7f 100644 (file)
@@ -31,6 +31,7 @@
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mem.h"
 
@@ -39,8 +40,8 @@
 
 typedef struct TgvContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     AVFrame last_frame;
+    uint8_t *frame_buffer;
     int width,height;
     uint32_t palette[AVPALETTE_COUNT];
 
@@ -138,8 +139,8 @@ static int unpack(const uint8_t *src, const uint8_t *src_end,
  * Decode inter-frame
  * @return 0 on success, -1 on critical buffer underflow
  */
-static int tgv_decode_inter(TgvContext *s, const uint8_t *buf,
-                            const uint8_t *buf_end)
+static int tgv_decode_inter(TgvContext *s, AVFrame *frame,
+                            const uint8_t *buf, const uint8_t *buf_end)
 {
     int num_mvs;
     int num_blocks_raw;
@@ -237,22 +238,13 @@ static int tgv_decode_inter(TgvContext *s, const uint8_t *buf,
 
             for (j = 0; j < 4; j++)
                 for (i = 0; i < 4; i++)
-                    s->frame.data[0][(y * 4 + j) * s->frame.linesize[0] + (x * 4 + i)] =
+                    frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * 4 + i)] =
                         src[j * src_stride + i];
     }
 
     return 0;
 }
 
-/** release AVFrame buffers if allocated */
-static void cond_release_buffer(AVFrame *pic)
-{
-    if (pic->data[0]) {
-        av_freep(&pic->data[0]);
-        av_free(pic->data[1]);
-    }
-}
-
 static int tgv_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
@@ -261,6 +253,7 @@ static int tgv_decode_frame(AVCodecContext *avctx,
     int buf_size           = avpkt->size;
     TgvContext *s          = avctx->priv_data;
     const uint8_t *buf_end = buf + buf_size;
+    AVFrame *frame         = data;
     int chunk_type, ret;
 
     chunk_type = AV_RL32(&buf[0]);
@@ -277,8 +270,8 @@ static int tgv_decode_frame(AVCodecContext *avctx,
         s->height = AV_RL16(&buf[2]);
         if (s->avctx->width != s->width || s->avctx->height != s->height) {
             avcodec_set_dimensions(s->avctx, s->width, s->height);
-            cond_release_buffer(&s->frame);
-            cond_release_buffer(&s->last_frame);
+            av_freep(&s->frame_buffer);
+            av_frame_unref(&s->last_frame);
         }
 
         pal_count = AV_RL16(&buf[6]);
@@ -292,46 +285,46 @@ static int tgv_decode_frame(AVCodecContext *avctx,
     if ((ret = av_image_check_size(s->width, s->height, 0, avctx)) < 0)
         return ret;
 
-    /* shuffle */
-    FFSWAP(AVFrame, s->frame, s->last_frame);
-    if (!s->frame.data[0]) {
-        s->frame.reference = 1;
-        s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-        s->frame.linesize[0] = s->width;
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
+        return ret;
 
-        s->frame.data[0] = av_malloc(s->width * s->height);
-        if (!s->frame.data[0])
-            return AVERROR(ENOMEM);
-        s->frame.data[1] = av_malloc(AVPALETTE_SIZE);
-        if (!s->frame.data[1]) {
-            av_freep(&s->frame.data[0]);
-            return AVERROR(ENOMEM);
-        }
-    }
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
 
     if (chunk_type == kVGT_TAG) {
-        s->frame.key_frame = 1;
-        s->frame.pict_type = AV_PICTURE_TYPE_I;
-        if (unpack(buf, buf_end, s->frame.data[0], s->avctx->width, s->avctx->height) < 0) {
+        int y;
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
+
+        if (!s->frame_buffer &&
+            !(s->frame_buffer = av_malloc(s->width * s->height)))
+            return AVERROR(ENOMEM);
+
+        if (unpack(buf, buf_end, s->frame_buffer, s->avctx->width, s->avctx->height) < 0) {
             av_log(avctx, AV_LOG_WARNING, "truncated intra frame\n");
             return AVERROR_INVALIDDATA;
         }
+        for (y = 0; y < s->height; y++)
+            memcpy(frame->data[0]  + y * frame->linesize[0],
+                   s->frame_buffer + y * s->width,
+                   s->width);
     } else {
         if (!s->last_frame.data[0]) {
             av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n");
             return buf_size;
         }
-        s->frame.key_frame = 0;
-        s->frame.pict_type = AV_PICTURE_TYPE_P;
-        if (tgv_decode_inter(s, buf, buf_end) < 0) {
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        if (tgv_decode_inter(s, frame, buf, buf_end) < 0) {
             av_log(avctx, AV_LOG_WARNING, "truncated inter frame\n");
             return AVERROR_INVALIDDATA;
         }
     }
 
+    av_frame_unref(&s->last_frame);
+    if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -339,8 +332,8 @@ static int tgv_decode_frame(AVCodecContext *avctx,
 static av_cold int tgv_decode_end(AVCodecContext *avctx)
 {
     TgvContext *s = avctx->priv_data;
-    cond_release_buffer(&s->frame);
-    cond_release_buffer(&s->last_frame);
+    av_frame_unref(&s->last_frame);
+    av_freep(&s->frame_buffer);
     av_free(s->mv_codebook);
     av_free(s->block_codebook);
     return 0;
@@ -355,4 +348,5 @@ AVCodec ff_eatgv_decoder = {
     .close          = tgv_decode_end,
     .decode         = tgv_decode_frame,
     .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts TGV video"),
+    .capabilities   = CODEC_CAP_DR1,
 };
index caf92366e1e9c517738df3ecb33ea372e327c703..eba4b6f390957251dfa0f2db0b194684e0c3c89f 100644 (file)
@@ -36,7 +36,6 @@
 
 typedef struct TqiContext {
     MpegEncContext s;
-    AVFrame frame;
     void *bitstream_buf;
     unsigned int bitstream_buf_size;
     DECLARE_ALIGNED(16, int16_t, block)[6][64];
@@ -68,21 +67,21 @@ static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64])
     return 0;
 }
 
-static inline void tqi_idct_put(TqiContext *t, int16_t (*block)[64])
+static inline void tqi_idct_put(TqiContext *t, AVFrame *frame, int16_t (*block)[64])
 {
     MpegEncContext *s = &t->s;
-    int linesize= t->frame.linesize[0];
-    uint8_t *dest_y  = t->frame.data[0] + (s->mb_y * 16* linesize            ) + s->mb_x * 16;
-    uint8_t *dest_cb = t->frame.data[1] + (s->mb_y * 8 * t->frame.linesize[1]) + s->mb_x * 8;
-    uint8_t *dest_cr = t->frame.data[2] + (s->mb_y * 8 * t->frame.linesize[2]) + s->mb_x * 8;
+    int linesize = frame->linesize[0];
+    uint8_t *dest_y  = frame->data[0] + (s->mb_y * 16* linesize            ) + s->mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (s->mb_y * 8 * frame->linesize[1]) + s->mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (s->mb_y * 8 * frame->linesize[2]) + s->mb_x * 8;
 
     ff_ea_idct_put_c(dest_y                 , linesize, block[0]);
     ff_ea_idct_put_c(dest_y              + 8, linesize, block[1]);
     ff_ea_idct_put_c(dest_y + 8*linesize    , linesize, block[2]);
     ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]);
     if(!(s->avctx->flags&CODEC_FLAG_GRAY)) {
-        ff_ea_idct_put_c(dest_cb, t->frame.linesize[1], block[4]);
-        ff_ea_idct_put_c(dest_cr, t->frame.linesize[2], block[5]);
+        ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]);
+        ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
@@ -104,21 +103,20 @@ static int tqi_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf_end = buf+buf_size;
     TqiContext *t = avctx->priv_data;
     MpegEncContext *s = &t->s;
+    AVFrame *frame = data;
+    int ret;
 
     s->width  = AV_RL16(&buf[0]);
     s->height = AV_RL16(&buf[2]);
     tqi_calculate_qtable(s, buf[4]);
     buf += 8;
 
-    if (t->frame.data[0])
-        avctx->release_buffer(avctx, &t->frame);
-
     if (s->avctx->width!=s->width || s->avctx->height!=s->height)
         avcodec_set_dimensions(s->avctx, s->width, s->height);
 
-    if(ff_get_buffer(avctx, &t->frame) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     av_fast_padded_malloc(&t->bitstream_buf, &t->bitstream_buf_size,
@@ -134,19 +132,16 @@ static int tqi_decode_frame(AVCodecContext *avctx,
     {
         if (tqi_decode_mb(s, t->block) < 0)
             break;
-        tqi_idct_put(t, t->block);
+        tqi_idct_put(t, frame, t->block);
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = t->frame;
     return buf_size;
 }
 
 static av_cold int tqi_decode_end(AVCodecContext *avctx)
 {
     TqiContext *t = avctx->priv_data;
-    if(t->frame.data[0])
-        avctx->release_buffer(avctx, &t->frame);
     av_free(t->bitstream_buf);
     return 0;
 }
index 39892e43b3c70a98118fa530b27383e654828311..78921e3fcff3e84baca198d5e26fcbe26fbf648e 100644 (file)
@@ -143,7 +143,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
             mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
             error    = s->error_status_table[mb_index];
 
-            if (IS_INTER(s->cur_pic->f.mb_type[mb_index]))
+            if (IS_INTER(s->cur_pic->mb_type[mb_index]))
                 continue; // inter
             if (!(error & ER_DC_ERROR))
                 continue; // dc-ok
@@ -152,7 +152,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
             for (j = b_x + 1; j < w; j++) {
                 int mb_index_j = (j >> is_luma) + (b_y >> is_luma) * s->mb_stride;
                 int error_j    = s->error_status_table[mb_index_j];
-                int intra_j    = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
+                int intra_j    = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
                 if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
                     color[0]    = dc[j + b_y * stride];
                     distance[0] = j - b_x;
@@ -164,7 +164,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
             for (j = b_x - 1; j >= 0; j--) {
                 int mb_index_j = (j >> is_luma) + (b_y >> is_luma) * s->mb_stride;
                 int error_j    = s->error_status_table[mb_index_j];
-                int intra_j    = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
+                int intra_j    = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
                 if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
                     color[1]    = dc[j + b_y * stride];
                     distance[1] = b_x - j;
@@ -176,7 +176,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
             for (j = b_y + 1; j < h; j++) {
                 int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride;
                 int error_j    = s->error_status_table[mb_index_j];
-                int intra_j    = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
+                int intra_j    = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
 
                 if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
                     color[2]    = dc[b_x + j * stride];
@@ -189,7 +189,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
             for (j = b_y - 1; j >= 0; j--) {
                 int mb_index_j = (b_x >> is_luma) + (j >> is_luma) * s->mb_stride;
                 int error_j    = s->error_status_table[mb_index_j];
-                int intra_j    = IS_INTRA(s->cur_pic->f.mb_type[mb_index_j]);
+                int intra_j    = IS_INTRA(s->cur_pic->mb_type[mb_index_j]);
                 if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
                     color[3]    = dc[b_x + j * stride];
                     distance[3] = b_y - j;
@@ -229,13 +229,13 @@ static void h_block_filter(ERContext *s, uint8_t *dst, int w,
             int y;
             int left_status  = s->error_status_table[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride];
             int right_status = s->error_status_table[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride];
-            int left_intra   = IS_INTRA(s->cur_pic->f.mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
-            int right_intra  = IS_INTRA(s->cur_pic->f.mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+            int left_intra   = IS_INTRA(s->cur_pic->mb_type[( b_x      >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
+            int right_intra  = IS_INTRA(s->cur_pic->mb_type[((b_x + 1) >> is_luma) + (b_y >> is_luma) * s->mb_stride]);
             int left_damage  = left_status & ER_MB_ERROR;
             int right_damage = right_status & ER_MB_ERROR;
             int offset       = b_x * 8 + b_y * stride * 8;
-            int16_t *left_mv  = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
-            int16_t *right_mv = s->cur_pic->f.motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
+            int16_t *left_mv  = s->cur_pic->motion_val[0][mvy_stride * b_y + mvx_stride *  b_x];
+            int16_t *right_mv = s->cur_pic->motion_val[0][mvy_stride * b_y + mvx_stride * (b_x + 1)];
             if (!(left_damage || right_damage))
                 continue; // both undamaged
             if ((!left_intra) && (!right_intra) &&
@@ -297,14 +297,14 @@ static void v_block_filter(ERContext *s, uint8_t *dst, int w, int h,
             int x;
             int top_status    = s->error_status_table[(b_x >> is_luma) +  (b_y      >> is_luma) * s->mb_stride];
             int bottom_status = s->error_status_table[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride];
-            int top_intra     = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
-            int bottom_intra  = IS_INTRA(s->cur_pic->f.mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
+            int top_intra     = IS_INTRA(s->cur_pic->mb_type[(b_x >> is_luma) + ( b_y      >> is_luma) * s->mb_stride]);
+            int bottom_intra  = IS_INTRA(s->cur_pic->mb_type[(b_x >> is_luma) + ((b_y + 1) >> is_luma) * s->mb_stride]);
             int top_damage    = top_status & ER_MB_ERROR;
             int bottom_damage = bottom_status & ER_MB_ERROR;
             int offset        = b_x * 8 + b_y * stride * 8;
 
-            int16_t *top_mv    = s->cur_pic->f.motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
-            int16_t *bottom_mv = s->cur_pic->f.motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
+            int16_t *top_mv    = s->cur_pic->motion_val[0][mvy_stride *  b_y      + mvx_stride * b_x];
+            int16_t *bottom_mv = s->cur_pic->motion_val[0][mvy_stride * (b_y + 1) + mvx_stride * b_x];
 
             if (!(top_damage || bottom_damage))
                 continue; // both undamaged
@@ -369,7 +369,7 @@ static void guess_mv(ERContext *s)
         int f = 0;
         int error = s->error_status_table[mb_xy];
 
-        if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
+        if (IS_INTRA(s->cur_pic->mb_type[mb_xy]))
             f = MV_FROZEN; // intra // FIXME check
         if (!(error & ER_MV_ERROR))
             f = MV_FROZEN; // inter with undamaged MV
@@ -386,7 +386,7 @@ static void guess_mv(ERContext *s)
                 const int mb_xy = mb_x + mb_y * s->mb_stride;
                 int mv_dir = (s->last_pic && s->last_pic->f.data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
 
-                if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
+                if (IS_INTRA(s->cur_pic->mb_type[mb_xy]))
                     continue;
                 if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
                     continue;
@@ -427,7 +427,7 @@ static void guess_mv(ERContext *s)
 
                     if (fixed[mb_xy] == MV_FROZEN)
                         continue;
-                    assert(!IS_INTRA(s->cur_pic->f.mb_type[mb_xy]));
+                    assert(!IS_INTRA(s->cur_pic->mb_type[mb_xy]));
                     assert(s->last_pic && s->last_pic->f.data[0]);
 
                     j = 0;
@@ -458,38 +458,38 @@ static void guess_mv(ERContext *s)
 
                     if (mb_x > 0 && fixed[mb_xy - 1]) {
                         mv_predictor[pred_count][0] =
-                            s->cur_pic->f.motion_val[0][mot_index - mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index - mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->cur_pic->f.motion_val[0][mot_index - mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index - mot_step][1];
                         ref[pred_count] =
-                            s->cur_pic->f.ref_index[0][4 * (mb_xy - 1)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy - 1)];
                         pred_count++;
                     }
                     if (mb_x + 1 < mb_width && fixed[mb_xy + 1]) {
                         mv_predictor[pred_count][0] =
-                            s->cur_pic->f.motion_val[0][mot_index + mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index + mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->cur_pic->f.motion_val[0][mot_index + mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index + mot_step][1];
                         ref[pred_count] =
-                            s->cur_pic->f.ref_index[0][4 * (mb_xy + 1)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy + 1)];
                         pred_count++;
                     }
                     if (mb_y > 0 && fixed[mb_xy - mb_stride]) {
                         mv_predictor[pred_count][0] =
-                            s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index - mot_stride * mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->cur_pic->f.motion_val[0][mot_index - mot_stride * mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index - mot_stride * mot_step][1];
                         ref[pred_count] =
-                            s->cur_pic->f.ref_index[0][4 * (mb_xy - s->mb_stride)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy - s->mb_stride)];
                         pred_count++;
                     }
                     if (mb_y + 1<mb_height && fixed[mb_xy + mb_stride]) {
                         mv_predictor[pred_count][0] =
-                            s->cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][0];
+                            s->cur_pic->motion_val[0][mot_index + mot_stride * mot_step][0];
                         mv_predictor[pred_count][1] =
-                            s->cur_pic->f.motion_val[0][mot_index + mot_stride * mot_step][1];
+                            s->cur_pic->motion_val[0][mot_index + mot_stride * mot_step][1];
                         ref[pred_count] =
-                            s->cur_pic->f.ref_index[0][4 * (mb_xy + s->mb_stride)];
+                            s->cur_pic->ref_index[0][4 * (mb_xy + s->mb_stride)];
                         pred_count++;
                     }
                     if (pred_count == 0)
@@ -547,19 +547,19 @@ skip_mean_and_median:
                         if (s->avctx->codec_id == AV_CODEC_ID_H264) {
                             // FIXME
                         } else {
-                            ff_thread_await_progress(&s->last_pic->f,
+                            ff_thread_await_progress(&s->last_pic->tf,
                                                      mb_y, 0);
                         }
-                        if (!s->last_pic->f.motion_val[0] ||
-                            !s->last_pic->f.ref_index[0])
+                        if (!s->last_pic->motion_val[0] ||
+                            !s->last_pic->ref_index[0])
                             goto skip_last_mv;
-                        prev_x   = s->last_pic->f.motion_val[0][mot_index][0];
-                        prev_y   = s->last_pic->f.motion_val[0][mot_index][1];
-                        prev_ref = s->last_pic->f.ref_index[0][4 * mb_xy];
+                        prev_x   = s->last_pic->motion_val[0][mot_index][0];
+                        prev_y   = s->last_pic->motion_val[0][mot_index][1];
+                        prev_ref = s->last_pic->ref_index[0][4 * mb_xy];
                     } else {
-                        prev_x   = s->cur_pic->f.motion_val[0][mot_index][0];
-                        prev_y   = s->cur_pic->f.motion_val[0][mot_index][1];
-                        prev_ref = s->cur_pic->f.ref_index[0][4 * mb_xy];
+                        prev_x   = s->cur_pic->motion_val[0][mot_index][0];
+                        prev_y   = s->cur_pic->motion_val[0][mot_index][1];
+                        prev_ref = s->cur_pic->ref_index[0][4 * mb_xy];
                     }
 
                     /* last MV */
@@ -576,9 +576,9 @@ skip_last_mv:
                         uint8_t *src = s->cur_pic->f.data[0] +
                                        mb_x * 16 + mb_y * 16 * linesize[0];
 
-                        s->cur_pic->f.motion_val[0][mot_index][0] =
+                        s->cur_pic->motion_val[0][mot_index][0] =
                             s->mv[0][0][0] = mv_predictor[j][0];
-                        s->cur_pic->f.motion_val[0][mot_index][1] =
+                        s->cur_pic->motion_val[0][mot_index][1] =
                             s->mv[0][0][1] = mv_predictor[j][1];
 
                         // predictor intra or otherwise not available
@@ -623,8 +623,8 @@ skip_last_mv:
 
                     for (i = 0; i < mot_step; i++)
                         for (j = 0; j < mot_step; j++) {
-                            s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
-                            s->cur_pic->f.motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
+                            s->cur_pic->motion_val[0][mot_index + i + j * mot_stride][0] = s->mv[0][0][0];
+                            s->cur_pic->motion_val[0][mot_index + i + j * mot_stride][1] = s->mv[0][0][1];
                         }
 
                     s->decode_mb(s->opaque, ref[best_pred], MV_DIR_FORWARD,
@@ -706,7 +706,7 @@ static int is_intra_more_likely(ERContext *s)
                 if (s->avctx->codec_id == AV_CODEC_ID_H264) {
                     // FIXME
                 } else {
-                    ff_thread_await_progress(&s->last_pic->f, mb_y, 0);
+                    ff_thread_await_progress(&s->last_pic->tf, mb_y, 0);
                 }
                 is_intra_likely += s->dsp->sad[0](NULL, last_mb_ptr, mb_ptr,
                                                  linesize[0], 16);
@@ -714,7 +714,7 @@ static int is_intra_more_likely(ERContext *s)
                                                  last_mb_ptr + linesize[0] * 16,
                                                  linesize[0], 16);
             } else {
-                if (IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
+                if (IS_INTRA(s->cur_pic->mb_type[mb_xy]))
                    is_intra_likely++;
                 else
                    is_intra_likely--;
@@ -831,13 +831,25 @@ void ff_er_frame_end(ERContext *s)
         return;
     };
 
-    if (s->cur_pic->f.motion_val[0] == NULL) {
+    if (s->cur_pic->motion_val[0] == NULL) {
         av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
 
         for (i = 0; i < 2; i++) {
-            s->cur_pic->f.ref_index[i]     = av_mallocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
-            s->cur_pic->motion_val_base[i] = av_mallocz((size + 4) * 2 * sizeof(uint16_t));
-            s->cur_pic->f.motion_val[i]    = s->cur_pic->motion_val_base[i] + 4;
+            s->cur_pic->ref_index_buf[i]  = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));
+            s->cur_pic->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));
+            if (!s->cur_pic->ref_index_buf[i] || !s->cur_pic->motion_val_buf[i])
+                break;
+            s->cur_pic->ref_index[i]  = s->cur_pic->ref_index_buf[i]->data;
+            s->cur_pic->motion_val[i] = (int16_t (*)[2])s->cur_pic->motion_val_buf[i]->data + 4;
+        }
+        if (i < 2) {
+            for (i = 0; i < 2; i++) {
+                av_buffer_unref(&s->cur_pic->ref_index_buf[i]);
+                av_buffer_unref(&s->cur_pic->motion_val_buf[i]);
+                s->cur_pic->ref_index[i]  = NULL;
+                s->cur_pic->motion_val[i] = NULL;
+            }
+            return;
         }
         s->cur_pic->f.motion_subsample_log2 = 3;
     }
@@ -997,9 +1009,9 @@ void ff_er_frame_end(ERContext *s)
             continue;
 
         if (is_intra_likely)
-            s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
+            s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4;
         else
-            s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+            s->cur_pic->mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;
     }
 
     // change inter to intra blocks if no reference frames are available
@@ -1007,15 +1019,15 @@ void ff_er_frame_end(ERContext *s)
         !(s->next_pic && s->next_pic->f.data[0]))
         for (i = 0; i < s->mb_num; i++) {
             const int mb_xy = s->mb_index2xy[i];
-            if (!IS_INTRA(s->cur_pic->f.mb_type[mb_xy]))
-                s->cur_pic->f.mb_type[mb_xy] = MB_TYPE_INTRA4x4;
+            if (!IS_INTRA(s->cur_pic->mb_type[mb_xy]))
+                s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4;
         }
 
     /* handle inter blocks with damaged AC */
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->cur_pic->f.mb_type[mb_xy];
+            const int mb_type = s->cur_pic->mb_type[mb_xy];
             const int dir     = !(s->last_pic && s->last_pic->f.data[0]);
             const int mv_dir  = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;
             int mv_type;
@@ -1034,13 +1046,13 @@ void ff_er_frame_end(ERContext *s)
                 int j;
                 mv_type = MV_TYPE_8X8;
                 for (j = 0; j < 4; j++) {
-                    s->mv[0][j][0] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
-                    s->mv[0][j][1] = s->cur_pic->f.motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
+                    s->mv[0][j][0] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];
+                    s->mv[0][j][1] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];
                 }
             } else {
                 mv_type     = MV_TYPE_16X16;
-                s->mv[0][0][0] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
-                s->mv[0][0][1] = s->cur_pic->f.motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
+                s->mv[0][0][0] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];
+                s->mv[0][0][1] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];
             }
 
             s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */,
@@ -1054,7 +1066,7 @@ void ff_er_frame_end(ERContext *s)
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                 int       xy      = mb_x * 2 + mb_y * 2 * s->b8_stride;
                 const int mb_xy   = mb_x + mb_y * s->mb_stride;
-                const int mb_type = s->cur_pic->f.mb_type[mb_xy];
+                const int mb_type = s->cur_pic->mb_type[mb_xy];
                 int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
 
                 error = s->error_status_table[mb_xy];
@@ -1075,12 +1087,12 @@ void ff_er_frame_end(ERContext *s)
                     int time_pp = s->pp_time;
                     int time_pb = s->pb_time;
 
-                    ff_thread_await_progress(&s->next_pic->f, mb_y, 0);
+                    ff_thread_await_progress(&s->next_pic->tf, mb_y, 0);
 
-                    s->mv[0][0][0] = s->next_pic->f.motion_val[0][xy][0] *  time_pb            / time_pp;
-                    s->mv[0][0][1] = s->next_pic->f.motion_val[0][xy][1] *  time_pb            / time_pp;
-                    s->mv[1][0][0] = s->next_pic->f.motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
-                    s->mv[1][0][1] = s->next_pic->f.motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
+                    s->mv[0][0][0] = s->next_pic->motion_val[0][xy][0] *  time_pb            / time_pp;
+                    s->mv[0][0][1] = s->next_pic->motion_val[0][xy][1] *  time_pb            / time_pp;
+                    s->mv[1][0][0] = s->next_pic->motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;
+                    s->mv[1][0][1] = s->next_pic->motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;
                 } else {
                     s->mv[0][0][0] = 0;
                     s->mv[0][0][1] = 0;
@@ -1105,7 +1117,7 @@ void ff_er_frame_end(ERContext *s)
             int16_t *dc_ptr;
             uint8_t *dest_y, *dest_cb, *dest_cr;
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->cur_pic->f.mb_type[mb_xy];
+            const int mb_type = s->cur_pic->mb_type[mb_xy];
 
             error = s->error_status_table[mb_xy];
 
@@ -1156,7 +1168,7 @@ void ff_er_frame_end(ERContext *s)
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
             uint8_t *dest_y, *dest_cb, *dest_cr;
             const int mb_xy   = mb_x + mb_y * s->mb_stride;
-            const int mb_type = s->cur_pic->f.mb_type[mb_xy];
+            const int mb_type = s->cur_pic->mb_type[mb_xy];
 
             error = s->error_status_table[mb_xy];
 
index a27ab6890dc88a74e131fbd9a1de733d9278888b..b304dd8b39579b3acde5a2d9604fd0dfbf4c864c 100644 (file)
@@ -78,8 +78,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx)
     for (i = 0; i < 3; i++)
         av_free(s->codebooks[i].blocks);
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
@@ -203,6 +202,7 @@ static int escape124_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     Escape124Context *s = avctx->priv_data;
+    AVFrame *frame = data;
 
     GetBitContext gb;
     unsigned frame_flags, frame_size;
@@ -214,8 +214,7 @@ static int escape124_decode_frame(AVCodecContext *avctx,
 
     uint16_t* old_frame_data, *new_frame_data;
     unsigned old_stride, new_stride;
-
-    AVFrame new_frame = { { 0 } };
+    int ret;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -230,10 +229,14 @@ static int escape124_decode_frame(AVCodecContext *avctx,
     // Leave last frame unchanged
     // FIXME: Is this necessary?  I haven't seen it in any real samples
     if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) {
+        if (!s->frame.data[0])
+            return AVERROR_INVALIDDATA;
+
         av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n");
 
         *got_frame = 1;
-        *(AVFrame*)data = s->frame;
+        if ((ret = av_frame_ref(frame, &s->frame)) < 0)
+            return ret;
 
         return frame_size;
     }
@@ -266,14 +269,13 @@ static int escape124_decode_frame(AVCodecContext *avctx,
         }
     }
 
-    new_frame.reference = 3;
-    if (ff_get_buffer(avctx, &new_frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    new_frame_data = (uint16_t*)new_frame.data[0];
-    new_stride = new_frame.linesize[0] / 2;
+    new_frame_data = (uint16_t*)frame->data[0];
+    new_stride = frame->linesize[0] / 2;
     old_frame_data = (uint16_t*)s->frame.data[0];
     old_stride = s->frame.linesize[0] / 2;
 
@@ -354,10 +356,10 @@ static int escape124_decode_frame(AVCodecContext *avctx,
            "Escape sizes: %i, %i, %i\n",
            frame_size, buf_size, get_bits_count(&gb) / 8);
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
+    if ((ret = av_frame_ref(&s->frame, frame)) < 0)
+        return ret;
 
-    *(AVFrame*)data = s->frame = new_frame;
     *got_frame = 1;
 
     return frame_size;
index d37230c6c15c5c6c9eb32a68b781f2c7a69134bf..81c684c2fee39a6391285db0b5c2189888ca9293 100644 (file)
@@ -266,10 +266,7 @@ av_cold int ffv1_close(AVCodecContext *avctx)
     FFV1Context *s = avctx->priv_data;
     int i, j;
 
-    if (avctx->codec->decode && s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-    if (avctx->codec->decode && s->last_picture.data[0])
-        avctx->release_buffer(avctx, &s->last_picture);
+    av_frame_unref(&s->last_picture);
 
     for (j = 0; j < s->slice_count; j++) {
         FFV1Context *fs = s->slice_context[j];
index 4752cea95148c9ed1b221d9146c6dce1412be677..43c96079ae5fe3bfdc902d741b9e0c965b3ff1ac 100644 (file)
@@ -80,6 +80,8 @@ typedef struct FFV1Context {
     int flags;
     int picture_number;
     AVFrame picture, last_picture;
+
+    AVFrame *cur;
     int plane_count;
     int ac;     // 1 = range coder <-> 0 = golomb rice
     int ac_byte_count;      // number of bytes used for AC coding
index a1b3db360c43c08091663f7544c00f3cef41f18e..f9b094dab7c18e37727a5e9e15391aef7f1cd5ed 100644 (file)
@@ -316,16 +316,16 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs)
 
     ps = get_symbol(c, state, 0);
     if (ps == 1) {
-        f->picture.interlaced_frame = 1;
-        f->picture.top_field_first  = 1;
+        f->cur->interlaced_frame = 1;
+        f->cur->top_field_first  = 1;
     } else if (ps == 2) {
-        f->picture.interlaced_frame = 1;
-        f->picture.top_field_first  = 0;
+        f->cur->interlaced_frame = 1;
+        f->cur->top_field_first  = 0;
     } else if (ps == 3) {
-        f->picture.interlaced_frame = 0;
+        f->cur->interlaced_frame = 0;
     }
-    f->picture.sample_aspect_ratio.num = get_symbol(c, state, 0);
-    f->picture.sample_aspect_ratio.den = get_symbol(c, state, 0);
+    f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0);
+    f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0);
 
     return 0;
 }
@@ -338,7 +338,7 @@ static int decode_slice(AVCodecContext *c, void *arg)
     const int ps = (av_pix_fmt_desc_get(c->pix_fmt)->flags & PIX_FMT_PLANAR)
                    ? (c->bits_per_raw_sample > 8) + 1
                    : 4;
-    AVFrame *const p = &f->picture;
+    AVFrame *const p = f->cur;
 
     if (f->version > 2) {
         if (decode_slice_header(f, fs) < 0) {
@@ -348,7 +348,7 @@ static int decode_slice(AVCodecContext *c, void *arg)
     }
     if ((ret = ffv1_init_slice_state(f, fs)) < 0)
         return ret;
-    if (f->picture.key_frame)
+    if (f->cur->key_frame)
         ffv1_clear_slice_state(f, fs);
     width  = fs->slice_width;
     height = fs->slice_height;
@@ -799,16 +799,12 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
     int buf_size        = avpkt->size;
     FFV1Context *f      = avctx->priv_data;
     RangeCoder *const c = &f->slice_context[0]->c;
-    AVFrame *const p    = &f->picture;
     int i, ret;
     uint8_t keystate = 128;
     const uint8_t *buf_p;
+    AVFrame *const p    = data;
 
-    AVFrame *picture = data;
-
-    /* release previously stored data */
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
+    f->cur = p;
 
     ff_init_range_decoder(c, buf, buf_size);
     ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
@@ -829,8 +825,7 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
         p->key_frame = 0;
     }
 
-    p->reference = 3; //for error concealment
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -869,6 +864,8 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
             ff_init_range_decoder(&fs->c, buf_p, v);
         } else
             fs->c.bytestream_end = (uint8_t *)(buf_p + v);
+
+        fs->cur = p;
     }
 
     avctx->execute(avctx, decode_slice, &f->slice_context[0], NULL,
@@ -884,13 +881,13 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
             for (j = 0; j < 4; j++) {
                 int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0;
                 int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0;
-                dst[j] = f->picture.data[j] + f->picture.linesize[j] *
+                dst[j] = p->data[j] + p->linesize[j] *
                          (fs->slice_y >> sv) + (fs->slice_x >> sh);
                 src[j] = f->last_picture.data[j] +
                          f->last_picture.linesize[j] *
                          (fs->slice_y >> sv) + (fs->slice_x >> sh);
             }
-            av_image_copy(dst, f->picture.linesize, (const uint8_t **)src,
+            av_image_copy(dst, p->linesize, (const uint8_t **)src,
                           f->last_picture.linesize,
                           avctx->pix_fmt, fs->slice_width,
                           fs->slice_height);
@@ -899,10 +896,12 @@ static int ffv1_decode_frame(AVCodecContext *avctx, void *data,
 
     f->picture_number++;
 
-    *picture   = *p;
-    *got_frame = 1;
+    av_frame_unref(&f->last_picture);
+    if ((ret = av_frame_ref(&f->last_picture, p)) < 0)
+        return ret;
+    f->cur = NULL;
 
-    FFSWAP(AVFrame, f->picture, f->last_picture);
+    *got_frame = 1;
 
     return buf_size;
 }
index 6bb6be347778cc963efef0dfcacb1572a6c62835..91412ef82140ad68b6d30efbd43df61ff90eed59 100644 (file)
@@ -529,7 +529,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = s->blocksize;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 3c5a35c0dd35347e84b5d460edd4135f574c6473..3f211926e36ddec589958844ff68b3455443531c 100644 (file)
@@ -41,6 +41,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct BlockInfo {
     uint8_t *pos;
@@ -238,7 +239,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
 {
     int buf_size       = avpkt->size;
     FlashSVContext *s  = avctx->priv_data;
-    int h_blocks, v_blocks, h_part, v_part, i, j;
+    int h_blocks, v_blocks, h_part, v_part, i, j, ret;
     GetBitContext gb;
 
     /* no supplementary picture */
@@ -327,13 +328,9 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
             s->image_width, s->image_height, s->block_width, s->block_height,
             h_blocks, v_blocks, h_part, v_part);
 
-    s->frame.reference    = 3;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                            FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* loop over all block columns */
@@ -358,8 +355,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
             s->diff_height    = cur_blk_height;
 
             if (8 * size > get_bits_left(&gb)) {
-                avctx->release_buffer(avctx, &s->frame);
-                s->frame.data[0] = NULL;
+                av_frame_unref(&s->frame);
                 return AVERROR_INVALIDDATA;
             }
 
@@ -441,8 +437,10 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
         memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
     }
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     if ((get_bits_count(&gb) / 8) != buf_size)
         av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
@@ -458,8 +456,7 @@ static av_cold int flashsv_decode_end(AVCodecContext *avctx)
     FlashSVContext *s = avctx->priv_data;
     inflateEnd(&s->zstream);
     /* release the frame if needed */
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     /* free the tmpblock */
     av_free(s->tmpblock);
index 08c3ef32a8865805e88f389267ce859a74ed789d..2588619e1507680231e6aa681249abed9a9283ed 100644 (file)
@@ -42,6 +42,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "mathops.h"
 
 #define FLI_256_COLOR 4
@@ -167,9 +168,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -424,8 +423,10 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
         s->new_palette = 0;
     }
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -463,9 +464,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -685,9 +684,10 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
                "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -733,8 +733,7 @@ static av_cold int flic_decode_end(AVCodecContext *avctx)
 {
     FlicDecodeContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index 237cb743f9255e56004069995eaae15a2a11f20a..2a5a5a8b381bc5a3113738766bd9bb8db3d2ce39 100644 (file)
@@ -36,6 +36,7 @@
 #include "huffman.h"
 #include "bytestream.h"
 #include "dsputil.h"
+#include "internal.h"
 
 #define FPS_TAG MKTAG('F', 'P', 'S', 'x')
 
@@ -60,7 +61,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     FrapsContext * const s = avctx->priv_data;
 
-    avctx->coded_frame = &s->frame;
     avctx->pix_fmt     = AV_PIX_FMT_NONE; /* set in decode_frame */
 
     s->avctx  = avctx;
@@ -161,7 +161,7 @@ static int decode_frame(AVCodecContext *avctx,
 
     pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
     if (avctx->pix_fmt != pix_fmt && f->data[0]) {
-        avctx->release_buffer(avctx, f);
+        av_frame_unref(f);
     }
     avctx->pix_fmt = pix_fmt;
 
@@ -184,11 +184,7 @@ static int decode_frame(AVCodecContext *avctx,
             return AVERROR_INVALIDDATA;
         }
 
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if ((ret = avctx->reget_buffer(avctx, f)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
@@ -225,11 +221,7 @@ static int decode_frame(AVCodecContext *avctx,
             return AVERROR_INVALIDDATA;
         }
 
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if ((ret = avctx->reget_buffer(avctx, f)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
@@ -252,11 +244,7 @@ static int decode_frame(AVCodecContext *avctx,
          * Fraps v4 is virtually the same
          */
         planes = 3;
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if ((ret = avctx->reget_buffer(avctx, f)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
@@ -300,11 +288,7 @@ static int decode_frame(AVCodecContext *avctx,
     case 5:
         /* Virtually the same as version 4, but is for RGB24 */
         planes = 3;
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if ((ret = avctx->reget_buffer(avctx, f)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, f)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
@@ -350,7 +334,8 @@ static int decode_frame(AVCodecContext *avctx,
         break;
     }
 
-    *frame = *f;
+    if ((ret = av_frame_ref(frame, f)) < 0)
+        return ret;
     *got_frame = 1;
 
     return buf_size;
@@ -366,8 +351,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     FrapsContext *s = (FrapsContext*)avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     av_freep(&s->tmpbuf);
     return 0;
index 3f8f6baf6aa6d3fa1cf9c99218e530062d0b9131..1323727b42887c4b3d824ebc6abcceb04d4e58fc 100644 (file)
@@ -32,10 +32,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     }
     avctx->pix_fmt = AV_PIX_FMT_UYVY422;
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
     return 0;
 }
 
@@ -43,13 +39,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     int field, ret;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = buf + avpkt->size;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < avctx->width * 2 * avctx->height + 4 + 2*8) {
         av_log(avctx, AV_LOG_ERROR, "Packet is too small.\n");
         return AVERROR_INVALIDDATA;
@@ -59,8 +52,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if ((ret = ff_get_buffer(avctx, pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -98,27 +90,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = *pic;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_frwu_decoder = {
     .name           = "frwu",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_FRWU,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Forward Uncompressed"),
index c100a90d3432cd32d5dc815baeed38e50b3c33d0..100dab2f9b2a9e2e3354b06a4e43418e4fe96f01 100644 (file)
@@ -94,7 +94,7 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = avpkt->size * 2;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 377a718ffb0acaa523b403b9fece6b14517759fc..64b4e1fd4c9d5b742ded4d07bf29c307c2d3b3f9 100644 (file)
@@ -1218,7 +1218,7 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     frame->nb_samples = FRAME_LEN;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
          av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
          return ret;
     }
index d6ae9b26796493694fa2eb14ba096aaffea01515..e1448a148749d08257041eab4aec7083a9def1a1 100644 (file)
@@ -451,7 +451,7 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = out_samples;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 2a962e5de0a919b6478034404124b68271db2cd2..9b74d342c8ea210f86ee0aef329e195801b8090b 100644 (file)
@@ -34,7 +34,6 @@
 #define GCE_DISPOSAL_RESTORE    3
 
 typedef struct GifState {
-    AVFrame picture;
     int screen_width;
     int screen_height;
     int bits_per_pixel;
@@ -63,7 +62,7 @@ typedef struct GifState {
 static const uint8_t gif87a_sig[6] = "GIF87a";
 static const uint8_t gif89a_sig[6] = "GIF89a";
 
-static int gif_read_image(GifState *s)
+static int gif_read_image(GifState *s, AVFrame *frame)
 {
     int left, top, width, height, bits_per_pixel, code_size, flags;
     int is_interleaved, has_local_palette, y, pass, y1, linesize, n, i;
@@ -112,8 +111,8 @@ static int gif_read_image(GifState *s)
                        s->bytestream_end - s->bytestream, FF_LZW_GIF);
 
     /* read all the image */
-    linesize = s->picture.linesize[0];
-    ptr1 = s->picture.data[0] + top * linesize + left;
+    linesize = frame->linesize[0];
+    ptr1 = frame->data[0] + top * linesize + left;
     ptr = ptr1;
     pass = 0;
     y1 = 0;
@@ -245,7 +244,7 @@ static int gif_read_header1(GifState *s)
     return 0;
 }
 
-static int gif_parse_next_image(GifState *s)
+static int gif_parse_next_image(GifState *s, AVFrame *frame)
 {
     while (s->bytestream < s->bytestream_end) {
         int code = bytestream_get_byte(&s->bytestream);
@@ -255,7 +254,7 @@ static int gif_parse_next_image(GifState *s)
 
         switch (code) {
         case ',':
-            return gif_read_image(s);
+            return gif_read_image(s, frame);
         case '!':
             if ((ret = gif_read_extension(s)) < 0)
                 return ret;
@@ -276,9 +275,6 @@ static av_cold int gif_decode_init(AVCodecContext *avctx)
 
     s->avctx = avctx;
 
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
-    s->picture.data[0] = NULL;
     ff_lzw_decode_open(&s->lzw);
     return 0;
 }
@@ -302,18 +298,15 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return ret;
     avcodec_set_dimensions(avctx, s->screen_width, s->screen_height);
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-    if ((ret = ff_get_buffer(avctx, &s->picture)) < 0) {
+    if ((ret = ff_get_buffer(avctx, picture, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    s->image_palette = (uint32_t *)s->picture.data[1];
-    ret = gif_parse_next_image(s);
+    s->image_palette = (uint32_t *)picture->data[1];
+    ret = gif_parse_next_image(s, picture);
     if (ret < 0)
         return ret;
 
-    *picture = s->picture;
     *got_frame = 1;
     return s->bytestream - buf;
 }
@@ -323,8 +316,6 @@ static av_cold int gif_decode_close(AVCodecContext *avctx)
     GifState *s = avctx->priv_data;
 
     ff_lzw_decode_close(&s->lzw);
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
     return 0;
 }
 
index e452be3fe032fdee875a2c569e13d2387a24f636..d67f0b49c09e7cc792e8a01a81f3d0a7e6833b08 100644 (file)
@@ -69,7 +69,7 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = avctx->frame_size;
-    if ((res = ff_get_buffer(avctx, frame)) < 0) {
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
index 35d5002252388c77ec4d8a6c5190c579383e5b6a..d8ce66d24c30a1e2424418c366cb5d2a5f59366f 100644 (file)
@@ -214,7 +214,7 @@ static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 )
 
         s->mv_dir = MV_DIR_FORWARD;
         s->mv_type = MV_TYPE_16X16;
-        s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+        s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
         s->mv[0][0][0] = 0;
         s->mv[0][0][1] = 0;
         s->mb_skipped = 1;
@@ -322,14 +322,14 @@ static int h261_decode_mb(H261Context *h){
     }
 
     if(s->mb_intra){
-        s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+        s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
         goto intra;
     }
 
     //set motion vectors
     s->mv_dir = MV_DIR_FORWARD;
     s->mv_type = MV_TYPE_16X16;
-    s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+    s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
     s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation
     s->mv[0][0][1] = h->current_mv_y * 2;
 
@@ -624,8 +624,9 @@ retry:
 assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
 assert(s->current_picture.f.pict_type == s->pict_type);
 
-    *pict = s->current_picture_ptr->f;
-    ff_print_debug_info(s, pict);
+    if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+        return ret;
+    ff_print_debug_info(s, s->current_picture_ptr);
 
     *got_frame = 1;
 
index 5ff47de76d7fe5c285a139f73e03973c40b0b71a..c097033951fb5fc5d2d8f949caee6e42788f6bc8 100644 (file)
@@ -51,7 +51,7 @@ void ff_h263_update_motion_val(MpegEncContext * s){
     const int wrap = s->b8_stride;
     const int xy = s->block_index[0];
 
-    s->current_picture.f.mbskip_table[mb_xy] = s->mb_skipped;
+    s->current_picture.mbskip_table[mb_xy] = s->mb_skipped;
 
     if(s->mv_type != MV_TYPE_8X8){
         int motion_x, motion_y;
@@ -70,30 +70,30 @@ void ff_h263_update_motion_val(MpegEncContext * s){
                 s->p_field_mv_table[i][0][mb_xy][0]= s->mv[0][i][0];
                 s->p_field_mv_table[i][0][mb_xy][1]= s->mv[0][i][1];
             }
-            s->current_picture.f.ref_index[0][4*mb_xy    ] =
-            s->current_picture.f.ref_index[0][4*mb_xy + 1] = s->field_select[0][0];
-            s->current_picture.f.ref_index[0][4*mb_xy + 2] =
-            s->current_picture.f.ref_index[0][4*mb_xy + 3] = s->field_select[0][1];
+            s->current_picture.ref_index[0][4*mb_xy    ] =
+            s->current_picture.ref_index[0][4*mb_xy + 1] = s->field_select[0][0];
+            s->current_picture.ref_index[0][4*mb_xy + 2] =
+            s->current_picture.ref_index[0][4*mb_xy + 3] = s->field_select[0][1];
         }
 
         /* no update if 8X8 because it has been done during parsing */
-        s->current_picture.f.motion_val[0][xy][0]            = motion_x;
-        s->current_picture.f.motion_val[0][xy][1]            = motion_y;
-        s->current_picture.f.motion_val[0][xy + 1][0]        = motion_x;
-        s->current_picture.f.motion_val[0][xy + 1][1]        = motion_y;
-        s->current_picture.f.motion_val[0][xy + wrap][0]     = motion_x;
-        s->current_picture.f.motion_val[0][xy + wrap][1]     = motion_y;
-        s->current_picture.f.motion_val[0][xy + 1 + wrap][0] = motion_x;
-        s->current_picture.f.motion_val[0][xy + 1 + wrap][1] = motion_y;
+        s->current_picture.motion_val[0][xy][0]            = motion_x;
+        s->current_picture.motion_val[0][xy][1]            = motion_y;
+        s->current_picture.motion_val[0][xy + 1][0]        = motion_x;
+        s->current_picture.motion_val[0][xy + 1][1]        = motion_y;
+        s->current_picture.motion_val[0][xy + wrap][0]     = motion_x;
+        s->current_picture.motion_val[0][xy + wrap][1]     = motion_y;
+        s->current_picture.motion_val[0][xy + 1 + wrap][0] = motion_x;
+        s->current_picture.motion_val[0][xy + 1 + wrap][1] = motion_y;
     }
 
     if(s->encoding){ //FIXME encoding MUST be cleaned up
         if (s->mv_type == MV_TYPE_8X8)
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8;
+            s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_8x8;
         else if(s->mb_intra)
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_INTRA;
+            s->current_picture.mb_type[mb_xy] = MB_TYPE_INTRA;
         else
-            s->current_picture.f.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16;
+            s->current_picture.mb_type[mb_xy] = MB_TYPE_L0 | MB_TYPE_16x16;
     }
 }
 
@@ -153,7 +153,7 @@ void ff_h263_loop_filter(MpegEncContext * s){
        Diag Top
        Left Center
     */
-    if (!IS_SKIP(s->current_picture.f.mb_type[xy])) {
+    if (!IS_SKIP(s->current_picture.mb_type[xy])) {
         qp_c= s->qscale;
         s->dsp.h263_v_loop_filter(dest_y+8*linesize  , linesize, qp_c);
         s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c);
@@ -163,10 +163,10 @@ void ff_h263_loop_filter(MpegEncContext * s){
     if(s->mb_y){
         int qp_dt, qp_tt, qp_tc;
 
-        if (IS_SKIP(s->current_picture.f.mb_type[xy - s->mb_stride]))
+        if (IS_SKIP(s->current_picture.mb_type[xy - s->mb_stride]))
             qp_tt=0;
         else
-            qp_tt = s->current_picture.f.qscale_table[xy - s->mb_stride];
+            qp_tt = s->current_picture.qscale_table[xy - s->mb_stride];
 
         if(qp_c)
             qp_tc= qp_c;
@@ -186,10 +186,10 @@ void ff_h263_loop_filter(MpegEncContext * s){
             s->dsp.h263_h_loop_filter(dest_y-8*linesize+8  ,   linesize, qp_tt);
 
         if(s->mb_x){
-            if (qp_tt || IS_SKIP(s->current_picture.f.mb_type[xy - 1 - s->mb_stride]))
+            if (qp_tt || IS_SKIP(s->current_picture.mb_type[xy - 1 - s->mb_stride]))
                 qp_dt= qp_tt;
             else
-                qp_dt = s->current_picture.f.qscale_table[xy - 1 - s->mb_stride];
+                qp_dt = s->current_picture.qscale_table[xy - 1 - s->mb_stride];
 
             if(qp_dt){
                 const int chroma_qp= s->chroma_qscale_table[qp_dt];
@@ -208,10 +208,10 @@ void ff_h263_loop_filter(MpegEncContext * s){
 
     if(s->mb_x){
         int qp_lc;
-        if (qp_c || IS_SKIP(s->current_picture.f.mb_type[xy - 1]))
+        if (qp_c || IS_SKIP(s->current_picture.mb_type[xy - 1]))
             qp_lc= qp_c;
         else
-            qp_lc = s->current_picture.f.qscale_table[xy - 1];
+            qp_lc = s->current_picture.qscale_table[xy - 1];
 
         if(qp_lc){
             s->dsp.h263_h_loop_filter(dest_y,   linesize, qp_lc);
@@ -320,7 +320,7 @@ int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir,
     static const int off[4]= {2, 1, 1, -1};
 
     wrap = s->b8_stride;
-    mot_val = s->current_picture.f.motion_val[dir] + s->block_index[block];
+    mot_val = s->current_picture.motion_val[dir] + s->block_index[block];
 
     A = mot_val[ - 1];
     /* special case for first (slice) line */
index f5e147478938a0327dbffb308cb43875f416789f..28fb2dbbd5c17ac267ed495dc7bdb398d45c0bd3 100644 (file)
@@ -359,7 +359,8 @@ uint64_t time= rdtsc();
     if (buf_size == 0) {
         /* special case for last picture */
         if (s->low_delay==0 && s->next_picture_ptr) {
-            *pict = s->next_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
+                return ret;
             s->next_picture_ptr= NULL;
 
             *got_frame = 1;
@@ -722,14 +723,17 @@ intrax8_decoded:
     assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
     assert(s->current_picture.f.pict_type == s->pict_type);
     if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-        *pict = s->current_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->current_picture_ptr);
     } else if (s->last_picture_ptr != NULL) {
-        *pict = s->last_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->last_picture_ptr);
     }
 
     if(s->last_picture_ptr || s->low_delay){
         *got_frame = 1;
-        ff_print_debug_info(s, pict);
     }
 
 #ifdef PRINT_FRAME_TIME
index 0af5cea0d1cb66708bb52b10feca47db841831a5..498f611a975ab69942cdf3b0dc302a04320db070 100644 (file)
@@ -113,7 +113,7 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
      * practice then correct remapping should be added. */
     if (ref >= h->ref_count[0])
         ref = 0;
-    fill_rectangle(&h->cur_pic.f.ref_index[0][4 * h->mb_xy],
+    fill_rectangle(&h->cur_pic.ref_index[0][4 * h->mb_xy],
                    2, 2, 2, ref, 1);
     fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
     fill_rectangle(h->mv_cache[0][scan8[0]], 4, 4, 8,
@@ -166,28 +166,25 @@ void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
     }
 }
 
-static void free_frame_buffer(H264Context *h, Picture *pic)
-{
-    ff_thread_release_buffer(h->avctx, &pic->f);
-    av_freep(&pic->f.hwaccel_picture_private);
-}
-
-static void free_picture(H264Context *h, Picture *pic)
+static void unref_picture(H264Context *h, Picture *pic)
 {
+    int off = offsetof(Picture, tf) + sizeof(pic->tf);
     int i;
 
-    if (pic->f.data[0])
-        free_frame_buffer(h, pic);
+    if (!pic->f.data[0])
+        return;
+
+    ff_thread_release_buffer(h->avctx, &pic->tf);
+    av_buffer_unref(&pic->hwaccel_priv_buf);
 
-    av_freep(&pic->qscale_table_base);
-    pic->f.qscale_table = NULL;
-    av_freep(&pic->mb_type_base);
-    pic->f.mb_type = NULL;
+    av_buffer_unref(&pic->qscale_table_buf);
+    av_buffer_unref(&pic->mb_type_buf);
     for (i = 0; i < 2; i++) {
-        av_freep(&pic->motion_val_base[i]);
-        av_freep(&pic->f.ref_index[i]);
-        pic->f.motion_val[i] = NULL;
+        av_buffer_unref(&pic->motion_val_buf[i]);
+        av_buffer_unref(&pic->ref_index_buf[i]);
     }
+
+    memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
 }
 
 static void release_unused_pictures(H264Context *h, int remove_current)
@@ -195,15 +192,74 @@ static void release_unused_pictures(H264Context *h, int remove_current)
     int i;
 
     /* release non reference frames */
-    for (i = 0; i < h->picture_count; i++) {
-        if (h->DPB[i].f.data[0] && !h->DPB[i].f.reference &&
-            (!h->DPB[i].owner2 || h->DPB[i].owner2 == h) &&
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        if (h->DPB[i].f.data[0] && !h->DPB[i].reference &&
             (remove_current || &h->DPB[i] != h->cur_pic_ptr)) {
-            free_frame_buffer(h, &h->DPB[i]);
+            unref_picture(h, &h->DPB[i]);
         }
     }
 }
 
+static int ref_picture(H264Context *h, Picture *dst, Picture *src)
+{
+    int ret, i;
+
+    av_assert0(!dst->f.buf[0]);
+    av_assert0(src->f.buf[0]);
+
+    src->tf.f = &src->f;
+    dst->tf.f = &dst->f;
+    ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    if (ret < 0)
+        goto fail;
+
+
+    dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf);
+    dst->mb_type_buf      = av_buffer_ref(src->mb_type_buf);
+    if (!dst->qscale_table_buf || !dst->mb_type_buf)
+        goto fail;
+    dst->qscale_table = src->qscale_table;
+    dst->mb_type      = src->mb_type;
+
+    for (i = 0; i < 2; i ++) {
+        dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]);
+        dst->ref_index_buf[i]  = av_buffer_ref(src->ref_index_buf[i]);
+        if (!dst->motion_val_buf[i] || !dst->ref_index_buf[i])
+            goto fail;
+        dst->motion_val[i] = src->motion_val[i];
+        dst->ref_index[i]  = src->ref_index[i];
+    }
+
+    if (src->hwaccel_picture_private) {
+        dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+        if (!dst->hwaccel_priv_buf)
+            goto fail;
+        dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
+    }
+
+    for (i = 0; i < 2; i++)
+        dst->field_poc[i] = src->field_poc[i];
+
+    memcpy(dst->ref_poc,   src->ref_poc,   sizeof(src->ref_poc));
+    memcpy(dst->ref_count, src->ref_count, sizeof(src->ref_count));
+
+    dst->poc                     = src->poc;
+    dst->frame_num               = src->frame_num;
+    dst->mmco_reset              = src->mmco_reset;
+    dst->pic_id                  = src->pic_id;
+    dst->long_ref                = src->long_ref;
+    dst->mbaff                   = src->mbaff;
+    dst->field_picture           = src->field_picture;
+    dst->needs_realloc           = src->needs_realloc;
+    dst->reference               = src->reference;
+
+    return 0;
+fail:
+    unref_picture(h, dst);
+    return ret;
+}
+
+
 static int alloc_scratch_buffers(H264Context *h, int linesize)
 {
     int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
@@ -229,60 +285,86 @@ static int alloc_scratch_buffers(H264Context *h, int linesize)
     return 0;
 }
 
-static int alloc_picture(H264Context *h, Picture *pic)
+static int init_table_pools(H264Context *h)
 {
     const int big_mb_num    = h->mb_stride * (h->mb_height + 1) + 1;
     const int mb_array_size = h->mb_stride * h->mb_height;
     const int b4_stride     = h->mb_width * 4 + 1;
     const int b4_array_size = b4_stride * h->mb_height * 4;
+
+    h->qscale_table_pool = av_buffer_pool_init(big_mb_num + h->mb_stride,
+                                               av_buffer_allocz);
+    h->mb_type_pool      = av_buffer_pool_init((big_mb_num + h->mb_stride) *
+                                               sizeof(uint32_t), av_buffer_allocz);
+    h->motion_val_pool = av_buffer_pool_init(2 * (b4_array_size + 4) *
+                                             sizeof(int16_t), av_buffer_allocz);
+    h->ref_index_pool  = av_buffer_pool_init(4 * mb_array_size, av_buffer_allocz);
+
+    if (!h->qscale_table_pool || !h->mb_type_pool || !h->motion_val_pool ||
+        !h->ref_index_pool) {
+        av_buffer_pool_uninit(&h->qscale_table_pool);
+        av_buffer_pool_uninit(&h->mb_type_pool);
+        av_buffer_pool_uninit(&h->motion_val_pool);
+        av_buffer_pool_uninit(&h->ref_index_pool);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int alloc_picture(H264Context *h, Picture *pic)
+{
     int i, ret = 0;
 
     av_assert0(!pic->f.data[0]);
 
     if (h->avctx->hwaccel) {
         const AVHWAccel *hwaccel = h->avctx->hwaccel;
-        av_assert0(!pic->f.hwaccel_picture_private);
+        av_assert0(!pic->hwaccel_picture_private);
         if (hwaccel->priv_data_size) {
-            pic->f.hwaccel_picture_private = av_mallocz(hwaccel->priv_data_size);
-            if (!pic->f.hwaccel_picture_private)
+            pic->hwaccel_priv_buf = av_buffer_allocz(hwaccel->priv_data_size);
+            if (!pic->hwaccel_priv_buf)
                 return AVERROR(ENOMEM);
+            pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;
         }
     }
-    ret = ff_thread_get_buffer(h->avctx, &pic->f);
+    pic->tf.f = &pic->f;
+    ret = ff_thread_get_buffer(h->avctx, &pic->tf, pic->reference ?
+                                                   AV_GET_BUFFER_FLAG_REF : 0);
     if (ret < 0)
         goto fail;
 
     h->linesize   = pic->f.linesize[0];
     h->uvlinesize = pic->f.linesize[1];
 
-    if (pic->f.qscale_table == NULL) {
-        FF_ALLOCZ_OR_GOTO(h->avctx, pic->qscale_table_base,
-                          (big_mb_num + h->mb_stride) * sizeof(uint8_t),
-                          fail)
-        FF_ALLOCZ_OR_GOTO(h->avctx, pic->mb_type_base,
-                          (big_mb_num + h->mb_stride) * sizeof(uint32_t),
-                          fail)
-        pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
-        pic->f.qscale_table = pic->qscale_table_base + 2 * h->mb_stride + 1;
+    if (!h->qscale_table_pool) {
+        ret = init_table_pools(h);
+        if (ret < 0)
+            goto fail;
+    }
 
-        for (i = 0; i < 2; i++) {
-            FF_ALLOCZ_OR_GOTO(h->avctx, pic->motion_val_base[i],
-                              2 * (b4_array_size + 4) * sizeof(int16_t),
-                              fail)
-            pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
-            FF_ALLOCZ_OR_GOTO(h->avctx, pic->f.ref_index[i],
-                              4 * mb_array_size * sizeof(uint8_t), fail)
-        }
-        pic->f.motion_subsample_log2 = 2;
+    pic->qscale_table_buf = av_buffer_pool_get(h->qscale_table_pool);
+    pic->mb_type_buf      = av_buffer_pool_get(h->mb_type_pool);
+    if (!pic->qscale_table_buf || !pic->mb_type_buf)
+        goto fail;
 
-        pic->f.qstride = h->mb_stride;
-    }
+    pic->mb_type      = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 1;
+    pic->qscale_table = pic->qscale_table_buf->data + 2 * h->mb_stride + 1;
+
+    for (i = 0; i < 2; i++) {
+        pic->motion_val_buf[i] = av_buffer_pool_get(h->motion_val_pool);
+        pic->ref_index_buf[i]  = av_buffer_pool_get(h->ref_index_pool);
+        if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i])
+            goto fail;
 
-    pic->owner2 = h;
+        pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
+        pic->ref_index[i]  = pic->ref_index_buf[i]->data;
+    }
+    pic->f.motion_subsample_log2 = 2;
 
     return 0;
 fail:
-    free_frame_buffer(h, pic);
+    unref_picture(h, pic);
     return (ret < 0) ? ret : AVERROR(ENOMEM);
 }
 
@@ -290,9 +372,8 @@ static inline int pic_is_unused(H264Context *h, Picture *pic)
 {
     if (pic->f.data[0] == NULL)
         return 1;
-    if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF))
-        if (!pic->owner2 || pic->owner2 == h)
-            return 1;
+    if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
+        return 1;
     return 0;
 }
 
@@ -300,17 +381,16 @@ static int find_unused_picture(H264Context *h)
 {
     int i;
 
-    for (i = h->picture_range_start; i < h->picture_range_end; i++) {
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
         if (pic_is_unused(h, &h->DPB[i]))
             break;
     }
-    if (i == h->picture_range_end)
+    if (i == MAX_PICTURE_COUNT)
         return AVERROR_INVALIDDATA;
 
     if (h->DPB[i].needs_realloc) {
         h->DPB[i].needs_realloc = 0;
-        free_picture(h, &h->DPB[i]);
-        avcodec_get_frame_defaults(&h->DPB[i].f);
+        unref_picture(h, &h->DPB[i]);
     }
 
     return i;
@@ -561,8 +641,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
         // Error resilience puts the current picture in the ref list.
         // Don't try to wait on these as it will cause a deadlock.
         // Fields can wait on each other, though.
-        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
-            (ref->f.reference & 3) != h->picture_structure) {
+        if (ref->tf.progress->data   != h->cur_pic.tf.progress->data ||
+            (ref->reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 0);
             if (refs[0][ref_n] < 0)
                 nrefs[0] += 1;
@@ -574,8 +654,8 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
         int ref_n    = h->ref_cache[1][scan8[n]];
         Picture *ref = &h->ref_list[1][ref_n];
 
-        if (ref->f.thread_opaque   != h->cur_pic.f.thread_opaque ||
-            (ref->f.reference & 3) != h->picture_structure) {
+        if (ref->tf.progress->data != h->cur_pic.tf.progress->data ||
+            (ref->reference & 3) != h->picture_structure) {
             my = get_lowest_part_list_y(h, ref, n, height, y_offset, 1);
             if (refs[1][ref_n] < 0)
                 nrefs[1] += 1;
@@ -592,7 +672,7 @@ static inline void get_lowest_part_y(H264Context *h, int refs[2][48], int n,
 static void await_references(H264Context *h)
 {
     const int mb_xy   = h->mb_xy;
-    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     int refs[2][48];
     int nrefs[2] = { 0 };
     int ref, list;
@@ -664,7 +744,7 @@ static void await_references(H264Context *h)
             int row = refs[list][ref];
             if (row >= 0) {
                 Picture *ref_pic      = &h->ref_list[list][ref];
-                int ref_field         = ref_pic->f.reference - 1;
+                int ref_field         = ref_pic->reference - 1;
                 int ref_field_picture = ref_pic->field_picture;
                 int pic_height        = 16 * h->mb_height >> ref_field_picture;
 
@@ -672,24 +752,24 @@ static void await_references(H264Context *h)
                 nrefs[list]--;
 
                 if (!FIELD_PICTURE && ref_field_picture) { // frame referencing two fields
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN((row >> 1) - !(row & 1),
                                                    pic_height - 1),
                                              1);
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN((row >> 1), pic_height - 1),
                                              0);
                 } else if (FIELD_PICTURE && !ref_field_picture) { // field referencing one field of a frame
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row * 2 + ref_field,
                                                    pic_height - 1),
                                              0);
                 } else if (FIELD_PICTURE) {
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row, pic_height - 1),
                                              ref_field);
                 } else {
-                    ff_thread_await_progress(&ref_pic->f,
+                    ff_thread_await_progress(&ref_pic->tf,
                                              FFMIN(row, pic_height - 1),
                                              0);
                 }
@@ -781,7 +861,7 @@ static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,
     ysh = 3 - (chroma_idc == 2 /* yuv422 */);
     if (chroma_idc == 1 /* yuv420 */ && MB_FIELD) {
         // chroma offset when predicting from a field of opposite parity
-        my  += 2 * ((h->mb_y & 1) - (pic->f.reference - 1));
+        my  += 2 * ((h->mb_y & 1) - (pic->reference - 1));
         emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);
     }
 
@@ -1009,13 +1089,17 @@ static void free_tables(H264Context *h, int free_rbsp)
     av_freep(&h->mb2b_xy);
     av_freep(&h->mb2br_xy);
 
-    if (free_rbsp) {
-        for (i = 0; i < h->picture_count && !h->avctx->internal->is_copy; i++)
-            free_picture(h, &h->DPB[i]);
+    av_buffer_pool_uninit(&h->qscale_table_pool);
+    av_buffer_pool_uninit(&h->mb_type_pool);
+    av_buffer_pool_uninit(&h->motion_val_pool);
+    av_buffer_pool_uninit(&h->ref_index_pool);
+
+    if (free_rbsp && h->DPB) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++)
+            unref_picture(h, &h->DPB[i]);
         av_freep(&h->DPB);
-        h->picture_count = 0;
     } else if (h->DPB) {
-        for (i = 0; i < h->picture_count; i++)
+        for (i = 0; i < MAX_PICTURE_COUNT; i++)
             h->DPB[i].needs_realloc = 1;
     }
 
@@ -1164,11 +1248,10 @@ int ff_h264_alloc_tables(H264Context *h)
         init_dequant_tables(h);
 
     if (!h->DPB) {
-        h->picture_count = MAX_PICTURE_COUNT * FFMAX(1, h->avctx->thread_count);
-        h->DPB = av_mallocz_array(h->picture_count, sizeof(*h->DPB));
+        h->DPB = av_mallocz_array(MAX_PICTURE_COUNT, sizeof(*h->DPB));
         if (!h->DPB)
             return AVERROR(ENOMEM);
-        for (i = 0; i < h->picture_count; i++)
+        for (i = 0; i < MAX_PICTURE_COUNT; i++)
             avcodec_get_frame_defaults(&h->DPB[i].f);
         avcodec_get_frame_defaults(&h->cur_pic.f);
     }
@@ -1367,8 +1450,6 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
     common_init(h);
 
     h->picture_structure   = PICT_FRAME;
-    h->picture_range_start = 0;
-    h->picture_range_end   = MAX_PICTURE_COUNT;
     h->slice_context_count = 1;
     h->workaround_bugs     = avctx->workaround_bugs;
     h->flags               = avctx->flags;
@@ -1408,6 +1489,8 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
         h->low_delay           = 0;
     }
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
@@ -1415,7 +1498,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
 #undef REBASE_PICTURE
 #define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
     ((pic && pic >= old_ctx->DPB &&                       \
-      pic < old_ctx->DPB + old_ctx->picture_count) ?      \
+      pic < old_ctx->DPB + MAX_PICTURE_COUNT) ?      \
         &new_ctx->DPB[pic - old_ctx->DPB] : NULL)
 
 static void copy_picture_range(Picture **to, Picture **from, int count,
@@ -1427,7 +1510,7 @@ static void copy_picture_range(Picture **to, Picture **from, int count,
     for (i = 0; i < count; i++) {
         assert((IN_RANGE(from[i], old_base, sizeof(*old_base)) ||
                 IN_RANGE(from[i], old_base->DPB,
-                         sizeof(Picture) * old_base->picture_count) ||
+                         sizeof(Picture) * MAX_PICTURE_COUNT) ||
                 !from[i]));
         to[i] = REBASE_PICTURE(from[i], new_base, old_base);
     }
@@ -1476,7 +1559,7 @@ static int decode_update_thread_context(AVCodecContext *dst,
     H264Context *h = dst->priv_data, *h1 = src->priv_data;
     int inited = h->context_initialized, err = 0;
     int context_reinitialized = 0;
-    int i;
+    int i, ret;
 
     if (dst == src || !h1->context_initialized)
         return 0;
@@ -1529,12 +1612,16 @@ static int decode_update_thread_context(AVCodecContext *dst,
         memset(&h->me, 0, sizeof(h->me));
         h->context_initialized = 0;
 
-        h->picture_range_start  += MAX_PICTURE_COUNT;
-        h->picture_range_end    += MAX_PICTURE_COUNT;
+        memset(&h->cur_pic, 0, sizeof(h->cur_pic));
+        avcodec_get_frame_defaults(&h->cur_pic.f);
+        h->cur_pic.tf.f = &h->cur_pic.f;
 
         h->avctx = dst;
         h->DPB   = NULL;
-        h->cur_pic.f.extended_data = h->cur_pic.f.data;
+        h->qscale_table_pool = NULL;
+        h->mb_type_pool = NULL;
+        h->ref_index_pool = NULL;
+        h->motion_val_pool = NULL;
 
         if (ff_h264_alloc_tables(h) < 0) {
             av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
@@ -1568,15 +1655,17 @@ static int decode_update_thread_context(AVCodecContext *dst,
     h->data_partitioning    = h1->data_partitioning;
     h->low_delay            = h1->low_delay;
 
-    memcpy(h->DPB, h1->DPB, h1->picture_count * sizeof(*h1->DPB));
-
-    // reset s->picture[].f.extended_data to s->picture[].f.data
-    for (i = 0; i < h->picture_count; i++)
-        h->DPB[i].f.extended_data = h->DPB[i].f.data;
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        unref_picture(h, &h->DPB[i]);
+        if (h1->DPB[i].f.data[0] &&
+            (ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0)
+            return ret;
+    }
 
     h->cur_pic_ptr     = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);
-    h->cur_pic = h1->cur_pic;
-    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+    unref_picture(h, &h->cur_pic);
+    if ((ret = ref_picture(h, &h->cur_pic, &h1->cur_pic)) < 0)
+        return ret;
 
     h->workaround_bugs = h1->workaround_bugs;
     h->low_delay       = h1->low_delay;
@@ -1660,7 +1749,7 @@ int ff_h264_frame_start(H264Context *h)
     }
     pic = &h->DPB[i];
 
-    pic->f.reference            = h->droppable ? 0 : h->picture_structure;
+    pic->reference            = h->droppable ? 0 : h->picture_structure;
     pic->f.coded_picture_number = h->coded_picture_number++;
     pic->field_picture          = h->picture_structure != PICT_FRAME;
     /*
@@ -1675,8 +1764,9 @@ int ff_h264_frame_start(H264Context *h)
         return ret;
 
     h->cur_pic_ptr = pic;
-    h->cur_pic     = *h->cur_pic_ptr;
-    h->cur_pic.f.extended_data = h->cur_pic.f.data;
+    unref_picture(h, &h->cur_pic);
+    if ((ret = ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0)
+        return ret;
 
     ff_er_frame_start(&h->er);
 
@@ -1717,7 +1807,7 @@ int ff_h264_frame_start(H264Context *h)
      * get released even with set reference, besides SVQ3 and others do not
      * mark frames as reference later "naturally". */
     if (h->avctx->codec_id != AV_CODEC_ID_SVQ3)
-        h->cur_pic_ptr->f.reference = 0;
+        h->cur_pic_ptr->reference = 0;
 
     h->cur_pic_ptr->field_poc[0] = h->cur_pic_ptr->field_poc[1] = INT_MAX;
 
@@ -1743,7 +1833,6 @@ static void decode_postinit(H264Context *h, int setup_finished)
     int i, pics, out_of_order, out_idx;
     int invalid = 0, cnt = 0;
 
-    h->cur_pic_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
     h->cur_pic_ptr->f.pict_type   = h->pict_type;
 
     if (h->next_output_pic)
@@ -1847,8 +1936,8 @@ static void decode_postinit(H264Context *h, int setup_finished)
     assert(pics <= MAX_DELAYED_PIC_COUNT);
 
     h->delayed_pic[pics++] = cur;
-    if (cur->f.reference == 0)
-        cur->f.reference = DELAYED_PIC_REF;
+    if (cur->reference == 0)
+        cur->reference = DELAYED_PIC_REF;
 
     /* Frame reordering. This code takes pictures from coding order and sorts
      * them by their incremental POC value into display order. It supports POC
@@ -1913,10 +2002,9 @@ static void decode_postinit(H264Context *h, int setup_finished)
     }
 
     if (pics > h->avctx->has_b_frames) {
-        out->f.reference &= ~DELAYED_PIC_REF;
+        out->reference &= ~DELAYED_PIC_REF;
         // for frame threading, the owner must be the second field's thread or
         // else the first thread can release the picture and reuse it unsafely
-        out->owner2       = h;
         for (i = out_idx; h->delayed_pic[i]; i++)
             h->delayed_pic[i] = h->delayed_pic[i + 1];
     }
@@ -2350,7 +2438,7 @@ static av_always_inline void hl_decode_mb_idct_luma(H264Context *h, int mb_type,
 void ff_h264_hl_decode_mb(H264Context *h)
 {
     const int mb_xy   = h->mb_xy;
-    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     int is_complex    = CONFIG_SMALL || h->is_complex || IS_INTRA_PCM(mb_type) || h->qscale == 0;
 
     if (CHROMA444) {
@@ -2516,7 +2604,7 @@ static void flush_change(H264Context *h)
     h->prev_interlaced_frame = 1;
     idr(h);
     if (h->cur_pic_ptr)
-        h->cur_pic_ptr->f.reference = 0;
+        h->cur_pic_ptr->reference = 0;
     h->first_field = 0;
     memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));
     memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));
@@ -2533,17 +2621,16 @@ static void flush_dpb(AVCodecContext *avctx)
 
     for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) {
         if (h->delayed_pic[i])
-            h->delayed_pic[i]->f.reference = 0;
+            h->delayed_pic[i]->reference = 0;
         h->delayed_pic[i] = NULL;
     }
 
     flush_change(h);
 
-    for (i = 0; i < h->picture_count; i++) {
-        if (h->DPB[i].f.data[0])
-            free_frame_buffer(h, &h->DPB[i]);
-    }
+    for (i = 0; i < MAX_PICTURE_COUNT; i++)
+        unref_picture(h, &h->DPB[i]);
     h->cur_pic_ptr = NULL;
+    unref_picture(h, &h->cur_pic);
 
     h->mb_x = h->mb_y = 0;
 
@@ -2676,7 +2763,7 @@ static int field_end(H264Context *h, int in_setup)
     h->mb_y = 0;
 
     if (!in_setup && !h->droppable)
-        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
                                   h->picture_structure == PICT_BOTTOM_FIELD);
 
     if (CONFIG_H264_VDPAU_DECODER &&
@@ -3019,9 +3106,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
 
         h0->current_slice = 0;
         if (!h0->first_field) {
-            if (h->cur_pic_ptr && !h->droppable &&
-                h->cur_pic_ptr->owner2 == h) {
-                ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+            if (h->cur_pic_ptr && !h->droppable) {
+                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
                                           h->picture_structure == PICT_BOTTOM_FIELD);
             }
             h->cur_pic_ptr = NULL;
@@ -3240,20 +3326,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         if (h0->first_field) {
             assert(h0->cur_pic_ptr);
             assert(h0->cur_pic_ptr->f.data[0]);
-            assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
-
-            /* Mark old field/frame as completed */
-            if (!last_pic_droppable && h0->cur_pic_ptr->owner2 == h0) {
-                ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
-                                          last_pic_structure == PICT_BOTTOM_FIELD);
-            }
+            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
 
             /* figure out if we have a complementary field pair */
             if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) {
                 /* Previous field is unmatched. Don't display it, but let it
                  * remain for reference if marked as such. */
                 if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
-                    ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
+                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                               last_pic_structure == PICT_TOP_FIELD);
                 }
             } else {
@@ -3263,7 +3343,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                      * pair. Throw away previous field except for reference
                      * purposes. */
                     if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {
-                        ff_thread_report_progress(&h0->cur_pic_ptr->f, INT_MAX,
+                        ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                                   last_pic_structure == PICT_TOP_FIELD);
                     }
                 } else {
@@ -3286,14 +3366,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                         h->droppable         = last_pic_droppable;
                         return AVERROR_PATCHWELCOME;
                     }
-
-                    /* Take ownership of this buffer. Note that if another thread owned
-                     * the first field of this buffer, we're not operating on that pointer,
-                     * so the original thread is still responsible for reporting progress
-                     * on that first field (or if that was us, we just did that above).
-                     * By taking ownership, we assign responsibility to ourselves to
-                     * report progress on the second field. */
-                    h0->cur_pic_ptr->owner2 = h0;
                 }
             }
         }
@@ -3308,8 +3380,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
             h->prev_frame_num++;
             h->prev_frame_num %= 1 << h->sps.log2_max_frame_num;
             h->cur_pic_ptr->frame_num = h->prev_frame_num;
-            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX, 1);
+            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
+            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
             if ((ret = ff_generate_sliding_window_mmcos(h, 1)) < 0 &&
                 h->avctx->err_recognition & AV_EF_EXPLODE)
                 return ret;
@@ -3339,7 +3411,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         if (h0->first_field) {
             assert(h0->cur_pic_ptr);
             assert(h0->cur_pic_ptr->f.data[0]);
-            assert(h0->cur_pic_ptr->f.reference != DELAYED_PIC_REF);
+            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);
 
             /* figure out if we have a complementary field pair */
             if (!FIELD_PICTURE || h->picture_structure == last_pic_structure) {
@@ -3606,16 +3678,16 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
         int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j];
         for (i = 0; i < 16; i++) {
             id_list[i] = 60;
-            if (h->ref_list[j][i].f.data[0]) {
+            if (j < h->list_count && i < h->ref_count[j] && h->ref_list[j][i].f.buf[0]) {
                 int k;
-                uint8_t *base = h->ref_list[j][i].f.base[0];
+                AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer;
                 for (k = 0; k < h->short_ref_count; k++)
-                    if (h->short_ref[k]->f.base[0] == base) {
+                    if (h->short_ref[k]->f.buf[0]->buffer == buf) {
                         id_list[i] = k;
                         break;
                     }
                 for (k = 0; k < h->long_ref_count; k++)
-                    if (h->long_ref[k] && h->long_ref[k]->f.base[0] == base) {
+                    if (h->long_ref[k] && h->long_ref[k]->f.buf[0]->buffer == buf) {
                         id_list[i] = h->short_ref_count + k;
                         break;
                     }
@@ -3626,12 +3698,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
             ref2frm[1] = -1;
         for (i = 0; i < 16; i++)
             ref2frm[i + 2] = 4 * id_list[i] +
-                             (h->ref_list[j][i].f.reference & 3);
+                             (h->ref_list[j][i].reference & 3);
         ref2frm[18 + 0]     =
             ref2frm[18 + 1] = -1;
         for (i = 16; i < 48; i++)
             ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] +
-                             (h->ref_list[j][i].f.reference & 3);
+                             (h->ref_list[j][i].reference & 3);
     }
 
     if (h->avctx->debug & FF_DEBUG_PICT_INFO) {
@@ -3691,11 +3763,11 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
             const int b_xy  = h->mb2b_xy[top_xy] + 3 * b_stride;
             const int b8_xy = 4 * top_xy + 2;
             int (*ref2frm)[64] = h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
-            AV_COPY128(mv_dst - 1 * 8, h->cur_pic.f.motion_val[list][b_xy + 0]);
+            AV_COPY128(mv_dst - 1 * 8, h->cur_pic.motion_val[list][b_xy + 0]);
             ref_cache[0 - 1 * 8] =
-            ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 0]];
+            ref_cache[1 - 1 * 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 0]];
             ref_cache[2 - 1 * 8] =
-            ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 1]];
+            ref_cache[3 - 1 * 8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 1]];
         } else {
             AV_ZERO128(mv_dst - 1 * 8);
             AV_WN32A(&ref_cache[0 - 1 * 8], ((LIST_NOT_USED) & 0xFF) * 0x01010101u);
@@ -3706,14 +3778,14 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
                 const int b_xy  = h->mb2b_xy[left_xy[LTOP]] + 3;
                 const int b8_xy = 4 * left_xy[LTOP] + 1;
                 int (*ref2frm)[64] = h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
-                AV_COPY32(mv_dst - 1 +  0, h->cur_pic.f.motion_val[list][b_xy + b_stride * 0]);
-                AV_COPY32(mv_dst - 1 +  8, h->cur_pic.f.motion_val[list][b_xy + b_stride * 1]);
-                AV_COPY32(mv_dst - 1 + 16, h->cur_pic.f.motion_val[list][b_xy + b_stride * 2]);
-                AV_COPY32(mv_dst - 1 + 24, h->cur_pic.f.motion_val[list][b_xy + b_stride * 3]);
+                AV_COPY32(mv_dst - 1 +  0, h->cur_pic.motion_val[list][b_xy + b_stride * 0]);
+                AV_COPY32(mv_dst - 1 +  8, h->cur_pic.motion_val[list][b_xy + b_stride * 1]);
+                AV_COPY32(mv_dst - 1 + 16, h->cur_pic.motion_val[list][b_xy + b_stride * 2]);
+                AV_COPY32(mv_dst - 1 + 24, h->cur_pic.motion_val[list][b_xy + b_stride * 3]);
                 ref_cache[-1 +  0] =
-                ref_cache[-1 +  8] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 0]];
+                ref_cache[-1 +  8] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 2 * 0]];
                 ref_cache[-1 + 16] =
-                ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.f.ref_index[list][b8_xy + 2 * 1]];
+                ref_cache[-1 + 24] = ref2frm[list][h->cur_pic.ref_index[list][b8_xy + 2 * 1]];
             } else {
                 AV_ZERO32(mv_dst - 1 +  0);
                 AV_ZERO32(mv_dst - 1 +  8);
@@ -3737,7 +3809,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
     }
 
     {
-        int8_t *ref = &h->cur_pic.f.ref_index[list][4 * mb_xy];
+        int8_t *ref = &h->cur_pic.ref_index[list][4 * mb_xy];
         int (*ref2frm)[64] = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
         uint32_t ref01 = (pack16to32(ref2frm[list][ref[0]], ref2frm[list][ref[1]]) & 0x00FF00FF) * 0x0101;
         uint32_t ref23 = (pack16to32(ref2frm[list][ref[2]], ref2frm[list][ref[3]]) & 0x00FF00FF) * 0x0101;
@@ -3748,7 +3820,7 @@ static av_always_inline void fill_filter_caches_inter(H264Context *h,
     }
 
     {
-        int16_t(*mv_src)[2] = &h->cur_pic.f.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride];
+        int16_t(*mv_src)[2] = &h->cur_pic.motion_val[list][4 * h->mb_x + 4 * h->mb_y * b_stride];
         AV_COPY128(mv_dst + 8 * 0, mv_src + 0 * b_stride);
         AV_COPY128(mv_dst + 8 * 1, mv_src + 1 * b_stride);
         AV_COPY128(mv_dst + 8 * 2, mv_src + 2 * b_stride);
@@ -3775,7 +3847,7 @@ static int fill_filter_caches(H264Context *h, int mb_type)
 
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
     if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]);
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
         if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag)
@@ -3783,7 +3855,7 @@ static int fill_filter_caches(H264Context *h, int mb_type)
         } else {
             if (curr_mb_field_flag)
                 top_xy += h->mb_stride &
-                    (((h->cur_pic.f.mb_type[top_xy] >> 7) & 1) - 1);
+                    (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1);
             if (left_mb_field_flag != curr_mb_field_flag)
                 left_xy[LBOT] += h->mb_stride;
         }
@@ -3797,25 +3869,25 @@ static int fill_filter_caches(H264Context *h, int mb_type)
          * This is a conservative estimate: could also check beta_offset
          * and more accurate chroma_qp. */
         int qp_thresh = h->qp_thresh; // FIXME strictly we should store qp_thresh for each mb of a slice
-        int qp        = h->cur_pic.f.qscale_table[mb_xy];
+        int qp        = h->cur_pic.qscale_table[mb_xy];
         if (qp <= qp_thresh &&
             (left_xy[LTOP] < 0 ||
-             ((qp + h->cur_pic.f.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
+             ((qp + h->cur_pic.qscale_table[left_xy[LTOP]] + 1) >> 1) <= qp_thresh) &&
             (top_xy < 0 ||
-             ((qp + h->cur_pic.f.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
+             ((qp + h->cur_pic.qscale_table[top_xy] + 1) >> 1) <= qp_thresh)) {
             if (!FRAME_MBAFF)
                 return 1;
             if ((left_xy[LTOP] < 0 ||
-                 ((qp + h->cur_pic.f.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
+                 ((qp + h->cur_pic.qscale_table[left_xy[LBOT]] + 1) >> 1) <= qp_thresh) &&
                 (top_xy < h->mb_stride ||
-                 ((qp + h->cur_pic.f.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh))
+                 ((qp + h->cur_pic.qscale_table[top_xy - h->mb_stride] + 1) >> 1) <= qp_thresh))
                 return 1;
         }
     }
 
-    top_type        = h->cur_pic.f.mb_type[top_xy];
-    left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]];
-    left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]];
+    top_type        = h->cur_pic.mb_type[top_xy];
+    left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]];
+    left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]];
     if (h->deblocking_filter == 2) {
         if (h->slice_table[top_xy] != h->slice_num)
             top_type = 0;
@@ -3920,7 +3992,7 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
                 int mb_xy, mb_type;
                 mb_xy         = h->mb_xy = mb_x + mb_y * h->mb_stride;
                 h->slice_num  = h->slice_table[mb_xy];
-                mb_type       = h->cur_pic.f.mb_type[mb_xy];
+                mb_type       = h->cur_pic.mb_type[mb_xy];
                 h->list_count = h->list_counts[mb_xy];
 
                 if (FRAME_MBAFF)
@@ -3955,8 +4027,8 @@ static void loop_filter(H264Context *h, int start_x, int end_x)
                                  uvlinesize, 0);
                 if (fill_filter_caches(h, mb_type))
                     continue;
-                h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mb_xy]);
-                h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mb_xy]);
+                h->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);
+                h->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);
 
                 if (FRAME_MBAFF) {
                     ff_h264_filter_mb(h, mb_x, mb_y, dest_y, dest_cb, dest_cr,
@@ -3978,9 +4050,9 @@ static void predict_field_decoding_flag(H264Context *h)
 {
     const int mb_xy = h->mb_x + h->mb_y * h->mb_stride;
     int mb_type     = (h->slice_table[mb_xy - 1] == h->slice_num) ?
-                      h->cur_pic.f.mb_type[mb_xy - 1] :
+                      h->cur_pic.mb_type[mb_xy - 1] :
                       (h->slice_table[mb_xy - h->mb_stride] == h->slice_num) ?
-                      h->cur_pic.f.mb_type[mb_xy - h->mb_stride] : 0;
+                      h->cur_pic.mb_type[mb_xy - h->mb_stride] : 0;
     h->mb_mbaff     = h->mb_field_decoding_flag = IS_INTERLACED(mb_type) ? 1 : 0;
 }
 
@@ -4014,7 +4086,7 @@ static void decode_finish_row(H264Context *h)
     if (h->droppable)
         return;
 
-    ff_thread_report_progress(&h->cur_pic_ptr->f, top + height - 1,
+    ff_thread_report_progress(&h->cur_pic_ptr->tf, top + height - 1,
                               h->picture_structure == PICT_BOTTOM_FIELD);
 }
 
@@ -4513,9 +4585,8 @@ again:
 
 end:
     /* clean up */
-    if (h->cur_pic_ptr && h->cur_pic_ptr->owner2 == h &&
-        !h->droppable) {
-        ff_thread_report_progress(&h->cur_pic_ptr->f, INT_MAX,
+    if (h->cur_pic_ptr && !h->droppable) {
+        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
                                   h->picture_structure == PICT_BOTTOM_FIELD);
     }
 
@@ -4543,6 +4614,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     H264Context *h     = avctx->priv_data;
     AVFrame *pict      = data;
     int buf_index      = 0;
+    int ret;
 
     h->flags  = avctx->flags;
 
@@ -4571,8 +4643,9 @@ out:
             h->delayed_pic[i] = h->delayed_pic[i + 1];
 
         if (out) {
+            if ((ret = av_frame_ref(pict, &out->f)) < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = out->f;
         }
 
         return buf_index;
@@ -4605,8 +4678,9 @@ out:
             /* Wait for second field. */
             *got_frame = 0;
         } else {
+            if ((ret = av_frame_ref(pict, &h->next_output_pic->f)) < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = h->next_output_pic->f;
         }
     }
 
@@ -4635,13 +4709,15 @@ static av_cold int h264_decode_end(AVCodecContext *avctx)
 
     ff_h264_free_context(h);
 
-    if (h->DPB && !h->avctx->internal->is_copy) {
-        for (i = 0; i < h->picture_count; i++) {
-            free_picture(h, &h->DPB[i]);
+    if (h->DPB) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            unref_picture(h, &h->DPB[i]);
         }
     }
     av_freep(&h->DPB);
 
+    unref_picture(h, &h->cur_pic);
+
     return 0;
 }
 
index e3e28911f57c4153838cb225f8c23bbe29952e44..e33f37e359497c533d27a21d176d2d818b82867e 100644 (file)
@@ -266,8 +266,6 @@ typedef struct H264Context {
     Picture *DPB;
     Picture *cur_pic_ptr;
     Picture cur_pic;
-    int picture_count;
-    int picture_range_start, picture_range_end;
 
     int pixel_shift;    ///< 0 for 8-bit H264, 1 for high-bit-depth H264
     int chroma_qp[2];   // QPc
@@ -621,6 +619,11 @@ typedef struct H264Context {
     uint8_t *bipred_scratchpad;
     uint8_t *edge_emu_buffer;
     int16_t *dc_val_base;
+
+    AVBufferPool *qscale_table_pool;
+    AVBufferPool *mb_type_pool;
+    AVBufferPool *motion_val_pool;
+    AVBufferPool *ref_index_pool;
 } H264Context;
 
 extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
@@ -876,7 +879,7 @@ static av_always_inline void write_back_motion_list(H264Context *h,
                                                     int b_xy, int b8_xy,
                                                     int mb_type, int list)
 {
-    int16_t(*mv_dst)[2] = &h->cur_pic.f.motion_val[list][b_xy];
+    int16_t(*mv_dst)[2] = &h->cur_pic.motion_val[list][b_xy];
     int16_t(*mv_src)[2] = &h->mv_cache[list][scan8[0]];
     AV_COPY128(mv_dst + 0 * b_stride, mv_src + 8 * 0);
     AV_COPY128(mv_dst + 1 * b_stride, mv_src + 8 * 1);
@@ -897,7 +900,7 @@ static av_always_inline void write_back_motion_list(H264Context *h,
     }
 
     {
-        int8_t *ref_index = &h->cur_pic.f.ref_index[list][b8_xy];
+        int8_t *ref_index = &h->cur_pic.ref_index[list][b8_xy];
         int8_t *ref_cache = h->ref_cache[list];
         ref_index[0 + 0 * 2] = ref_cache[scan8[0]];
         ref_index[1 + 0 * 2] = ref_cache[scan8[4]];
@@ -915,7 +918,7 @@ static av_always_inline void write_back_motion(H264Context *h, int mb_type)
     if (USES_LIST(mb_type, 0)) {
         write_back_motion_list(h, b_stride, b_xy, b8_xy, mb_type, 0);
     } else {
-        fill_rectangle(&h->cur_pic.f.ref_index[0][b8_xy],
+        fill_rectangle(&h->cur_pic.ref_index[0][b8_xy],
                        2, 2, 2, (uint8_t)LIST_NOT_USED, 1);
     }
     if (USES_LIST(mb_type, 1))
index 4effc7d5e01cf438fbbf5a68c61d11f32178909d..12eb2c7b2247c67d8468e7b75f522e814b350444 100644 (file)
@@ -1283,8 +1283,8 @@ static int decode_cabac_field_decoding_flag(H264Context *h) {
 
     unsigned long ctx = 0;
 
-    ctx += h->mb_field_decoding_flag & !!h->mb_x; //for FMO:(s->current_picture.f.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
-    ctx += (h->cur_pic.f.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
+    ctx += h->mb_field_decoding_flag & !!h->mb_x; //for FMO:(s->current_picture.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
+    ctx += (h->cur_pic.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == h->slice_num);
 
     return get_cabac_noinline( &h->cabac, &(h->cabac_state+70)[ctx] );
 }
@@ -1328,13 +1328,13 @@ static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
         mba_xy = mb_xy - 1;
         if( (mb_y&1)
             && h->slice_table[mba_xy] == h->slice_num
-            && MB_FIELD == !!IS_INTERLACED( h->cur_pic.f.mb_type[mba_xy] ) )
+            && MB_FIELD == !!IS_INTERLACED( h->cur_pic.mb_type[mba_xy] ) )
             mba_xy += h->mb_stride;
         if( MB_FIELD ){
             mbb_xy = mb_xy - h->mb_stride;
             if( !(mb_y&1)
                 && h->slice_table[mbb_xy] == h->slice_num
-                && IS_INTERLACED( h->cur_pic.f.mb_type[mbb_xy] ) )
+                && IS_INTERLACED( h->cur_pic.mb_type[mbb_xy] ) )
                 mbb_xy -= h->mb_stride;
         }else
             mbb_xy = mb_x + (mb_y-1)*h->mb_stride;
@@ -1344,9 +1344,9 @@ static int decode_cabac_mb_skip( H264Context *h, int mb_x, int mb_y ) {
         mbb_xy = mb_xy - (h->mb_stride << FIELD_PICTURE);
     }
 
-    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mba_xy] ))
+    if( h->slice_table[mba_xy] == h->slice_num && !IS_SKIP(h->cur_pic.mb_type[mba_xy] ))
         ctx++;
-    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP(h->cur_pic.f.mb_type[mbb_xy] ))
+    if( h->slice_table[mbb_xy] == h->slice_num && !IS_SKIP(h->cur_pic.mb_type[mbb_xy] ))
         ctx++;
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_B )
@@ -1893,7 +1893,7 @@ int ff_h264_decode_mb_cabac(H264Context *h) {
         /* read skip flags */
         if( skip ) {
             if( FRAME_MBAFF && (h->mb_y&1)==0 ){
-                h->cur_pic.f.mb_type[mb_xy] = MB_TYPE_SKIP;
+                h->cur_pic.mb_type[mb_xy] = MB_TYPE_SKIP;
                 h->next_mb_skipped = decode_cabac_mb_skip( h, h->mb_x, h->mb_y+1 );
                 if(!h->next_mb_skipped)
                     h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);
@@ -2012,10 +2012,10 @@ decode_intra_mb:
         h->cbp_table[mb_xy] = 0xf7ef;
         h->chroma_pred_mode_table[mb_xy] = 0;
         // In deblocking, the quantizer is 0
-        h->cur_pic.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
-        h->cur_pic.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.mb_type[mb_xy] = mb_type;
         h->last_qscale_diff = 0;
         return 0;
     }
@@ -2309,7 +2309,7 @@ decode_intra_mb:
             AV_WN32A(&nnz_cache[4+8*10], top_empty);
         }
     }
-    h->cur_pic.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.mb_type[mb_xy] = mb_type;
 
     if( cbp || IS_INTRA16x16( mb_type ) ) {
         const uint8_t *scan, *scan8x8;
@@ -2411,7 +2411,7 @@ decode_intra_mb:
         h->last_qscale_diff = 0;
     }
 
-    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
+    h->cur_pic.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
index 4b44cbefa931b5076beb00c1b290515b171dc528..be7d2e969807b44fd4ff73d275f9dc11d6f29b2d 100644 (file)
@@ -769,11 +769,11 @@ decode_intra_mb:
         skip_bits_long(&h->gb, mb_size);
 
         // In deblocking, the quantizer is 0
-        h->cur_pic.f.qscale_table[mb_xy] = 0;
+        h->cur_pic.qscale_table[mb_xy] = 0;
         // All coeffs are present
         memset(h->non_zero_count[mb_xy], 16, 48);
 
-        h->cur_pic.f.mb_type[mb_xy] = mb_type;
+        h->cur_pic.mb_type[mb_xy] = mb_type;
         return 0;
     }
 
@@ -1068,7 +1068,7 @@ decode_intra_mb:
     }
     h->cbp=
     h->cbp_table[mb_xy]= cbp;
-    h->cur_pic.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.mb_type[mb_xy] = mb_type;
 
     if(cbp || IS_INTRA16x16(mb_type)){
         int i4x4, i8x8, chroma_idx;
@@ -1168,7 +1168,7 @@ decode_intra_mb:
         fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
         fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
     }
-    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
+    h->cur_pic.qscale_table[mb_xy] = h->qscale;
     write_back_non_zero_count(h);
 
     return 0;
index 9d8758edfcd3c39c5f674ec511e9a0cdee78bb00..0e81280612f710b2e7e8fee657e0c4d9e3d33be2 100644 (file)
@@ -87,7 +87,7 @@ static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field,
                 poc= (poc&~3) + rfield + 1;
 
             for(j=start; j<end; j++){
-                if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].f.reference & 3) == poc) {
+                if (4 * h->ref_list[0][j].frame_num + (h->ref_list[0][j].reference & 3) == poc) {
                     int cur_ref= mbafi ? (j-16)^field : j;
                     if (ref1->mbaff)
                         map[list][2 * old_ref + (rfield^field) + 16] = cur_ref;
@@ -105,12 +105,12 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
     Picture * const cur = h->cur_pic_ptr;
     int list, j, field;
     int sidx= (h->picture_structure&1)^1;
-    int ref1sidx = (ref1->f.reference&1)^1;
+    int ref1sidx = (ref1->reference&1)^1;
 
     for(list=0; list<2; list++){
         cur->ref_count[sidx][list] = h->ref_count[list];
         for(j=0; j<h->ref_count[list]; j++)
-            cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].f.reference & 3);
+            cur->ref_poc[sidx][list][j] = 4 * h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference & 3);
     }
 
     if(h->picture_structure == PICT_FRAME){
@@ -126,8 +126,8 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
         int *col_poc = h->ref_list[1]->field_poc;
         h->col_parity= (FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc));
         ref1sidx=sidx= h->col_parity;
-    } else if (!(h->picture_structure & h->ref_list[1][0].f.reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
-        h->col_fieldoff = 2 * h->ref_list[1][0].f.reference - 3;
+    } else if (!(h->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff) { // FL -> FL & differ parity
+        h->col_fieldoff = 2 * h->ref_list[1][0].reference - 3;
     }
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_B || h->direct_spatial_mv_pred)
@@ -143,7 +143,7 @@ void ff_h264_direct_ref_list_init(H264Context * const h){
 
 static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y)
 {
-    int ref_field = ref->f.reference - 1;
+    int ref_field = ref->reference - 1;
     int ref_field_picture = ref->field_picture;
     int ref_height = 16*h->mb_height >> ref_field_picture;
 
@@ -153,7 +153,7 @@ static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y
     //FIXME it can be safe to access mb stuff
     //even if pixels aren't deblocked yet
 
-    ff_thread_await_progress(&ref->f,
+    ff_thread_await_progress(&ref->tf,
                              FFMIN(16 * mb_y >> ref_field_picture, ref_height - 1),
                              ref_field_picture && ref_field);
 }
@@ -172,7 +172,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
     int mv[2];
     int list;
 
-    assert(h->ref_list[1][0].f.reference & 3);
+    assert(h->ref_list[1][0].reference & 3);
 
     await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
@@ -234,7 +234,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
         return;
     }
 
-    if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+    if (IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
             mb_y = (h->mb_y&~1) + h->col_parity;
             mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
@@ -248,8 +248,8 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
             mb_y = h->mb_y&~1;
             mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
-            mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride];
+            mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + h->mb_stride];
             b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
@@ -268,7 +268,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){
         }else{                                           //     AFR/FR    -> AFR/FR
 single_col:
             mb_type_col[0] =
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
 
             sub_mb_type |= MB_TYPE_16x16|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
             if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
@@ -288,10 +288,10 @@ single_col:
 
     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
 
-    l1mv0  = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
-    l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
-    l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
+    l1mv0  = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
+    l1ref0 = &h->ref_list[1][0].ref_index [0][4 * mb_xy];
+    l1ref1 = &h->ref_list[1][0].ref_index [1][4 * mb_xy];
     if(!b8_stride){
         if(h->mb_y&1){
             l1ref0 += 2;
@@ -419,11 +419,11 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
     unsigned int sub_mb_type;
     int i8, i4;
 
-    assert(h->ref_list[1][0].f.reference & 3);
+    assert(h->ref_list[1][0].reference & 3);
 
     await_reference_mb_row(h, &h->ref_list[1][0], h->mb_y + !!IS_INTERLACED(*mb_type));
 
-    if (IS_INTERLACED(h->ref_list[1][0].f.mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+    if (IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
         if (!IS_INTERLACED(*mb_type)) {                          //     AFR/FR    -> AFL/FL
             mb_y = (h->mb_y&~1) + h->col_parity;
             mb_xy= h->mb_x + ((h->mb_y&~1) + h->col_parity)*h->mb_stride;
@@ -437,8 +437,8 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
         if(IS_INTERLACED(*mb_type)){                     // AFL       /FL -> AFR/FR
             mb_y = h->mb_y&~1;
             mb_xy= h->mb_x + (h->mb_y&~1)*h->mb_stride;
-            mb_type_col[0] = h->ref_list[1][0].f.mb_type[mb_xy];
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + h->mb_stride];
+            mb_type_col[0] = h->ref_list[1][0].mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy + h->mb_stride];
             b8_stride = 2+4*h->mb_stride;
             b4_stride *= 6;
             if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) {
@@ -458,7 +458,7 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){
         }else{                                           //     AFR/FR    -> AFR/FR
 single_col:
             mb_type_col[0] =
-            mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy];
+            mb_type_col[1] = h->ref_list[1][0].mb_type[mb_xy];
 
             sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */
             if(!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)){
@@ -478,10 +478,10 @@ single_col:
 
     await_reference_mb_row(h, &h->ref_list[1][0], mb_y);
 
-    l1mv0  = &h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = &h->ref_list[1][0].f.motion_val[1][h->mb2b_xy [mb_xy]];
-    l1ref0 = &h->ref_list[1][0].f.ref_index [0][4 * mb_xy];
-    l1ref1 = &h->ref_list[1][0].f.ref_index [1][4 * mb_xy];
+    l1mv0  = &h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = &h->ref_list[1][0].motion_val[1][h->mb2b_xy [mb_xy]];
+    l1ref0 = &h->ref_list[1][0].ref_index [0][4 * mb_xy];
+    l1ref1 = &h->ref_list[1][0].ref_index [1][4 * mb_xy];
     if(!b8_stride){
         if(h->mb_y&1){
             l1ref0 += 2;
index 929997c778cf1e70758464c3005689ae08a828c7..2e4683d8e3c143d0d0a22a214caf1ff69054484a 100644 (file)
@@ -256,10 +256,10 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h,
     int a = h->slice_alpha_c0_offset - qp_bd_offset;
     int b = h->slice_beta_offset - qp_bd_offset;
 
-    int mb_type = h->cur_pic.f.mb_type[mb_xy];
-    int qp      = h->cur_pic.f.qscale_table[mb_xy];
-    int qp0     = h->cur_pic.f.qscale_table[mb_xy - 1];
-    int qp1     = h->cur_pic.f.qscale_table[h->top_mb_xy];
+    int mb_type = h->cur_pic.mb_type[mb_xy];
+    int qp      = h->cur_pic.qscale_table[mb_xy];
+    int qp0     = h->cur_pic.qscale_table[mb_xy - 1];
+    int qp1     = h->cur_pic.qscale_table[h->top_mb_xy];
     int qpc = get_chroma_qp( h, 0, qp );
     int qpc0 = get_chroma_qp( h, 0, qp0 );
     int qpc1 = get_chroma_qp( h, 0, qp1 );
@@ -497,10 +497,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             for(j=0; j<2; j++, mbn_xy += h->mb_stride){
                 DECLARE_ALIGNED(8, int16_t, bS)[4];
                 int qp;
-                if (IS_INTRA(mb_type | h->cur_pic.f.mb_type[mbn_xy])) {
+                if (IS_INTRA(mb_type | h->cur_pic.mb_type[mbn_xy])) {
                     AV_WN64A(bS, 0x0003000300030003ULL);
                 } else {
-                    if (!CABAC && IS_8x8DCT(h->cur_pic.f.mb_type[mbn_xy])) {
+                    if (!CABAC && IS_8x8DCT(h->cur_pic.mb_type[mbn_xy])) {
                         bS[0]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+0]);
                         bS[1]= 1+((h->cbp_table[mbn_xy] & 0x4000)||h->non_zero_count_cache[scan8[0]+1]);
                         bS[2]= 1+((h->cbp_table[mbn_xy] & 0x8000)||h->non_zero_count_cache[scan8[0]+2]);
@@ -515,12 +515,12 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
                 }
                 // Do not use s->qscale as luma quantizer because it has not the same
                 // value in IPCM macroblocks.
-                qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbn_xy] + 1) >> 1;
+                qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbn_xy] + 1) >> 1;
                 tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
                 { int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
                 filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, a, b, h, 0 );
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbn_xy]) + 1) >> 1;
                 if (chroma) {
                     if (chroma444) {
                         filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], a, b, h, 0);
@@ -580,10 +580,10 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
             // Do not use s->qscale as luma quantizer because it has not the same
             // value in IPCM macroblocks.
             if(bS[0]+bS[1]+bS[2]+bS[3]){
-                qp = (h->cur_pic.f.qscale_table[mb_xy] + h->cur_pic.f.qscale_table[mbm_xy] + 1) >> 1;
+                qp = (h->cur_pic.qscale_table[mb_xy] + h->cur_pic.qscale_table[mbm_xy] + 1) >> 1;
                 tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
-                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
-                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.f.qscale_table[mbm_xy]) + 1) >> 1;
+                chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp(h, 0, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
+                chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp(h, 1, h->cur_pic.qscale_table[mbm_xy]) + 1) >> 1;
                 if( dir == 0 ) {
                     filter_mb_edgev( &img_y[0], linesize, bS, qp, a, b, h, 1 );
                     if (chroma) {
@@ -663,7 +663,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
         /* Filter edge */
         // Do not use s->qscale as luma quantizer because it has not the same
         // value in IPCM macroblocks.
-        qp = h->cur_pic.f.qscale_table[mb_xy];
+        qp = h->cur_pic.qscale_table[mb_xy];
         tprintf(h->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
         if( dir == 0 ) {
             filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
@@ -702,7 +702,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
 
 void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize) {
     const int mb_xy= mb_x + mb_y*h->mb_stride;
-    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
     int first_vertical_edge_done = 0;
     av_unused int dir;
@@ -758,9 +758,9 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
             }
         }
 
-        mb_qp   = h->cur_pic.f.qscale_table[mb_xy];
-        mbn0_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[0]];
-        mbn1_qp = h->cur_pic.f.qscale_table[h->left_mb_xy[1]];
+        mb_qp   = h->cur_pic.qscale_table[mb_xy];
+        mbn0_qp = h->cur_pic.qscale_table[h->left_mb_xy[0]];
+        mbn1_qp = h->cur_pic.qscale_table[h->left_mb_xy[1]];
         qp[0] = ( mb_qp + mbn0_qp + 1 ) >> 1;
         bqp[0] = ( get_chroma_qp( h, 0, mb_qp ) +
                    get_chroma_qp( h, 0, mbn0_qp ) + 1 ) >> 1;
index b596567429f568c640c017f5c9996413739516a2..a39d4c9ca0e4fd8455da341cde5471778bfbca15 100644 (file)
@@ -43,7 +43,7 @@ static av_noinline void FUNC(hl_decode_mb)(H264Context *h)
     const int mb_x    = h->mb_x;
     const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     uint8_t *dest_y, *dest_cb, *dest_cr;
     int linesize, uvlinesize /*dct_offset*/;
     int i, j;
@@ -279,7 +279,7 @@ static av_noinline void FUNC(hl_decode_mb_444)(H264Context *h)
     const int mb_x    = h->mb_x;
     const int mb_y    = h->mb_y;
     const int mb_xy   = h->mb_xy;
-    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
     uint8_t *dest[3];
     int linesize;
     int i, j, p;
index ad54558b91ff893f2352f76836299b5b28d4013d..dee02f59088c7d6abde176f830806bfab05f7765 100644 (file)
@@ -68,7 +68,7 @@ static void MCFUNC(hl_motion)(H264Context *h, uint8_t *dest_y,
                               h264_biweight_func *weight_avg)
 {
     const int mb_xy   = h->mb_xy;
-    const int mb_type = h->cur_pic.f.mb_type[mb_xy];
+    const int mb_type = h->cur_pic.mb_type[mb_xy];
 
     assert(IS_INTER(mb_type));
 
index b49ff31c153ebdd05c100ddf29592f5f3e8a6657..a61ad20f66a6379decc11bb887b9f494fa88876b 100644 (file)
@@ -48,15 +48,15 @@ static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C,
         const int mb_type = mb_types[xy + (y4 >> 2) * h->mb_stride];    \
         if (!USES_LIST(mb_type, list))                                  \
             return LIST_NOT_USED;                                       \
-        mv = h->cur_pic_ptr->f.motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
+        mv = h->cur_pic_ptr->motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
         h->mv_cache[list][scan8[0] - 2][0] = mv[0];                     \
         h->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP;               \
-        return h->cur_pic_ptr->f.ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
+        return h->cur_pic_ptr->ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
 
         if (topright_ref == PART_NOT_AVAILABLE
             && i >= scan8[0] + 8 && (i & 7) == 4
             && h->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
-            const uint32_t *mb_types = h->cur_pic_ptr->f.mb_type;
+            const uint32_t *mb_types = h->cur_pic_ptr->mb_type;
             const int16_t *mv;
             AV_ZERO32(h->mv_cache[list][scan8[0] - 2]);
             *C = h->mv_cache[list][scan8[0] - 2];
@@ -253,8 +253,8 @@ static av_always_inline void pred_pskip_motion(H264Context *const h)
 {
     DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 };
     DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
-    int8_t *ref     = h->cur_pic.f.ref_index[0];
-    int16_t(*mv)[2] = h->cur_pic.f.motion_val[0];
+    int8_t *ref     = h->cur_pic.ref_index[0];
+    int16_t(*mv)[2] = h->cur_pic.motion_val[0];
     int top_ref, left_ref, diagonal_ref, match_count, mx, my;
     const int16_t *A, *B, *C;
     int b_stride = h->b_stride;
@@ -370,7 +370,7 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
     left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
     h->left_block = left_block_options[0];
     if (FRAME_MBAFF) {
-        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.f.mb_type[mb_xy - 1]);
+        const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]);
         const int curr_mb_field_flag = IS_INTERLACED(mb_type);
         if (h->mb_y & 1) {
             if (left_mb_field_flag != curr_mb_field_flag) {
@@ -388,9 +388,9 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
             }
         } else {
             if (curr_mb_field_flag) {
-                topleft_xy  += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy - 1] >> 7) & 1) - 1);
-                topright_xy += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy + 1] >> 7) & 1) - 1);
-                top_xy      += h->mb_stride & (((h->cur_pic.f.mb_type[top_xy]     >> 7) & 1) - 1);
+                topleft_xy  += h->mb_stride & (((h->cur_pic.mb_type[top_xy - 1] >> 7) & 1) - 1);
+                topright_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy + 1] >> 7) & 1) - 1);
+                top_xy      += h->mb_stride & (((h->cur_pic.mb_type[top_xy]     >> 7) & 1) - 1);
             }
             if (left_mb_field_flag != curr_mb_field_flag) {
                 if (curr_mb_field_flag) {
@@ -410,11 +410,11 @@ static void fill_decode_neighbors(H264Context *h, int mb_type)
     h->left_mb_xy[LBOT] = left_xy[LBOT];
     //FIXME do we need all in the context?
 
-    h->topleft_type    = h->cur_pic.f.mb_type[topleft_xy];
-    h->top_type        = h->cur_pic.f.mb_type[top_xy];
-    h->topright_type   = h->cur_pic.f.mb_type[topright_xy];
-    h->left_type[LTOP] = h->cur_pic.f.mb_type[left_xy[LTOP]];
-    h->left_type[LBOT] = h->cur_pic.f.mb_type[left_xy[LBOT]];
+    h->topleft_type    = h->cur_pic.mb_type[topleft_xy];
+    h->top_type        = h->cur_pic.mb_type[top_xy];
+    h->topright_type   = h->cur_pic.mb_type[topright_xy];
+    h->left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]];
+    h->left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]];
 
     if (FMO) {
         if (h->slice_table[topleft_xy] != h->slice_num)
@@ -480,7 +480,7 @@ static void fill_decode_caches(H264Context *h, int mb_type)
                         h->left_samples_available    &= 0xFF5F;
                     }
                 } else {
-                    int left_typei = h->cur_pic.f.mb_type[left_xy[LTOP] + h->mb_stride];
+                    int left_typei = h->cur_pic.mb_type[left_xy[LTOP] + h->mb_stride];
 
                     assert(left_xy[LTOP] == left_xy[LBOT]);
                     if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
@@ -602,9 +602,9 @@ static void fill_decode_caches(H264Context *h, int mb_type)
         int b_stride = h->b_stride;
         for (list = 0; list < h->list_count; list++) {
             int8_t *ref_cache = &h->ref_cache[list][scan8[0]];
-            int8_t *ref       = h->cur_pic.f.ref_index[list];
+            int8_t *ref       = h->cur_pic.ref_index[list];
             int16_t(*mv_cache)[2] = &h->mv_cache[list][scan8[0]];
-            int16_t(*mv)[2]       = h->cur_pic.f.motion_val[list];
+            int16_t(*mv)[2]       = h->cur_pic.motion_val[list];
             if (!USES_LIST(mb_type, list))
                 continue;
             assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
@@ -821,8 +821,8 @@ static void av_unused decode_mb_skip(H264Context *h)
     }
 
     write_back_motion(h, mb_type);
-    h->cur_pic.f.mb_type[mb_xy]      = mb_type;
-    h->cur_pic.f.qscale_table[mb_xy] = h->qscale;
+    h->cur_pic.mb_type[mb_xy]      = mb_type;
+    h->cur_pic.qscale_table[mb_xy] = h->qscale;
     h->slice_table[mb_xy]            = h->slice_num;
     h->prev_mb_skipped               = 1;
 }
index ead18c5680a6eb350dcc4e0b680a07b00535cf02..2af47e3ed66c4f7b7936b04cb22a174edb5fb748 100644 (file)
 //#undef NDEBUG
 #include <assert.h>
 
+#define COPY_PICTURE(dst, src) \
+do {\
+    *(dst) = *(src);\
+    (dst)->f.extended_data = (dst)->f.data;\
+    (dst)->tf.f = &(dst)->f;\
+} while (0)
+
 
 static void pic_as_field(Picture *pic, const int parity){
     int i;
     for (i = 0; i < 4; ++i) {
         if (parity == PICT_BOTTOM_FIELD)
             pic->f.data[i] += pic->f.linesize[i];
-        pic->f.reference    = parity;
+        pic->reference    = parity;
         pic->f.linesize[i] *= 2;
     }
     pic->poc= pic->field_poc[parity == PICT_BOTTOM_FIELD];
@@ -47,10 +54,10 @@ static void pic_as_field(Picture *pic, const int parity){
 
 static int split_field_copy(Picture *dest, Picture *src,
                             int parity, int id_add){
-    int match = !!(src->f.reference & parity);
+    int match = !!(src->reference & parity);
 
     if (match) {
-        *dest = *src;
+        COPY_PICTURE(dest, src);
         if(parity != PICT_FRAME){
             pic_as_field(dest, parity);
             dest->pic_id *= 2;
@@ -66,9 +73,9 @@ static int build_def_list(Picture *def, Picture **in, int len, int is_long, int
     int index=0;
 
     while(i[0]<len || i[1]<len){
-        while (i[0] < len && !(in[ i[0] ] && (in[ i[0] ]->f.reference & sel)))
+        while (i[0] < len && !(in[ i[0] ] && (in[ i[0] ]->reference & sel)))
             i[0]++;
-        while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->f.reference & (sel^3))))
+        while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->reference & (sel^3))))
             i[1]++;
         if(i[0] < len){
             in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num;
@@ -132,8 +139,12 @@ int ff_h264_fill_default_ref_list(H264Context *h){
 
         if(lens[0] == lens[1] && lens[1] > 1){
             for (i = 0; h->default_ref_list[0][i].f.data[0] == h->default_ref_list[1][i].f.data[0] && i < lens[0]; i++);
-            if(i == lens[0])
-                FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]);
+            if (i == lens[0]) {
+                Picture tmp;
+                COPY_PICTURE(&tmp, &h->default_ref_list[1][0]);
+                COPY_PICTURE(&h->default_ref_list[1][0], &h->default_ref_list[1][1]);
+                COPY_PICTURE(&h->default_ref_list[1][1], &tmp);
+            }
         }
     }else{
         len = build_def_list(h->default_ref_list[0]    , h->short_ref, h->short_ref_count, 0, h->picture_structure);
@@ -181,13 +192,14 @@ static int pic_num_extract(H264Context *h, int pic_num, int *structure){
 }
 
 int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
-    int list, index, pic_structure;
+    int list, index, pic_structure, i;
 
     print_short_term(h);
     print_long_term(h);
 
     for(list=0; list<h->list_count; list++){
-        memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]);
+        for (i = 0; i < h->ref_count[list]; i++)
+            COPY_PICTURE(&h->ref_list[list][i], &h->default_ref_list[list][i]);
 
         if(get_bits1(&h->gb)){
             int pred= h->curr_pic_num;
@@ -224,11 +236,11 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
 
                         for(i= h->short_ref_count-1; i>=0; i--){
                             ref = h->short_ref[i];
-                            assert(ref->f.reference);
+                            assert(ref->reference);
                             assert(!ref->long_ref);
                             if(
                                    ref->frame_num == frame_num &&
-                                   (ref->f.reference & pic_structure)
+                                   (ref->reference & pic_structure)
                               )
                                 break;
                         }
@@ -245,8 +257,8 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
                             return -1;
                         }
                         ref = h->long_ref[long_idx];
-                        assert(!(ref && !ref->f.reference));
-                        if (ref && (ref->f.reference & pic_structure)) {
+                        assert(!(ref && !ref->reference));
+                        if (ref && (ref->reference & pic_structure)) {
                             ref->pic_id= pic_id;
                             assert(ref->long_ref);
                             i=0;
@@ -264,9 +276,9 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
                                 break;
                         }
                         for(; i > index; i--){
-                            h->ref_list[list][i]= h->ref_list[list][i-1];
+                            COPY_PICTURE(&h->ref_list[list][i], &h->ref_list[list][i - 1]);
                         }
-                        h->ref_list[list][index]= *ref;
+                        COPY_PICTURE(&h->ref_list[list][index], ref);
                         if (FIELD_PICTURE){
                             pic_as_field(&h->ref_list[list][index], pic_structure);
                         }
@@ -283,7 +295,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
             if (!h->ref_list[list][index].f.data[0]) {
                 av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture\n");
                 if (h->default_ref_list[list][0].f.data[0])
-                    h->ref_list[list][index]= h->default_ref_list[list][0];
+                    COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]);
                 else
                     return -1;
             }
@@ -299,15 +311,15 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){
         for(i=0; i<h->ref_count[list]; i++){
             Picture *frame = &h->ref_list[list][i];
             Picture *field = &h->ref_list[list][16+2*i];
-            field[0] = *frame;
+            COPY_PICTURE(field, frame);
             for(j=0; j<3; j++)
                 field[0].f.linesize[j] <<= 1;
-            field[0].f.reference = PICT_TOP_FIELD;
+            field[0].reference = PICT_TOP_FIELD;
             field[0].poc= field[0].field_poc[0];
-            field[1] = field[0];
+            COPY_PICTURE(field + 1, field);
             for(j=0; j<3; j++)
                 field[1].f.data[j] += frame->f.linesize[j];
-            field[1].f.reference = PICT_BOTTOM_FIELD;
+            field[1].reference = PICT_BOTTOM_FIELD;
             field[1].poc= field[1].field_poc[1];
 
             h->luma_weight[16+2*i][list][0] = h->luma_weight[16+2*i+1][list][0] = h->luma_weight[i][list][0];
@@ -333,12 +345,12 @@ void ff_h264_fill_mbaff_ref_list(H264Context *h){
  */
 static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){
     int i;
-    if (pic->f.reference &= refmask) {
+    if (pic->reference &= refmask) {
         return 0;
     } else {
         for(i = 0; h->delayed_pic[i]; i++)
             if(pic == h->delayed_pic[i]){
-                pic->f.reference = DELAYED_PIC_REF;
+                pic->reference = DELAYED_PIC_REF;
                 break;
             }
         return 1;
@@ -490,7 +502,7 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)
 
     if (h->short_ref_count &&
         h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&
-        !(FIELD_PICTURE && !h->first_field && h->cur_pic_ptr->f.reference)) {
+        !(FIELD_PICTURE && !h->first_field && h->cur_pic_ptr->reference)) {
         mmco[0].opcode = MMCO_SHORT2UNUSED;
         mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num;
         mmco_index = 1;
@@ -584,7 +596,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
                 h->long_ref_count++;
             }
 
-            h->cur_pic_ptr->f.reference |= h->picture_structure;
+            h->cur_pic_ptr->reference |= h->picture_structure;
             current_ref_assigned=1;
             break;
         case MMCO_SET_MAX_LONG:
@@ -619,7 +631,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
          */
         if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) {
             /* Just mark the second field valid */
-            h->cur_pic_ptr->f.reference = PICT_FRAME;
+            h->cur_pic_ptr->reference = PICT_FRAME;
         } else if (h->cur_pic_ptr->long_ref) {
             av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference "
                                            "assignment for second field "
@@ -638,7 +650,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
 
             h->short_ref[0]= h->cur_pic_ptr;
             h->short_ref_count++;
-            h->cur_pic_ptr->f.reference |= h->picture_structure;
+            h->cur_pic_ptr->reference |= h->picture_structure;
         }
     }
 
index 6aa7335bf9106eadd40b6886ef9d76681a032c17..7a58ba4688242a28c39fe64dd09a880fc2a6c133 100644 (file)
@@ -241,7 +241,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     ff_huffyuv_common_init(avctx);
     memset(s->vlc, 0, 3 * sizeof(VLC));
 
-    avctx->coded_frame = &s->picture;
     s->interlaced = s->height > 288;
 
     s->bgr32 = 1;
@@ -337,7 +336,6 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
     HYuvContext *s = avctx->priv_data;
     int i;
 
-    avctx->coded_frame= &s->picture;
     ff_huffyuv_alloc_temp(s);
 
     for (i = 0; i < 6; i++)
@@ -443,7 +441,7 @@ static void decode_bgr_bitstream(HYuvContext *s, int count)
     }
 }
 
-static void draw_slice(HYuvContext *s, int y)
+static void draw_slice(HYuvContext *s, AVFrame *frame, int y)
 {
     int h, cy, i;
     int offset[AV_NUM_DATA_POINTERS];
@@ -460,14 +458,14 @@ static void draw_slice(HYuvContext *s, int y)
         cy = y;
     }
 
-    offset[0] = s->picture.linesize[0]*y;
-    offset[1] = s->picture.linesize[1]*cy;
-    offset[2] = s->picture.linesize[2]*cy;
+    offset[0] = frame->linesize[0] * y;
+    offset[1] = frame->linesize[1] * cy;
+    offset[2] = frame->linesize[2] * cy;
     for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
         offset[i] = 0;
     emms_c();
 
-    s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
+    s->avctx->draw_horiz_band(s->avctx, frame, offset, y, 3, h);
 
     s->last_slice_end = y + h;
 }
@@ -482,11 +480,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     const int width2 = s->width>>1;
     const int height = s->height;
     int fake_ystride, fake_ustride, fake_vstride;
-    AVFrame * const p = &s->picture;
+    ThreadFrame frame = { .f = data };
+    AVFrame * const p = data;
     int table_size = 0;
 
-    AVFrame *picture = data;
-
     av_fast_malloc(&s->bitstream_buffer,
                    &s->bitstream_buffer_size,
                    buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -497,11 +494,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer,
                      (const uint32_t*)buf, buf_size / 4);
 
-    if (p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference = 0;
-    if (ff_thread_get_buffer(avctx, p) < 0) {
+    if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -572,7 +565,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         if (y >= s->height) break;
                     }
 
-                    draw_slice(s, y);
+                    draw_slice(s, p, y);
 
                     ydst = p->data[0] + p->linesize[0]*y;
                     udst = p->data[1] + p->linesize[1]*cy;
@@ -594,7 +587,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         }
                     }
                 }
-                draw_slice(s, height);
+                draw_slice(s, p, height);
 
                 break;
             case MEDIAN:
@@ -651,7 +644,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         }
                         if (y >= height) break;
                     }
-                    draw_slice(s, y);
+                    draw_slice(s, p, y);
 
                     decode_422_bitstream(s, width);
 
@@ -666,7 +659,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                     }
                 }
 
-                draw_slice(s, height);
+                draw_slice(s, p, height);
                 break;
             }
         }
@@ -710,7 +703,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                     }
                 }
                 // just 1 large slice as this is not possible in reverse order
-                draw_slice(s, height);
+                draw_slice(s, p, height);
                 break;
             default:
                 av_log(avctx, AV_LOG_ERROR,
@@ -724,7 +717,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
     emms_c();
 
-    *picture = *p;
     *got_frame = 1;
 
     return (get_bits_count(&s->gb) + 31) / 32 * 4 + table_size;
@@ -735,9 +727,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
     HYuvContext *s = avctx->priv_data;
     int i;
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
     ff_huffyuv_common_end(s);
     av_freep(&s->bitstream_buffer);
 
index 05cd673faa80c18459b8b22c5c1a54d890b8be4e..9d34f3e2476f17677d7afb10f6f32ad58ae27f7d 100644 (file)
@@ -66,7 +66,6 @@ typedef struct
 typedef struct IdcinContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
 
     const unsigned char *buf;
     int size;
@@ -168,12 +167,10 @@ static av_cold int idcin_decode_init(AVCodecContext *avctx)
         huff_build_tree(s, i);
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-
     return 0;
 }
 
-static void idcin_decode_vlcs(IdcinContext *s)
+static void idcin_decode_vlcs(IdcinContext *s, AVFrame *frame)
 {
     hnode *hnodes;
     long x, y;
@@ -182,8 +179,8 @@ static void idcin_decode_vlcs(IdcinContext *s)
     int bit_pos, node_num, dat_pos;
 
     prev = bit_pos = dat_pos = 0;
-    for (y = 0; y < (s->frame.linesize[0] * s->avctx->height);
-        y += s->frame.linesize[0]) {
+    for (y = 0; y < (frame->linesize[0] * s->avctx->height);
+        y += frame->linesize[0]) {
         for (x = y; x < y + s->avctx->width; x++) {
             node_num = s->num_huff_nodes[prev];
             hnodes = s->huff_nodes[prev];
@@ -203,7 +200,7 @@ static void idcin_decode_vlcs(IdcinContext *s)
                 bit_pos--;
             }
 
-            s->frame.data[0][x] = node_num;
+            frame->data[0][x] = node_num;
             prev = node_num;
         }
     }
@@ -217,51 +214,38 @@ static int idcin_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     IdcinContext *s = avctx->priv_data;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+    AVFrame *frame = data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    if (ff_get_buffer(avctx, &s->frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "  id CIN Video: get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    idcin_decode_vlcs(s);
+    idcin_decode_vlcs(s, frame);
 
     if (pal) {
-        s->frame.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
         memcpy(s->pal, pal, AVPALETTE_SIZE);
     }
     /* make the palette available on the way out */
-    memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
+    memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
 }
 
-static av_cold int idcin_decode_end(AVCodecContext *avctx)
-{
-    IdcinContext *s = avctx->priv_data;
-
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    return 0;
-}
-
 AVCodec ff_idcin_decoder = {
     .name           = "idcinvideo",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_IDCIN,
     .priv_data_size = sizeof(IdcinContext),
     .init           = idcin_decode_init,
-    .close          = idcin_decode_end,
     .decode         = idcin_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("id Quake II CIN video"),
index 584e7f983fcff0d7d6180cf11d04837bcedba725..08d548b0eaec5f0a6152a8e87946ef14033439a2 100644 (file)
@@ -168,8 +168,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     if (!s->planebuf)
         return AVERROR(ENOMEM);
 
-    s->frame.reference = 1;
-
     return 0;
 }
 
@@ -256,15 +254,11 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
     const uint8_t *buf_end = buf+buf_size;
     int y, plane, res;
 
-    if (s->init) {
-        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return res;
-        }
-    } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+    if ((res = ff_reget_buffer(avctx, &s->frame)) < 0)
         return res;
-    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
+
+    if (!s->init && avctx->bits_per_coded_sample <= 8 &&
+        avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
         if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
             return res;
     }
@@ -298,8 +292,11 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
         }
     }
 
+    if ((res = av_frame_ref(data, &s->frame)) < 0)
+        return res;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+
     return buf_size;
 }
 
@@ -313,15 +310,11 @@ static int decode_frame_byterun1(AVCodecContext *avctx,
     const uint8_t *buf_end = buf+buf_size;
     int y, plane, res;
 
-    if (s->init) {
-        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return res;
-        }
-    } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+    if ((res = ff_reget_buffer(avctx, &s->frame)) < 0)
         return res;
-    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
+
+    if (!s->init && avctx->bits_per_coded_sample <= 8 &&
+        avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
         if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
             return res;
     }
@@ -354,16 +347,18 @@ static int decode_frame_byterun1(AVCodecContext *avctx,
         }
     }
 
+    if ((res = av_frame_ref(data, &s->frame)) < 0)
+        return res;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
+
     return buf_size;
 }
 
 static av_cold int decode_end(AVCodecContext *avctx)
 {
     IffContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
     av_freep(&s->planebuf);
     return 0;
 }
index 9b984c12bb8d9103753463b7519e9f11d750fae2..06bff9bd41d235294eabf9a6ce2de62da155b131 100644 (file)
@@ -940,7 +940,7 @@ static int imc_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = COEFFS;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 1b4d51b6b1fed27fd15957c1735eae6bdbeefe06..37b3ea19cdacfcda657722de60fc38bde23a4301 100644 (file)
@@ -29,6 +29,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "indeo2data.h"
+#include "internal.h"
 #include "mathops.h"
 
 typedef struct Ir2Context{
@@ -148,12 +149,7 @@ static int ir2_decode_frame(AVCodecContext *avctx,
     AVFrame * const p    = &s->picture;
     int start, ret;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 1;
-    p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -206,7 +202,9 @@ static int ir2_decode_frame(AVCodecContext *avctx,
             return ret;
     }
 
-    *picture   = s->picture;
+    if ((ret = av_frame_ref(picture, &s->picture)) < 0)
+        return ret;
+
     *got_frame = 1;
 
     return buf_size;
@@ -241,8 +239,7 @@ static av_cold int ir2_decode_end(AVCodecContext *avctx)
     Ir2Context * const ic = avctx->priv_data;
     AVFrame *pic = &ic->picture;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+    av_frame_unref(pic);
 
     return 0;
 }
index 22f5e7916b565575e6166adf2e2df9c0d191f1c2..e519361aa24dab68c78b1e77ca3d34b139a744d1 100644 (file)
@@ -81,7 +81,6 @@ typedef struct Cell {
 
 typedef struct Indeo3DecodeContext {
     AVCodecContext *avctx;
-    AVFrame         frame;
     DSPContext      dsp;
 
     GetBitContext   gb;
@@ -1034,6 +1033,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     Indeo3DecodeContext *ctx = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
+    AVFrame *frame     = data;
     int res;
 
     res = decode_frame_headers(ctx, avctx, buf, buf_size);
@@ -1070,27 +1070,22 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10)))
         return res;
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
-
-    ctx->frame.reference = 0;
-    if ((res = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
 
     output_plane(&ctx->planes[0], ctx->buf_sel,
-                 ctx->frame.data[0], ctx->frame.linesize[0],
+                 frame->data[0], frame->linesize[0],
                  avctx->height);
     output_plane(&ctx->planes[1], ctx->buf_sel,
-                 ctx->frame.data[1], ctx->frame.linesize[1],
+                 frame->data[1], frame->linesize[1],
                  (avctx->height + 3) >> 2);
     output_plane(&ctx->planes[2], ctx->buf_sel,
-                 ctx->frame.data[2], ctx->frame.linesize[2],
+                 frame->data[2], frame->linesize[2],
                  (avctx->height + 3) >> 2);
 
     *got_frame = 1;
-    *(AVFrame*)data = ctx->frame;
 
     return buf_size;
 }
@@ -1098,13 +1093,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
 static av_cold int decode_close(AVCodecContext *avctx)
 {
-    Indeo3DecodeContext *ctx = avctx->priv_data;
-
     free_frame_buffers(avctx->priv_data);
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
-
     return 0;
 }
 
index 05efbfc15a4b6aca606e2d669eba3d31a382547f..75bd4b9b1b68ebff350169ed0b6f82f962370a31 100644 (file)
 
 #include <stdint.h>
 
+#include "libavutil/buffer.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixfmt.h"
 #include "avcodec.h"
 
 #define FF_SANE_NB_CHANNELS 128U
 
-typedef struct InternalBuffer {
-    uint8_t *base[AV_NUM_DATA_POINTERS];
-    uint8_t *data[AV_NUM_DATA_POINTERS];
-    int linesize[AV_NUM_DATA_POINTERS];
-    int width;
-    int height;
-    enum AVPixelFormat pix_fmt;
-} InternalBuffer;
-
-typedef struct AVCodecInternal {
+typedef struct FramePool {
     /**
-     * internal buffer count
-     * used by default get/release/reget_buffer().
+     * Pools for each data plane. For audio all the planes have the same size,
+     * so only pools[0] is used.
      */
-    int buffer_count;
+    AVBufferPool *pools[4];
 
-    /**
-     * internal buffers
-     * used by default get/release/reget_buffer().
+    /*
+     * Pool parameters
      */
-    InternalBuffer *buffer;
+    int format;
+    int width, height;
+    int stride_align[AV_NUM_DATA_POINTERS];
+    int linesize[4];
+    int planes;
+    int channels;
+    int samples;
+} FramePool;
 
+typedef struct AVCodecInternal {
     /**
      * Whether the parent AVCodecContext is a copy of the context which had
      * init() called on it.
@@ -62,6 +61,21 @@ typedef struct AVCodecInternal {
      */
     int is_copy;
 
+    /**
+     * Whether to allocate progress for frame threading.
+     *
+     * The codec must set it to 1 if it uses ff_thread_await/report_progress(),
+     * then progress will be allocated in ff_thread_get_buffer(). The frames
+     * then MUST be freed with ff_thread_release_buffer().
+     *
+     * If the codec does not need to call the progress functions (there are no
+     * dependencies between the frames), it should leave this at 0. Then it can
+     * decode straight to the user-provided frames (which the user will then
+     * free with av_frame_unref()), there is no need to call
+     * ff_thread_release_buffer().
+     */
+    int allocate_progress;
+
 #if FF_API_OLD_ENCODE_AUDIO
     /**
      * Internal sample count used by avcodec_encode_audio() to fabricate pts.
@@ -76,11 +90,9 @@ typedef struct AVCodecInternal {
      */
     int last_audio_frame;
 
-    /**
-     * The data for the last allocated audio frame.
-     * Stored here so we can free it.
-     */
-    uint8_t *audio_data;
+    AVFrame to_free;
+
+    FramePool *pool;
 } AVCodecInternal;
 
 struct AVCodecDefault {
@@ -149,6 +161,12 @@ static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx,
  * AVCodecContext.get_buffer() and should be used instead calling get_buffer()
  * directly.
  */
-int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame);
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags);
+
+/**
+ * Identical in function to av_frame_make_writable(), except it uses
+ * ff_get_buffer() to allocate the buffer when needed.
+ */
+int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame);
 
 #endif /* AVCODEC_INTERNAL_H */
index 76e7d0fe41e9cfc4049f92f99f6cc9818b3ac098..57035fd11a6bcdf562b7e1f16a8ebe55f974c210 100644 (file)
@@ -51,9 +51,8 @@ typedef struct IpvideoContext {
 
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame second_last_frame;
-    AVFrame last_frame;
-    AVFrame current_frame;
+    AVFrame *second_last_frame;
+    AVFrame *last_frame;
     const unsigned char *decoding_map;
     int decoding_map_size;
 
@@ -67,10 +66,10 @@ typedef struct IpvideoContext {
     uint32_t pal[256];
 } IpvideoContext;
 
-static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y)
+static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
 {
-    int current_offset = s->pixel_ptr - s->current_frame.data[0];
-    int motion_offset = current_offset + delta_y * s->current_frame.linesize[0]
+    int current_offset = s->pixel_ptr - dst->data[0];
+    int motion_offset = current_offset + delta_y * dst->linesize[0]
                        + delta_x * (1 + s->is_16bpp);
     if (motion_offset < 0) {
         av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset < 0 (%d)\n", motion_offset);
@@ -85,21 +84,21 @@ static int copy_from(IpvideoContext *s, AVFrame *src, int delta_x, int delta_y)
         return AVERROR(EINVAL);
     }
     s->dsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
-                                           s->current_frame.linesize[0], 8);
+                                           dst->linesize[0], 8);
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s, AVFrame *frame)
 {
-    return copy_from(s, &s->last_frame, 0, 0);
+    return copy_from(s, s->last_frame, frame, 0, 0);
 }
 
-static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s, AVFrame *frame)
 {
-    return copy_from(s, &s->second_last_frame, 0, 0);
+    return copy_from(s, s->second_last_frame, frame, 0, 0);
 }
 
-static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame)
 {
     unsigned char B;
     int x, y;
@@ -120,10 +119,10 @@ static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s)
     }
 
     av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
-    return copy_from(s, &s->second_last_frame, x, y);
+    return copy_from(s, s->second_last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame)
 {
     unsigned char B;
     int x, y;
@@ -146,10 +145,10 @@ static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s)
     }
 
     av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
-    return copy_from(s, &s->current_frame, x, y);
+    return copy_from(s, frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char B, BL, BH;
@@ -167,10 +166,10 @@ static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s)
     y = -8 + BH;
 
     av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
-    return copy_from(s, &s->last_frame, x, y);
+    return copy_from(s, s->last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame)
 {
     signed char x, y;
 
@@ -180,10 +179,10 @@ static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s)
     y = bytestream2_get_byte(&s->stream_ptr);
 
     av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
-    return copy_from(s, &s->last_frame, x, y);
+    return copy_from(s, s->last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s, AVFrame *frame)
 {
     /* mystery opcode? skip multiple blocks? */
     av_log(s->avctx, AV_LOG_ERROR, "  Interplay video: Help! Mystery opcode 0x6 seen\n");
@@ -192,7 +191,7 @@ static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[2];
@@ -231,7 +230,7 @@ static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[4];
@@ -304,7 +303,7 @@ static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[4];
@@ -369,7 +368,7 @@ static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char P[8];
@@ -430,7 +429,7 @@ static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame)
 {
     int y;
 
@@ -444,7 +443,7 @@ static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
 
@@ -463,7 +462,7 @@ static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame)
 {
     int y;
     unsigned char P[2];
@@ -483,7 +482,7 @@ static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame)
 {
     int y;
     unsigned char pix;
@@ -500,7 +499,7 @@ static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char sample[2];
@@ -521,7 +520,7 @@ static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame)
 {
     signed char x, y;
 
@@ -530,10 +529,10 @@ static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s)
     y = bytestream2_get_byte(&s->stream_ptr);
 
     av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
-    return copy_from(s, &s->second_last_frame, x, y);
+    return copy_from(s, s->second_last_frame, frame, x, y);
 }
 
-static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[2];
@@ -570,7 +569,7 @@ static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[4];
@@ -646,7 +645,7 @@ static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[4];
@@ -713,7 +712,7 @@ static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[8];
@@ -779,7 +778,7 @@ static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
@@ -795,7 +794,7 @@ static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
@@ -815,7 +814,7 @@ static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t P[2];
@@ -836,7 +835,7 @@ static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s)
     return 0;
 }
 
-static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s)
+static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     uint16_t pix;
@@ -855,7 +854,7 @@ static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s)
     return 0;
 }
 
-static int (* const ipvideo_decode_block[])(IpvideoContext *s) = {
+static int (* const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame) = {
     ipvideo_decode_block_opcode_0x0, ipvideo_decode_block_opcode_0x1,
     ipvideo_decode_block_opcode_0x2, ipvideo_decode_block_opcode_0x3,
     ipvideo_decode_block_opcode_0x4, ipvideo_decode_block_opcode_0x5,
@@ -866,7 +865,7 @@ static int (* const ipvideo_decode_block[])(IpvideoContext *s) = {
     ipvideo_decode_block_opcode_0xE, ipvideo_decode_block_opcode_0xF,
 };
 
-static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = {
+static int (* const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame) = {
     ipvideo_decode_block_opcode_0x0,    ipvideo_decode_block_opcode_0x1,
     ipvideo_decode_block_opcode_0x2,    ipvideo_decode_block_opcode_0x3,
     ipvideo_decode_block_opcode_0x4,    ipvideo_decode_block_opcode_0x5,
@@ -877,7 +876,7 @@ static int (* const ipvideo_decode_block16[])(IpvideoContext *s) = {
     ipvideo_decode_block_opcode_0xE_16, ipvideo_decode_block_opcode_0x1,
 };
 
-static void ipvideo_decode_opcodes(IpvideoContext *s)
+static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame)
 {
     int x, y;
     unsigned char opcode;
@@ -887,16 +886,16 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
     if (!s->is_16bpp) {
         /* this is PAL8, so make the palette available */
-        memcpy(s->current_frame.data[1], s->pal, AVPALETTE_SIZE);
+        memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
 
-        s->stride = s->current_frame.linesize[0];
+        s->stride = frame->linesize[0];
     } else {
-        s->stride = s->current_frame.linesize[0] >> 1;
+        s->stride = frame->linesize[0] >> 1;
         s->mv_ptr = s->stream_ptr;
         bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
     }
     s->line_inc = s->stride - 8;
-    s->upper_motion_limit_offset = (s->avctx->height - 8) * s->current_frame.linesize[0]
+    s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
                                   + (s->avctx->width - 8) * (1 + s->is_16bpp);
 
     init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8);
@@ -909,13 +908,13 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
                     x, y, opcode, bytestream2_tell(&s->stream_ptr));
 
             if (!s->is_16bpp) {
-                s->pixel_ptr = s->current_frame.data[0] + x
-                              + y*s->current_frame.linesize[0];
-                ret = ipvideo_decode_block[opcode](s);
+                s->pixel_ptr = frame->data[0] + x
+                              + y*frame->linesize[0];
+                ret = ipvideo_decode_block[opcode](s, frame);
             } else {
-                s->pixel_ptr = s->current_frame.data[0] + x*2
-                              + y*s->current_frame.linesize[0];
-                ret = ipvideo_decode_block16[opcode](s);
+                s->pixel_ptr = frame->data[0] + x*2
+                              + y*frame->linesize[0];
+                ret = ipvideo_decode_block16[opcode](s, frame);
             }
             if (ret != 0) {
                 av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode problem on frame %d, @ block (%d, %d)\n",
@@ -942,8 +941,13 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
 
     ff_dsputil_init(&s->dsp, avctx);
 
-    s->current_frame.data[0] = s->last_frame.data[0] =
-    s->second_last_frame.data[0] = NULL;
+    s->last_frame        = av_frame_alloc();
+    s->second_last_frame = av_frame_alloc();
+    if (!s->last_frame || !s->second_last_frame) {
+        av_frame_free(&s->last_frame);
+        av_frame_free(&s->second_last_frame);
+        return AVERROR(ENOMEM);
+    }
 
     return 0;
 }
@@ -955,6 +959,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     IpvideoContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int ret;
 
     /* decoding map contains 4 bits of information per 8x8 block */
@@ -969,8 +974,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
     bytestream2_init(&s->stream_ptr, buf + s->decoding_map_size,
                      buf_size - s->decoding_map_size);
 
-    s->current_frame.reference = 3;
-    if ((ret = ff_get_buffer(avctx, &s->current_frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "  Interplay Video: get_buffer() failed\n");
         return ret;
     }
@@ -978,22 +982,20 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
     if (!s->is_16bpp) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
         if (pal) {
-            s->current_frame.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
     }
 
-    ipvideo_decode_opcodes(s);
+    ipvideo_decode_opcodes(s, frame);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->current_frame;
 
     /* shuffle frames */
-    if (s->second_last_frame.data[0])
-        avctx->release_buffer(avctx, &s->second_last_frame);
-    s->second_last_frame = s->last_frame;
-    s->last_frame = s->current_frame;
-    s->current_frame.data[0] = NULL;  /* catch any access attempts */
+    av_frame_unref(s->second_last_frame);
+    FFSWAP(AVFrame*, s->second_last_frame, s->last_frame);
+    if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+        return ret;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -1003,11 +1005,8 @@ static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
 {
     IpvideoContext *s = avctx->priv_data;
 
-    /* release the last frame */
-    if (s->last_frame.data[0])
-        avctx->release_buffer(avctx, &s->last_frame);
-    if (s->second_last_frame.data[0])
-        avctx->release_buffer(avctx, &s->second_last_frame);
+    av_frame_free(&s->last_frame);
+    av_frame_free(&s->second_last_frame);
 
     return 0;
 }
index f4a2fc67c3229a4fbb516342bbff069d858f5d42..b81a9ca9c4b76b5c02b9965ed919216ba0769d6d 100644 (file)
@@ -774,7 +774,7 @@ int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_of
                 /*emulate MB info in the relevant tables*/
                 s->mbskip_table [mb_xy]=0;
                 s->mbintra_table[mb_xy]=1;
-                s->current_picture.f.qscale_table[mb_xy] = w->quant;
+                s->current_picture.qscale_table[mb_xy] = w->quant;
                 mb_xy++;
             }
             s->dest[0]+= 8;
index 7f79982c6b4db0fa6bd5fce545ee84a747decd98..9a42c2d767ecfc46978cad1a4ff1b1e44e4767c2 100644 (file)
@@ -352,20 +352,20 @@ static void preview_obmc(MpegEncContext *s){
     do{
         if (get_bits1(&s->gb)) {
             /* skip mb */
-            mot_val = s->current_picture.f.motion_val[0][s->block_index[0]];
+            mot_val = s->current_picture.motion_val[0][s->block_index[0]];
             mot_val[0       ]= mot_val[2       ]=
             mot_val[0+stride]= mot_val[2+stride]= 0;
             mot_val[1       ]= mot_val[3       ]=
             mot_val[1+stride]= mot_val[3+stride]= 0;
 
-            s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
             goto end;
         }
         cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
     }while(cbpc == 20);
 
     if(cbpc & 4){
-        s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+        s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
     }else{
         get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
         if (cbpc & 8) {
@@ -377,7 +377,7 @@ static void preview_obmc(MpegEncContext *s){
         }
 
         if ((cbpc & 16) == 0) {
-                s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+                s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
                 /* 16x16 motion prediction */
                 mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
                 if (s->umvplus)
@@ -395,7 +395,7 @@ static void preview_obmc(MpegEncContext *s){
                 mot_val[1       ]= mot_val[3       ]=
                 mot_val[1+stride]= mot_val[3+stride]= my;
         } else {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
             for(i=0;i<4;i++) {
                 mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                 if (s->umvplus)
@@ -617,7 +617,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
                     s->block_last_index[i] = -1;
                 s->mv_dir = MV_DIR_FORWARD;
                 s->mv_type = MV_TYPE_16X16;
-                s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+                s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
                 s->mv[0][0][0] = 0;
                 s->mv[0][0][1] = 0;
                 s->mb_skipped = !(s->obmc | s->loop_filter);
@@ -650,7 +650,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
 
         s->mv_dir = MV_DIR_FORWARD;
         if ((cbpc & 16) == 0) {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
             /* 16x16 motion prediction */
             s->mv_type = MV_TYPE_16X16;
             ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
@@ -675,7 +675,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
             if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
                skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
         } else {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
             s->mv_type = MV_TYPE_8X8;
             for(i=0;i<4;i++) {
                 mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
@@ -703,8 +703,8 @@ int ff_h263_decode_mb(MpegEncContext *s,
     } else if(s->pict_type==AV_PICTURE_TYPE_B) {
         int mb_type;
         const int stride= s->b8_stride;
-        int16_t *mot_val0 = s->current_picture.f.motion_val[0][2 * (s->mb_x + s->mb_y * stride)];
-        int16_t *mot_val1 = s->current_picture.f.motion_val[1][2 * (s->mb_x + s->mb_y * stride)];
+        int16_t *mot_val0 = s->current_picture.motion_val[0][2 * (s->mb_x + s->mb_y * stride)];
+        int16_t *mot_val1 = s->current_picture.motion_val[1][2 * (s->mb_x + s->mb_y * stride)];
 //        const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
 
         //FIXME ugly
@@ -787,7 +787,7 @@ int ff_h263_decode_mb(MpegEncContext *s,
             }
         }
 
-        s->current_picture.f.mb_type[xy] = mb_type;
+        s->current_picture.mb_type[xy] = mb_type;
     } else { /* I-Frame */
         do{
             cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
@@ -802,11 +802,11 @@ int ff_h263_decode_mb(MpegEncContext *s,
         dquant = cbpc & 4;
         s->mb_intra = 1;
 intra:
-        s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+        s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
         if (s->h263_aic) {
             s->ac_pred = get_bits1(&s->gb);
             if(s->ac_pred){
-                s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
+                s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
 
                 s->h263_aic_dir = get_bits1(&s->gb);
             }
index 05f9631d53702d54cbf411f613fdf8ade33c843b..eb91142bd52fe7f6cdd7c32114107e117682166b 100644 (file)
@@ -274,7 +274,7 @@ void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line)
  */
 void ff_clean_h263_qscales(MpegEncContext *s){
     int i;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t * const qscale_table = s->current_picture.qscale_table;
 
     ff_init_qscale_tab(s);
 
@@ -528,8 +528,8 @@ void ff_h263_encode_mb(MpegEncContext * s,
                 /* motion vectors: 8x8 mode*/
                 ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
 
-                motion_x = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-                motion_y = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+                motion_x = s->current_picture.motion_val[0][s->block_index[i]][0];
+                motion_y = s->current_picture.motion_val[0][s->block_index[i]][1];
                 if (!s->umvplus) {
                     ff_h263_encode_motion_vector(s, motion_x - pred_x,
                                                     motion_y - pred_y, 1);
index 76782e517320ac217f9cf666c8a0ce9ed7af9b67..3d7cd13b7f122da4a90c8f1089d72ff647c26c06 100644 (file)
@@ -811,6 +811,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 {
     IVI45DecContext *ctx = avctx->priv_data;
     const uint8_t   *buf = avpkt->data;
+    AVFrame       *frame = data;
     int             buf_size = avpkt->size;
     int             result, p, b;
 
@@ -861,30 +862,25 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
     }
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
-
-    ctx->frame.reference = 0;
     avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height);
-    if ((result = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((result = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return result;
     }
 
     if (ctx->is_scalable) {
         if (avctx->codec_id == AV_CODEC_ID_INDEO4)
-            ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+            ff_ivi_recompose_haar(&ctx->planes[0], frame->data[0], frame->linesize[0]);
         else
-            ff_ivi_recompose53   (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+            ff_ivi_recompose53   (&ctx->planes[0], frame->data[0], frame->linesize[0]);
     } else {
-        ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]);
+        ivi_output_plane(&ctx->planes[0], frame->data[0], frame->linesize[0]);
     }
 
-    ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]);
-    ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]);
+    ivi_output_plane(&ctx->planes[2], frame->data[1], frame->linesize[1]);
+    ivi_output_plane(&ctx->planes[1], frame->data[2], frame->linesize[2]);
 
     *got_frame = 1;
-    *(AVFrame*)data = ctx->frame;
 
     return buf_size;
 }
@@ -901,9 +897,6 @@ av_cold int ff_ivi_decode_close(AVCodecContext *avctx)
     if (ctx->mb_vlc.cust_tab.table)
         ff_free_vlc(&ctx->mb_vlc.cust_tab);
 
-    if (ctx->frame.data[0])
-        avctx->release_buffer(avctx, &ctx->frame);
-
 #if IVI4_STREAM_ANALYSER
     if (avctx->codec_id == AV_CODEC_ID_INDEO4) {
     if (ctx->is_scalable)
index a3fb3140e2a6637d700bff3831b4e3f312bee2cc..aeb6b15877207f4d0b83049832219000d2c14768 100644 (file)
@@ -195,7 +195,6 @@ typedef struct IVIPicConfig {
 
 typedef struct IVI45DecContext {
     GetBitContext   gb;
-    AVFrame         frame;
     RVMapDesc       rvmap_tabs[9];   ///< local corrected copy of the static rvmap tables
 
     uint32_t        frame_num;
index 8c919d290ea5d3327486f2789a1be84c8f9da86d..6b82c6a45bd419c6d2cf7a924c644b332862003d 100644 (file)
@@ -28,6 +28,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "libavutil/intreadwrite.h"
 
 typedef struct JvContext {
@@ -136,16 +137,16 @@ static int decode_frame(AVCodecContext *avctx,
     int buf_size           = avpkt->size;
     const uint8_t *buf     = avpkt->data;
     const uint8_t *buf_end = buf + buf_size;
-    int video_size, video_type, i, j;
+    int video_size, video_type, i, j, ret;
 
     video_size = AV_RL32(buf);
     video_type = buf[4];
     buf += 5;
 
     if (video_size) {
-        if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+        if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
 
         if (video_type == 0 || video_type == 1) {
@@ -185,8 +186,9 @@ static int decode_frame(AVCodecContext *avctx,
         s->palette_has_changed       = 0;
         memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
+        if ((ret = av_frame_ref(data, &s->frame)) < 0)
+            return ret;
         *got_frame = 1;
-        *(AVFrame*)data = s->frame;
     }
 
     return buf_size;
@@ -196,8 +198,7 @@ static av_cold int decode_close(AVCodecContext *avctx)
 {
     JvContext *s = avctx->priv_data;
 
-    if(s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index 01655a54b80e26ea2bb2b143b081b018b960a6df..74ae6b7ffe1a1f35aec0091c7513b873c06e6c50 100644 (file)
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame prev, cur;
+    AVFrame prev;
 } KgvContext;
 
 static void decode_flush(AVCodecContext *avctx)
 {
     KgvContext * const c = avctx->priv_data;
 
-    if (c->prev.data[0])
-        avctx->release_buffer(avctx, &c->prev);
+    av_frame_unref(&c->prev);
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = buf + avpkt->size;
     KgvContext * const c = avctx->priv_data;
@@ -65,17 +65,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return res;
 
     if (w != avctx->width || h != avctx->height) {
-        if (c->prev.data[0])
-            avctx->release_buffer(avctx, &c->prev);
+        av_frame_unref(&c->prev);
         avcodec_set_dimensions(avctx, w, h);
     }
 
     maxcnt = w * h;
 
-    c->cur.reference = 3;
-    if ((res = ff_get_buffer(avctx, &c->cur)) < 0)
+    if ((res = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
         return res;
-    out  = (uint16_t *) c->cur.data[0];
+    out  = (uint16_t *) frame->data[0];
     if (c->prev.data[0]) {
         prev = (uint16_t *) c->prev.data[0];
     } else {
@@ -156,12 +154,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (outcnt - maxcnt)
         av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt);
 
-    *got_frame = 1;
-    *(AVFrame*)data = c->cur;
+    av_frame_unref(&c->prev);
+    if ((res = av_frame_ref(&c->prev, frame)) < 0)
+        return res;
 
-    if (c->prev.data[0])
-        avctx->release_buffer(avctx, &c->prev);
-    FFSWAP(AVFrame, c->cur, c->prev);
+    *got_frame = 1;
 
     return avpkt->size;
 }
index 3ed01ad0e132ca9bdb940673a0120954b3806c3e..574d053677288c6dc022e394f40809044c084cd6 100644 (file)
@@ -41,7 +41,6 @@
  */
 typedef struct KmvcContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int setpal;
     int palsize;
@@ -247,6 +246,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     KmvcContext *const ctx = avctx->priv_data;
+    AVFrame *frame = data;
     uint8_t *out, *src;
     int i, ret;
     int header;
@@ -254,12 +254,8 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
     bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
-    if (ctx->pic.data[0])
-        avctx->release_buffer(avctx, &ctx->pic);
 
-    ctx->pic.reference = 1;
-    ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -277,15 +273,15 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
     }
 
     if (header & KMVC_KEYFRAME) {
-        ctx->pic.key_frame = 1;
-        ctx->pic.pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
     } else {
-        ctx->pic.key_frame = 0;
-        ctx->pic.pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
     }
 
     if (header & KMVC_PALETTE) {
-        ctx->pic.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
         // palette starts from index 1 and has 127 entries
         for (i = 1; i <= ctx->palsize; i++) {
             ctx->pal[i] = bytestream2_get_be24(&ctx->g);
@@ -293,17 +289,17 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
     }
 
     if (pal) {
-        ctx->pic.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
         memcpy(ctx->pal, pal, AVPALETTE_SIZE);
     }
 
     if (ctx->setpal) {
         ctx->setpal = 0;
-        ctx->pic.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
     }
 
     /* make the palette available on the way out */
-    memcpy(ctx->pic.data[1], ctx->pal, 1024);
+    memcpy(frame->data[1], ctx->pal, 1024);
 
     blocksize = bytestream2_get_byte(&ctx->g);
 
@@ -328,12 +324,12 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    out = ctx->pic.data[0];
+    out = frame->data[0];
     src = ctx->cur;
     for (i = 0; i < avctx->height; i++) {
         memcpy(out, src, avctx->width);
         src += 320;
-        out += ctx->pic.linesize[0];
+        out += frame->linesize[0];
     }
 
     /* flip buffers */
@@ -346,7 +342,6 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
     }
 
     *got_frame = 1;
-    *(AVFrame *) data = ctx->pic;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -415,8 +410,6 @@ static av_cold int decode_end(AVCodecContext * avctx)
 
     av_freep(&c->frm0);
     av_freep(&c->frm1);
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
 
     return 0;
 }
index 33dd8b0c53d52e41ca387230aaa80d92271487a7..9d84d263c95f948fc761252211792ea8cbe3ea6e 100644 (file)
@@ -48,7 +48,6 @@ enum LagarithFrameType {
 
 typedef struct LagarithContext {
     AVCodecContext *avctx;
-    AVFrame picture;
     DSPContext dsp;
     int zeros;                  /**< number of consecutive zero bytes encountered */
     int zeros_rem;              /**< number of zero bytes remaining to output */
@@ -502,19 +501,14 @@ static int lag_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LagarithContext *l = avctx->priv_data;
-    AVFrame *const p = &l->picture;
+    ThreadFrame frame = { .f = data };
+    AVFrame *const p  = data;
     uint8_t frametype = 0;
     uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
     uint32_t offs[4];
     uint8_t *srcs[4], *dst;
     int i, j, planes = 3;
 
-    AVFrame *picture = data;
-
-    if (p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference = 0;
     p->key_frame = 1;
 
     frametype = buf[0];
@@ -526,7 +520,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_SOLID_RGBA:
         avctx->pix_fmt = AV_PIX_FMT_RGB32;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -548,7 +542,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
         if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
             avctx->pix_fmt = AV_PIX_FMT_RGB24;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -608,7 +602,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YUY2:
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -634,7 +628,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YV12:
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-        if (ff_thread_get_buffer(avctx, p) < 0) {
+        if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -663,7 +657,6 @@ static int lag_decode_frame(AVCodecContext *avctx,
         return -1;
     }
 
-    *picture = *p;
     *got_frame = 1;
 
     return buf_size;
@@ -683,8 +676,6 @@ static av_cold int lag_decode_end(AVCodecContext *avctx)
 {
     LagarithContext *l = avctx->priv_data;
 
-    if (l->picture.data[0])
-        ff_thread_release_buffer(avctx, &l->picture);
     av_freep(&l->rgb_planes);
 
     return 0;
index 914d4b27755f8a9717ab5c36ed5167ca1c6f8daf..957143dd7595330bb001b82909d596270bf6b518 100644 (file)
@@ -55,8 +55,6 @@
  * Decoder context
  */
 typedef struct LclDecContext {
-    AVFrame pic;
-
     // Image type
     int imgtype;
     // Compression type
@@ -160,6 +158,7 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i
  */
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LclDecContext * const c = avctx->priv_data;
@@ -176,17 +175,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     unsigned int mthread_inlen, mthread_outlen;
     unsigned int len = buf_size;
 
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 0;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    outptr = c->pic.data[0]; // Output image pointer
+    outptr = frame->data[0]; // Output image pointer
 
     /* Decompress frame */
     switch (avctx->codec_id) {
@@ -374,9 +368,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     }
 
     /* Convert colorspace */
-    y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0];
-    u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1];
-    v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2];
+    y_out = frame->data[0] + (height - 1) * frame->linesize[0];
+    u_out = frame->data[1] + (height - 1) * frame->linesize[1];
+    v_out = frame->data[2] + (height - 1) * frame->linesize[2];
     switch (c->imgtype) {
     case IMGTYPE_YUV111:
         for (row = 0; row < height; row++) {
@@ -385,9 +379,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 u_out[col] = *encoded++ + 128;
                 v_out[col] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_YUV422:
@@ -400,14 +394,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 v_out[ col >> 1     ] = *encoded++ + 128;
                 v_out[(col >> 1) + 1] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_RGB24:
         for (row = height - 1; row >= 0; row--) {
-            pixel_ptr = row * c->pic.linesize[0];
+            pixel_ptr = row * frame->linesize[0];
             memcpy(outptr + pixel_ptr, encoded, 3 * width);
             encoded += 3 * width;
         }
@@ -420,9 +414,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 u_out[col >> 2] = *encoded++ + 128;
                 v_out[col >> 2] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_YUV211:
@@ -433,26 +427,26 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 u_out[col >> 1] = *encoded++ + 128;
                 v_out[col >> 1] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0];
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0];
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     case IMGTYPE_YUV420:
-        u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1];
-        v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2];
+        u_out = frame->data[1] + ((height >> 1) - 1) * frame->linesize[1];
+        v_out = frame->data[2] + ((height >> 1) - 1) * frame->linesize[2];
         for (row = 0; row < height - 1; row += 2) {
             for (col = 0; col < width - 1; col += 2) {
                 memcpy(y_out + col, encoded, 2);
                 encoded += 2;
-                memcpy(y_out + col - c->pic.linesize[0], encoded, 2);
+                memcpy(y_out + col - frame->linesize[0], encoded, 2);
                 encoded += 2;
                 u_out[col >> 1] = *encoded++ + 128;
                 v_out[col >> 1] = *encoded++ + 128;
             }
-            y_out -= c->pic.linesize[0] << 1;
-            u_out -= c->pic.linesize[1];
-            v_out -= c->pic.linesize[2];
+            y_out -= frame->linesize[0] << 1;
+            u_out -= frame->linesize[1];
+            v_out -= frame->linesize[2];
         }
         break;
     default:
@@ -461,7 +455,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -625,8 +618,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
     LclDecContext * const c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
 #if CONFIG_ZLIB_DECODER
     if (avctx->codec_id == AV_CODEC_ID_ZLIB)
         inflateEnd(&c->zstream);
index baa65bea718a8b062cd118b636a236a5a268a102..3159f286da35a1fc90db6c6b67d97f9b93925f6e 100644 (file)
@@ -202,7 +202,7 @@ static int libgsm_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = avctx->frame_size;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index cabac053c2c02bb5b3e6d38a0db938043912fc95..d47227cadadc87ea43ea0998191a6d3bcaa0d535 100644 (file)
@@ -90,7 +90,7 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     frame->nb_samples = s->decoder.blockl;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index d3bd7431f56df20c371cc497c6d1ba99deb5c2c1..23efa6ca0b7e95beea4c72592ee0a52f3669b302 100644 (file)
@@ -103,7 +103,7 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 160;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 8f956f473f467bbeacf992ca05ad2b433bb5751f..19ab1605ecac2514b366e8e19f823512b088016b 100644 (file)
@@ -67,7 +67,6 @@ static const enum AVPixelFormat any_pix_fmts[]  = {RGB_PIXEL_FORMATS,
 typedef struct {
     AVClass *class;
     opj_dparameters_t dec_params;
-    AVFrame image;
     int lowres;
     int lowqual;
 } LibOpenJPEGContext;
@@ -239,16 +238,6 @@ static av_cold int libopenjpeg_decode_init(AVCodecContext *avctx)
     LibOpenJPEGContext *ctx = avctx->priv_data;
 
     opj_set_default_decoder_parameters(&ctx->dec_params);
-    avcodec_get_frame_defaults(&ctx->image);
-    avctx->coded_frame = &ctx->image;
-    return 0;
-}
-
-static av_cold int libopenjpeg_decode_init_thread_copy(AVCodecContext *avctx)
-{
-    LibOpenJPEGContext *ctx = avctx->priv_data;
-
-    avctx->coded_frame = &ctx->image;
     return 0;
 }
 
@@ -259,7 +248,8 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
     uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     LibOpenJPEGContext *ctx = avctx->priv_data;
-    AVFrame *picture = &ctx->image, *output = data;
+    ThreadFrame frame = { .f = data };
+    AVFrame *picture  = data;
     const AVPixFmtDescriptor *desc;
     opj_dinfo_t *dec;
     opj_cio_t *stream;
@@ -347,10 +337,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         if (image->comps[i].prec > avctx->bits_per_raw_sample)
             avctx->bits_per_raw_sample = image->comps[i].prec;
 
-    if (picture->data[0])
-        ff_thread_release_buffer(avctx, picture);
-
-    if (ff_thread_get_buffer(avctx, picture) < 0) {
+    if (ff_thread_get_buffer(avctx, &frame, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "ff_thread_get_buffer() failed\n");
         goto done;
     }
@@ -411,7 +398,6 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         goto done;
     }
 
-    *output    = ctx->image;
     *got_frame = 1;
     ret        = buf_size;
 
@@ -421,15 +407,6 @@ done:
     return ret;
 }
 
-static av_cold int libopenjpeg_decode_close(AVCodecContext *avctx)
-{
-    LibOpenJPEGContext *ctx = avctx->priv_data;
-
-    if (ctx->image.data[0])
-        ff_thread_release_buffer(avctx, &ctx->image);
-    return 0;
-}
-
 #define OFFSET(x) offsetof(LibOpenJPEGContext, x)
 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
 
@@ -452,10 +429,8 @@ AVCodec ff_libopenjpeg_decoder = {
     .id               = AV_CODEC_ID_JPEG2000,
     .priv_data_size   = sizeof(LibOpenJPEGContext),
     .init             = libopenjpeg_decode_init,
-    .close            = libopenjpeg_decode_close,
     .decode           = libopenjpeg_decode_frame,
     .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name        = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
     .priv_class       = &class,
-    .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy),
 };
index 0bf040b33b70572ed7ba4d632d1a619c7358faf5..8c33e91a74be32dec4e56a206185f5d9d4e3ff17 100644 (file)
@@ -116,7 +116,7 @@ static int libopus_decode(AVCodecContext *avc, void *data,
     int ret, nb_samples;
 
     frame->nb_samples = MAX_FRAME_SIZE;
-    ret = ff_get_buffer(avc, frame);
+    ret = ff_get_buffer(avc, frame, 0);
     if (ret < 0) {
         av_log(avc, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
index d0077d8a013dc53b71076709621edf1e79b23cec..7fedc632210732b6f955ab4b4933d88098ca7ceb 100644 (file)
@@ -70,9 +70,6 @@ typedef struct SchroDecoderParams {
 
     /** end of sequence pulled */
     int eos_pulled;
-
-    /** decoded picture */
-    AVFrame dec_frame;
 } SchroDecoderParams;
 
 typedef struct SchroParseUnitContext {
@@ -219,6 +216,7 @@ static int libschroedinger_decode_frame(AVCodecContext *avctx,
     SchroDecoder *decoder = p_schro_params->decoder;
     SchroBuffer *enc_buf;
     SchroFrame* frame;
+    AVFrame *avframe = data;
     int state;
     int go = 1;
     int outer = 1;
@@ -312,35 +310,29 @@ static int libschroedinger_decode_frame(AVCodecContext *avctx,
     framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue);
 
     if (framewithpts && framewithpts->frame) {
-        if (p_schro_params->dec_frame.data[0])
-            avctx->release_buffer(avctx, &p_schro_params->dec_frame);
-        if (ff_get_buffer(avctx, &p_schro_params->dec_frame) < 0) {
+        if (ff_get_buffer(avctx, avframe, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n");
             return AVERROR(ENOMEM);
         }
 
-        memcpy(p_schro_params->dec_frame.data[0],
+        memcpy(avframe->data[0],
                framewithpts->frame->components[0].data,
                framewithpts->frame->components[0].length);
 
-        memcpy(p_schro_params->dec_frame.data[1],
+        memcpy(avframe->data[1],
                framewithpts->frame->components[1].data,
                framewithpts->frame->components[1].length);
 
-        memcpy(p_schro_params->dec_frame.data[2],
+        memcpy(avframe->data[2],
                framewithpts->frame->components[2].data,
                framewithpts->frame->components[2].length);
 
         /* Fill frame with current buffer data from Schroedinger. */
-        p_schro_params->dec_frame.format  = -1; /* Unknown -1 */
-        p_schro_params->dec_frame.width   = framewithpts->frame->width;
-        p_schro_params->dec_frame.height  = framewithpts->frame->height;
-        p_schro_params->dec_frame.pkt_pts = framewithpts->pts;
-        p_schro_params->dec_frame.linesize[0] = framewithpts->frame->components[0].stride;
-        p_schro_params->dec_frame.linesize[1] = framewithpts->frame->components[1].stride;
-        p_schro_params->dec_frame.linesize[2] = framewithpts->frame->components[2].stride;
-
-        *(AVFrame*)data = p_schro_params->dec_frame;
+        avframe->pkt_pts = framewithpts->pts;
+        avframe->linesize[0] = framewithpts->frame->components[0].stride;
+        avframe->linesize[1] = framewithpts->frame->components[1].stride;
+        avframe->linesize[2] = framewithpts->frame->components[2].stride;
+
         *got_frame      = 1;
 
         /* Now free the frame resources. */
@@ -361,9 +353,6 @@ static av_cold int libschroedinger_decode_close(AVCodecContext *avctx)
     schro_decoder_free(p_schro_params->decoder);
     av_freep(&p_schro_params->format);
 
-    if (p_schro_params->dec_frame.data[0])
-        avctx->release_buffer(avctx, &p_schro_params->dec_frame);
-
     /* Free data in the output frame queue. */
     ff_schro_queue_free(&p_schro_params->dec_frame_queue,
                         libschroedinger_decode_frame_free);
index 549ff1dfee8232912058f3b88dafac78f7d24a57..5b656963c15e141b0b128e8051a93fa4dcc311b9 100644 (file)
@@ -116,7 +116,7 @@ static int libspeex_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = s->frame_size;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 54eee31dcff17f3bb6a9c6dfeaa2edf32b3ba85c..237b0f6a53be53b2708cdb68f89f8f1e330461aa 100644 (file)
@@ -30,6 +30,7 @@
 #include "libavutil/common.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct VP8DecoderContext {
     struct vpx_codec_ctx decoder;
@@ -65,6 +66,7 @@ static int vp8_decode(AVCodecContext *avctx,
     AVFrame *picture = data;
     const void *iter = NULL;
     struct vpx_image *img;
+    int ret;
 
     if (vpx_codec_decode(&ctx->decoder, avpkt->data, avpkt->size, NULL, 0) !=
         VPX_CODEC_OK) {
@@ -92,14 +94,10 @@ static int vp8_decode(AVCodecContext *avctx,
                 return AVERROR_INVALIDDATA;
             avcodec_set_dimensions(avctx, img->d_w, img->d_h);
         }
-        picture->data[0]     = img->planes[0];
-        picture->data[1]     = img->planes[1];
-        picture->data[2]     = img->planes[2];
-        picture->data[3]     = NULL;
-        picture->linesize[0] = img->stride[0];
-        picture->linesize[1] = img->stride[1];
-        picture->linesize[2] = img->stride[2];
-        picture->linesize[3] = 0;
+        if ((ret = ff_get_buffer(avctx, picture, 0)) < 0)
+            return ret;
+        av_image_copy(picture->data, picture->linesize, img->planes,
+                      img->stride, avctx->pix_fmt, img->d_w, img->d_h);
         *got_frame           = 1;
     }
     return avpkt->size;
@@ -126,7 +124,7 @@ AVCodec ff_libvpx_vp8_decoder = {
     .init           = vp8_init,
     .close          = vp8_free,
     .decode         = vp8_decode,
-    .capabilities   = CODEC_CAP_AUTO_THREADS,
+    .capabilities   = CODEC_CAP_AUTO_THREADS | CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("libvpx VP8"),
 };
 #endif /* CONFIG_LIBVPX_VP8_DECODER */
index 555bffa4ee12f7b79e0a1301290deb591ab454f1..c7291ada67b80a22eed5d3a8fc32505a7ed14e1d 100644 (file)
@@ -63,7 +63,10 @@ static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt,
 
     init_put_bits(&s->pb, pkt->data, pkt->size);
 
-    *p = *pict;
+    av_frame_unref(p);
+    ret = av_frame_ref(p, pict);
+    if (ret < 0)
+        return ret;
     p->pict_type= AV_PICTURE_TYPE_I;
     p->key_frame= 1;
 
index b1ad41ae46fc3dff8fea4b159ea2f66164fb3851..427a56f0fab7dd98014f240478ed4f46125b1531 100644 (file)
@@ -45,7 +45,6 @@ enum LOCO_MODE {
 
 typedef struct LOCOContext {
     AVCodecContext *avctx;
-    AVFrame pic;
     int lossy;
     int mode;
 } LOCOContext;
@@ -173,14 +172,10 @@ static int decode_frame(AVCodecContext *avctx,
     LOCOContext * const l = avctx->priv_data;
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
-    AVFrame * const p     = &l->pic;
+    AVFrame * const p     = data;
     int decoded, ret;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -260,7 +255,6 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
 
     return buf_size;
 buf_too_small:
@@ -321,24 +315,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    LOCOContext * const l = avctx->priv_data;
-    AVFrame *pic = &l->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    return 0;
-}
-
 AVCodec ff_loco_decoder = {
     .name           = "loco",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_LOCO,
     .priv_data_size = sizeof(LOCOContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("LOCO"),
index 368e5d7986cc96c2dd20dc314d735c13b60d8b72..559dcee5673fabfdb3c56d0a135268a0760fa0f2 100644 (file)
@@ -246,7 +246,7 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index f85c3bac89dbe699c8c6dfaec9837c14728f358a..3a1a7074d4b04d8f2f495443d855c47026821b84 100644 (file)
@@ -35,7 +35,7 @@
 typedef struct MDECContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame picture;
+    ThreadFrame frame;
     GetBitContext gb;
     ScanTable scantable;
     int version;
@@ -135,14 +135,14 @@ static inline int decode_mb(MDECContext *a, int16_t block[6][64])
     return 0;
 }
 
-static inline void idct_put(MDECContext *a, int mb_x, int mb_y)
+static inline void idct_put(MDECContext *a, AVFrame *frame, int mb_x, int mb_y)
 {
     int16_t (*block)[64] = a->block;
-    int linesize = a->picture.linesize[0];
+    int linesize = frame->linesize[0];
 
-    uint8_t *dest_y  = a->picture.data[0] + (mb_y * 16 * linesize              ) + mb_x * 16;
-    uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8  * a->picture.linesize[1]) + mb_x * 8;
-    uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8  * a->picture.linesize[2]) + mb_x * 8;
+    uint8_t *dest_y  = frame->data[0] + (mb_y * 16* linesize              ) + mb_x * 16;
+    uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+    uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
 
     a->dsp.idct_put(dest_y,                    linesize, block[0]);
     a->dsp.idct_put(dest_y                + 8, linesize, block[1]);
@@ -150,8 +150,8 @@ static inline void idct_put(MDECContext *a, int mb_x, int mb_y)
     a->dsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]);
 
     if (!(a->avctx->flags & CODEC_FLAG_GRAY)) {
-        a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
-        a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
+        a->dsp.idct_put(dest_cb, frame->linesize[1], block[4]);
+        a->dsp.idct_put(dest_cr, frame->linesize[2], block[5]);
     }
 }
 
@@ -162,20 +162,15 @@ static int decode_frame(AVCodecContext *avctx,
     MDECContext * const a = avctx->priv_data;
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
-    AVFrame *picture      = data;
-    AVFrame * const p     = &a->picture;
+    ThreadFrame frame     = { .f = data };
     int i, ret;
 
-    if (p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
+    frame.f->pict_type = AV_PICTURE_TYPE_I;
+    frame.f->key_frame = 1;
 
     av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!a->bitstream_buffer)
@@ -199,14 +194,10 @@ static int decode_frame(AVCodecContext *avctx,
             if ((ret = decode_mb(a, a->block)) < 0)
                 return ret;
 
-            idct_put(a, a->mb_x, a->mb_y);
+            idct_put(a, frame.f, a->mb_x, a->mb_y);
         }
     }
 
-    p->quality = a->qscale * FF_QP2LAMBDA;
-    memset(p->qscale_table, a->qscale, a->mb_width);
-
-    *picture   = a->picture;
     *got_frame = 1;
 
     return (get_bits_count(&a->gb) + 31) / 32 * 4;
@@ -215,12 +206,10 @@ static int decode_frame(AVCodecContext *avctx,
 static av_cold int decode_init(AVCodecContext *avctx)
 {
     MDECContext * const a = avctx->priv_data;
-    AVFrame *p            = &a->picture;
 
     a->mb_width  = (avctx->coded_width  + 15) / 16;
     a->mb_height = (avctx->coded_height + 15) / 16;
 
-    avctx->coded_frame = &a->picture;
     a->avctx           = avctx;
 
     ff_dsputil_init(&a->dsp, avctx);
@@ -229,8 +218,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     if (avctx->idct_algo == FF_IDCT_AUTO)
         avctx->idct_algo = FF_IDCT_SIMPLE;
-    p->qstride      = 0;
-    p->qscale_table = av_mallocz(a->mb_width);
     avctx->pix_fmt  = AV_PIX_FMT_YUVJ420P;
 
     return 0;
@@ -239,13 +226,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
 static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
 {
     MDECContext * const a = avctx->priv_data;
-    AVFrame *p            = &a->picture;
 
-    avctx->coded_frame = p;
     a->avctx           = avctx;
 
-    p->qscale_table = av_mallocz( a->mb_width);
-
     return 0;
 }
 
@@ -253,10 +236,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     MDECContext * const a = avctx->priv_data;
 
-    if (a->picture.data[0])
-        avctx->release_buffer(avctx, &a->picture);
     av_freep(&a->bitstream_buffer);
-    av_freep(&a->picture.qscale_table);
     a->bitstream_buffer_size = 0;
 
     return 0;
index 8ab1c9e985c506a53c9bbc7ee99f77dd415e6ea4..ecd837088d61209d585f28e306b6375efc34aa24 100644 (file)
@@ -44,7 +44,7 @@ typedef struct {
     int             cur_index;
     int             prev_index;
 
-    AVFrame         buf_ptrs    [16];
+    ThreadFrame     frames     [16];
     AVPicture       flipped_ptrs[16];
 
     DECLARE_ALIGNED(16, int16_t, dct_block)[64];
@@ -109,10 +109,31 @@ static const uint8_t col_zag[64] = {
     53, 60, 61, 54, 47, 55, 62, 63,
 };
 
+static av_cold int mimic_decode_end(AVCodecContext *avctx)
+{
+    MimicContext *ctx = avctx->priv_data;
+    int i;
+
+    av_free(ctx->swap_buf);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
+        if (ctx->frames[i].f)
+            ff_thread_release_buffer(avctx, &ctx->frames[i]);
+        av_frame_free(&ctx->frames[i].f);
+    }
+
+    if (!avctx->internal->is_copy)
+        ff_free_vlc(&ctx->vlc);
+
+    return 0;
+}
+
 static av_cold int mimic_decode_init(AVCodecContext *avctx)
 {
     MimicContext *ctx = avctx->priv_data;
-    int ret;
+    int ret, i;
+
+    avctx->internal->allocate_progress = 1;
 
     ctx->prev_index = 0;
     ctx->cur_index  = 15;
@@ -125,12 +146,21 @@ static av_cold int mimic_decode_init(AVCodecContext *avctx)
     ff_dsputil_init(&ctx->dsp, avctx);
     ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, col_zag);
 
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
+        ctx->frames[i].f = av_frame_alloc();
+        if (!ctx->frames[i].f) {
+            mimic_decode_end(avctx);
+            return AVERROR(ENOMEM);
+        }
+    }
+
     return 0;
 }
 
 static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
 {
     MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
+    int i, ret;
 
     if (avctx == avctx_from)
         return 0;
@@ -138,10 +168,16 @@ static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCod
     dst->cur_index  = src->next_cur_index;
     dst->prev_index = src->next_prev_index;
 
-    memcpy(dst->buf_ptrs, src->buf_ptrs, sizeof(src->buf_ptrs));
     memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
 
-    memset(&dst->buf_ptrs[dst->cur_index], 0, sizeof(AVFrame));
+    for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
+        ff_thread_release_buffer(avctx, &dst->frames[i]);
+        if (src->frames[i].f->data[0]) {
+            ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
+            if (ret < 0)
+                return ret;
+        }
+    }
 
     return 0;
 }
@@ -264,7 +300,7 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs,
                         uint8_t *p           = ctx->flipped_ptrs[index].data[0];
 
                         if (index != ctx->cur_index && p) {
-                            ff_thread_await_progress(&ctx->buf_ptrs[index],
+                            ff_thread_await_progress(&ctx->frames[index],
                                                      cur_row, 0);
                             p += src -
                                  ctx->flipped_ptrs[ctx->prev_index].data[plane];
@@ -275,7 +311,7 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs,
                         }
                     }
                 } else {
-                    ff_thread_await_progress(&ctx->buf_ptrs[ctx->prev_index],
+                    ff_thread_await_progress(&ctx->frames[ctx->prev_index],
                                              cur_row, 0);
                     ctx->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
                 }
@@ -285,7 +321,7 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs,
             src += (stride - ctx->num_hblocks[plane]) << 3;
             dst += (stride - ctx->num_hblocks[plane]) << 3;
 
-            ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index],
+            ff_thread_report_progress(&ctx->frames[ctx->cur_index],
                                       cur_row++, 0);
         }
     }
@@ -357,15 +393,16 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_PATCHWELCOME;
     }
 
-    if (is_pframe && !ctx->buf_ptrs[ctx->prev_index].data[0]) {
+    if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
         av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
         return AVERROR_INVALIDDATA;
     }
 
-    ctx->buf_ptrs[ctx->cur_index].reference = 1;
-    ctx->buf_ptrs[ctx->cur_index].pict_type = is_pframe ? AV_PICTURE_TYPE_P :
-                                                          AV_PICTURE_TYPE_I;
-    if ((res = ff_thread_get_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index])) < 0) {
+    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+    ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
+                                                           AV_PICTURE_TYPE_I;
+    if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
+                                    AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
@@ -374,7 +411,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
     ctx->next_cur_index  = (ctx->cur_index - 1) & 15;
 
     prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
-                  &ctx->buf_ptrs[ctx->cur_index]);
+                  ctx->frames[ctx->cur_index].f);
 
     ff_thread_finish_setup(avctx);
 
@@ -388,41 +425,39 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data,
     init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
 
     res = decode(ctx, quality, num_coeffs, !is_pframe);
-    ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0);
+    ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
     if (res < 0) {
         if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
-            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
+            ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
             return res;
         }
     }
 
-    *(AVFrame*)data = ctx->buf_ptrs[ctx->cur_index];
+    if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
+        return res;
     *got_frame      = 1;
 
     ctx->prev_index = ctx->next_prev_index;
     ctx->cur_index  = ctx->next_cur_index;
 
     /* Only release frames that aren't used for backreferences anymore */
-    if (ctx->buf_ptrs[ctx->cur_index].data[0])
-        ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]);
+    ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
 
     return buf_size;
 }
 
-static av_cold int mimic_decode_end(AVCodecContext *avctx)
+static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
 {
     MimicContext *ctx = avctx->priv_data;
     int i;
 
-    av_free(ctx->swap_buf);
-
-    if (avctx->internal->is_copy)
-        return 0;
-
-    for (i = 0; i < 16; i++)
-        if (ctx->buf_ptrs[i].data[0])
-            ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]);
-    ff_free_vlc(&ctx->vlc);
+    for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
+        ctx->frames[i].f = av_frame_alloc();
+        if (!ctx->frames[i].f) {
+            mimic_decode_end(avctx);
+            return AVERROR(ENOMEM);
+        }
+    }
 
     return 0;
 }
@@ -437,5 +472,6 @@ AVCodec ff_mimic_decoder = {
     .decode                = mimic_decode_frame,
     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name             = NULL_IF_CONFIG_SMALL("Mimic"),
-    .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context)
+    .update_thread_context = ONLY_IF_THREADS_ENABLED(mimic_decode_update_thread_context),
+    .init_thread_copy      = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
 };
index 9d5a8f31ef0d40ffa8a16744b1372e764802dede..5edc0e4e2432609f323f438b13fe3015290e5f49 100644 (file)
@@ -45,10 +45,10 @@ static int mjpegb_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     MJpegDecodeContext *s = avctx->priv_data;
     const uint8_t *buf_end, *buf_ptr;
-    AVFrame *picture = data;
     GetBitContext hgb; /* for the header */
     uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;
     uint32_t field_size, sod_offs;
+    int ret;
 
     buf_ptr = buf;
     buf_end = buf + buf_size;
@@ -136,17 +136,13 @@ read_header:
 
     //XXX FIXME factorize, this looks very similar to the EOI code
 
-    *picture= *s->picture_ptr;
+    if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
+        return ret;
     *got_frame = 1;
 
-    if(!s->lossless){
-        picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);
-        picture->qstride= 0;
-        picture->qscale_table= s->qscale_table;
-        memset(picture->qscale_table, picture->quality, (s->width+15)/16);
-        if(avctx->debug & FF_DEBUG_QP)
-            av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);
-        picture->quality*= FF_QP2LAMBDA;
+    if (!s->lossless && avctx->debug & FF_DEBUG_QP) {
+        av_log(avctx, AV_LOG_DEBUG, "QP: %d\n",
+               FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]));
     }
 
     return buf_size;
index 470529fcee73333d45f66b67a62572da1f987c3a..17930080f503ff123bb821ba9af18eb923826e46 100644 (file)
@@ -280,8 +280,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
     /* if different size, realloc/alloc picture */
     /* XXX: also check h_count and v_count */
     if (width != s->width || height != s->height) {
-        av_freep(&s->qscale_table);
-
         s->width      = width;
         s->height     = height;
         s->interlaced = 0;
@@ -299,7 +297,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
 
         avcodec_set_dimensions(s->avctx, width, height);
 
-        s->qscale_table  = av_mallocz((s->width + 15) / 16);
         s->first_picture = 0;
     }
 
@@ -350,10 +347,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
             s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
     }
 
-    if (s->picture_ptr->data[0])
-        s->avctx->release_buffer(s->avctx, s->picture_ptr);
-
-    if (ff_get_buffer(s->avctx, s->picture_ptr) < 0) {
+    av_frame_unref(s->picture_ptr);
+    if (ff_get_buffer(s->avctx, s->picture_ptr, AV_GET_BUFFER_FLAG_REF) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -1452,7 +1447,6 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int unescaped_buf_size;
     int start_code;
     int ret = 0;
-    AVFrame *picture = data;
 
     s->got_picture = 0; // picture from previous image can not be reused
     buf_ptr = buf;
@@ -1555,21 +1549,16 @@ eoi_parser:
                     if (s->bottom_field == !s->interlace_polarity)
                         goto not_the_end;
                 }
-                *picture   = *s->picture_ptr;
+                if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
+                    return ret;
                 *got_frame = 1;
 
-                if (!s->lossless) {
-                    picture->quality      = FFMAX3(s->qscale[0],
-                                                   s->qscale[1],
-                                                   s->qscale[2]);
-                    picture->qstride      = 0;
-                    picture->qscale_table = s->qscale_table;
-                    memset(picture->qscale_table, picture->quality,
-                           (s->width + 15) / 16);
-                    if (avctx->debug & FF_DEBUG_QP)
-                        av_log(avctx, AV_LOG_DEBUG,
-                               "QP: %d\n", picture->quality);
-                    picture->quality *= FF_QP2LAMBDA;
+                if (!s->lossless &&
+                    avctx->debug & FF_DEBUG_QP) {
+                    av_log(avctx, AV_LOG_DEBUG,
+                           "QP: %d\n", FFMAX3(s->qscale[0],
+                                              s->qscale[1],
+                                              s->qscale[2]));
                 }
 
                 goto the_end;
@@ -1631,11 +1620,10 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
     MJpegDecodeContext *s = avctx->priv_data;
     int i, j;
 
-    if (s->picture_ptr && s->picture_ptr->data[0])
-        avctx->release_buffer(avctx, s->picture_ptr);
+    if (s->picture_ptr)
+        av_frame_unref(s->picture_ptr);
 
     av_free(s->buffer);
-    av_free(s->qscale_table);
     av_freep(&s->ljpeg_buffer);
     s->ljpeg_buffer_size = 0;
 
index 130ce26d6c4cf928896e9cfb60e729e43628e999..160f35987e3e61d21b0769f0e6edb31fead15087 100644 (file)
@@ -991,7 +991,7 @@ static int output_data(MLPDecodeContext *m, unsigned int substr,
 
     /* get output buffer */
     frame->nb_samples = s->blockpos;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 784b939734c6aecb13b0175ce951646b2cb2dc4a..7101f8033fa53c6dfcf58aa1e998838e03dc6d2e 100644 (file)
@@ -34,6 +34,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define MM_PREAMBLE_SIZE    6
 
@@ -60,8 +61,6 @@ static av_cold int mm_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    s->frame.reference = 1;
-
     return 0;
 }
 
@@ -187,9 +186,9 @@ static int mm_decode_frame(AVCodecContext *avctx,
     buf_size -= MM_PREAMBLE_SIZE;
     bytestream2_init(&s->gb, buf, buf_size);
 
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((res = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return res;
     }
 
     switch(type) {
@@ -209,8 +208,10 @@ static int mm_decode_frame(AVCodecContext *avctx,
 
     memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
 
+    if ((res = av_frame_ref(data, &s->frame)) < 0)
+        return res;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     return buf_size;
 }
@@ -219,8 +220,7 @@ static av_cold int mm_decode_end(AVCodecContext *avctx)
 {
     MmContext *s = avctx->priv_data;
 
-    if(s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index d70021c4d3cf09af1ee764bd1cf6f127f3b410f1..99c55645446b0fab2e9aa5ac4071f429c66d9396 100644 (file)
@@ -494,16 +494,16 @@ static inline void set_p_mv_tables(MpegEncContext * s, int mx, int my, int mv4)
     if(mv4){
         int mot_xy= s->block_index[0];
 
-        s->current_picture.f.motion_val[0][mot_xy    ][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy    ][1] = my;
-        s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy + 1][1] = my;
+        s->current_picture.motion_val[0][mot_xy    ][0] = mx;
+        s->current_picture.motion_val[0][mot_xy    ][1] = my;
+        s->current_picture.motion_val[0][mot_xy + 1][0] = mx;
+        s->current_picture.motion_val[0][mot_xy + 1][1] = my;
 
         mot_xy += s->b8_stride;
-        s->current_picture.f.motion_val[0][mot_xy    ][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy    ][1] = my;
-        s->current_picture.f.motion_val[0][mot_xy + 1][0] = mx;
-        s->current_picture.f.motion_val[0][mot_xy + 1][1] = my;
+        s->current_picture.motion_val[0][mot_xy    ][0] = mx;
+        s->current_picture.motion_val[0][mot_xy    ][1] = my;
+        s->current_picture.motion_val[0][mot_xy + 1][0] = mx;
+        s->current_picture.motion_val[0][mot_xy + 1][1] = my;
     }
 }
 
@@ -576,8 +576,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
         const int mot_stride = s->b8_stride;
         const int mot_xy = s->block_index[block];
 
-        P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0];
-        P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1];
+        P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
+        P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
 
         if(P_LEFT[0]       > (c->xmax<<shift)) P_LEFT[0]       = (c->xmax<<shift);
 
@@ -586,10 +586,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
             c->pred_x= pred_x4= P_LEFT[0];
             c->pred_y= pred_y4= P_LEFT[1];
         } else {
-            P_TOP[0]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride             ][0];
-            P_TOP[1]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride             ][1];
-            P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][0];
-            P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + off[block]][1];
+            P_TOP[0]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][0];
+            P_TOP[1]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][1];
+            P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];
+            P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];
             if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);
             if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
             if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);
@@ -641,8 +641,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
             my4_sum+= my4;
         }
 
-        s->current_picture.f.motion_val[0][s->block_index[block]][0] = mx4;
-        s->current_picture.f.motion_val[0][s->block_index[block]][1] = my4;
+        s->current_picture.motion_val[0][s->block_index[block]][0] = mx4;
+        s->current_picture.motion_val[0][s->block_index[block]][1] = my4;
 
         if(mx4 != mx || my4 != my) same=0;
     }
@@ -894,16 +894,16 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
             const int mot_stride = s->b8_stride;
             const int mot_xy = s->block_index[0];
 
-            P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0];
-            P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1];
+            P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];
+            P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];
 
             if(P_LEFT[0]       > (c->xmax<<shift)) P_LEFT[0]       = (c->xmax<<shift);
 
             if(!s->first_slice_line) {
-                P_TOP[0]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride    ][0];
-                P_TOP[1]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride    ][1];
-                P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][0];
-                P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][1];
+                P_TOP[0]      = s->current_picture.motion_val[0][mot_xy - mot_stride    ][0];
+                P_TOP[1]      = s->current_picture.motion_val[0][mot_xy - mot_stride    ][1];
+                P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][0];
+                P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + 2][1];
                 if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);
                 if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
                 if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
@@ -1035,9 +1035,9 @@ void ff_estimate_p_frame_motion(MpegEncContext * s,
 
         if(intra_score < dmin){
             mb_type= CANDIDATE_MB_TYPE_INTRA;
-            s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
+            s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup
         }else
-            s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = 0;
+            s->current_picture.mb_type[mb_y*s->mb_stride + mb_x] = 0;
 
         {
             int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);
@@ -1403,7 +1403,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
     ymin= xmin=(-32)>>shift;
     ymax= xmax=   31>>shift;
 
-    if (IS_8X8(s->next_picture.f.mb_type[mot_xy])) {
+    if (IS_8X8(s->next_picture.mb_type[mot_xy])) {
         s->mv_type= MV_TYPE_8X8;
     }else{
         s->mv_type= MV_TYPE_16X16;
@@ -1413,8 +1413,8 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y)
         int index= s->block_index[i];
         int min, max;
 
-        c->co_located_mv[i][0] = s->next_picture.f.motion_val[0][index][0];
-        c->co_located_mv[i][1] = s->next_picture.f.motion_val[0][index][1];
+        c->co_located_mv[i][0] = s->next_picture.motion_val[0][index][0];
+        c->co_located_mv[i][1] = s->next_picture.motion_val[0][index][1];
         c->direct_basis_mv[i][0]= c->co_located_mv[i][0]*time_pb/time_pp + ((i& 1)<<(shift+3));
         c->direct_basis_mv[i][1]= c->co_located_mv[i][1]*time_pb/time_pp + ((i>>1)<<(shift+3));
 //        c->direct_basis_mv[1][i][0]= c->co_located_mv[i][0]*(time_pb - time_pp)/time_pp + ((i &1)<<(shift+3);
@@ -1503,7 +1503,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
 
     c->skip=0;
 
-    if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.f.mbskip_table[xy]) {
+    if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]) {
         int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0
 
         score= ((unsigned)(score*score + 128*256))>>16;
@@ -1674,14 +1674,14 @@ void ff_fix_long_p_mvs(MpegEncContext * s)
                     int block;
                     for(block=0; block<4; block++){
                         int off= (block& 1) + (block>>1)*wrap;
-                        int mx = s->current_picture.f.motion_val[0][ xy + off ][0];
-                        int my = s->current_picture.f.motion_val[0][ xy + off ][1];
+                        int mx = s->current_picture.motion_val[0][ xy + off ][0];
+                        int my = s->current_picture.motion_val[0][ xy + off ][1];
 
                         if(   mx >=range || mx <-range
                            || my >=range || my <-range){
                             s->mb_type[i] &= ~CANDIDATE_MB_TYPE_INTER4V;
                             s->mb_type[i] |= CANDIDATE_MB_TYPE_INTRA;
-                            s->current_picture.f.mb_type[i] = CANDIDATE_MB_TYPE_INTRA;
+                            s->current_picture.mb_type[i] = CANDIDATE_MB_TYPE_INTRA;
                         }
                     }
                 }
index c2bd0f4d2bf5ff6e285cc312f7568f07dfffbdfd..c205735c90cf082bcfcdcf19d39f9d47292319d2 100644 (file)
@@ -22,6 +22,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
 
 #define MAX_HUFF_CODES 16
 
@@ -244,13 +245,11 @@ static int mp_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     MotionPixelsContext *mp = avctx->priv_data;
     GetBitContext gb;
-    int i, count1, count2, sz;
+    int i, count1, count2, sz, ret;
 
-    mp->frame.reference = 1;
-    mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &mp->frame)) {
+    if ((ret = ff_reget_buffer(avctx, &mp->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* le32 bitstream msb first */
@@ -295,8 +294,9 @@ static int mp_decode_frame(AVCodecContext *avctx,
     ff_free_vlc(&mp->vlc);
 
 end:
+    if ((ret = av_frame_ref(data, &mp->frame)) < 0)
+        return ret;
     *got_frame       = 1;
-    *(AVFrame *)data = mp->frame;
     return buf_size;
 }
 
@@ -308,8 +308,7 @@ static av_cold int mp_decode_end(AVCodecContext *avctx)
     av_freep(&mp->vpt);
     av_freep(&mp->hpt);
     av_freep(&mp->bswapbuf);
-    if (mp->frame.data[0])
-        avctx->release_buffer(avctx, &mp->frame);
+    av_frame_unref(&mp->frame);
 
     return 0;
 }
index f151f9c304bc243b938e951187773d29b25b51b5..4ebb2541075184d9b83956ae61939887cdeb221b 100644 (file)
@@ -229,7 +229,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = last_frame ? c->lastframelen : MPC_FRAME_SIZE;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 1b32c4b3fa9e8545424174cfad8f7ed3d9470212..7f920d8b542e678e0ed22e933968c524986e6125 100644 (file)
@@ -249,7 +249,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = MPC_FRAME_SIZE;
-    if ((res = ff_get_buffer(avctx, frame)) < 0) {
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
index ce136e7c30693905dd3cc91f3aafc21a5e413ab4..c32055d60932cd18bc4ea6f8e2b4d31d8fa285ea 100644 (file)
@@ -746,19 +746,19 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
     if (s->mb_skip_run-- != 0) {
         if (s->pict_type == AV_PICTURE_TYPE_P) {
             s->mb_skipped = 1;
-            s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+            s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
         } else {
             int mb_type;
 
             if (s->mb_x)
-                mb_type = s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
+                mb_type = s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
             else
-                mb_type = s->current_picture.f.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
+                mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1]; // FIXME not sure if this is allowed in MPEG at all
             if (IS_INTRA(mb_type))
                 return -1;
-            s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
+            s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
                 mb_type | MB_TYPE_SKIP;
-//            assert(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
+//            assert(s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
 
             if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
                 s->mb_skipped = 1;
@@ -1101,7 +1101,7 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
         }
     }
 
-    s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
+    s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
 
     return 0;
 }
@@ -1576,6 +1576,8 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
 
     /* start frame decoding */
     if (s->first_field || s->picture_structure == PICT_FRAME) {
+        AVFrameSideData *pan_scan;
+
         if (ff_MPV_frame_start(s, avctx) < 0)
             return -1;
 
@@ -1594,7 +1596,12 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
             }
         }
 
-        *s->current_picture_ptr->f.pan_scan = s1->pan_scan;
+        pan_scan = av_frame_new_side_data(&s->current_picture_ptr->f,
+                                          AV_FRAME_DATA_PANSCAN,
+                                          sizeof(s1->pan_scan));
+        if (!pan_scan)
+            return AVERROR(ENOMEM);
+        memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
 
         if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
             ff_thread_finish_setup(avctx);
@@ -1736,7 +1743,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
         if (mpeg_decode_mb(s, s->block) < 0)
             return -1;
 
-        if (s->current_picture.f.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs
+        if (s->current_picture.motion_val[0] && !s->encoding) { // note motion_val is normally NULL unless we want to extract the MVs
             const int wrap = s->b8_stride;
             int xy         = s->mb_x * 2 + s->mb_y * 2 * wrap;
             int b8_xy      = 4 * (s->mb_x + s->mb_y * s->mb_stride);
@@ -1754,12 +1761,12 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
                         motion_y = s->mv[dir][i][1];
                     }
 
-                    s->current_picture.f.motion_val[dir][xy    ][0] = motion_x;
-                    s->current_picture.f.motion_val[dir][xy    ][1] = motion_y;
-                    s->current_picture.f.motion_val[dir][xy + 1][0] = motion_x;
-                    s->current_picture.f.motion_val[dir][xy + 1][1] = motion_y;
-                    s->current_picture.f.ref_index [dir][b8_xy    ] =
-                    s->current_picture.f.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];
+                    s->current_picture.motion_val[dir][xy    ][0] = motion_x;
+                    s->current_picture.motion_val[dir][xy    ][1] = motion_y;
+                    s->current_picture.motion_val[dir][xy + 1][0] = motion_x;
+                    s->current_picture.motion_val[dir][xy + 1][1] = motion_y;
+                    s->current_picture.ref_index [dir][b8_xy    ] =
+                    s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];
                     assert(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1);
                 }
                 xy += wrap;
@@ -1927,23 +1934,25 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
     if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) {
         /* end of image */
 
-        s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2;
-
         ff_er_frame_end(&s->er);
 
         ff_MPV_frame_end(s);
 
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            *pict = s->current_picture_ptr->f;
-            ff_print_debug_info(s, pict);
+            int ret = av_frame_ref(pict, &s->current_picture_ptr->f);
+            if (ret < 0)
+                return ret;
+            ff_print_debug_info(s, s->current_picture_ptr);
         } else {
             if (avctx->active_thread_type & FF_THREAD_FRAME)
                 s->picture_number++;
             /* latency of 1 frame for I- and P-frames */
             /* XXX: use another variable than picture_number */
             if (s->last_picture_ptr != NULL) {
-                *pict = s->last_picture_ptr->f;
-                 ff_print_debug_info(s, pict);
+                int ret = av_frame_ref(pict, &s->last_picture_ptr->f);
+                if (ret < 0)
+                    return ret;
+                ff_print_debug_info(s, s->last_picture_ptr);
             }
         }
 
@@ -2230,7 +2239,10 @@ static int decode_chunks(AVCodecContext *avctx,
                 if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
                     ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
 
-                if (slice_end(avctx, picture)) {
+                ret = slice_end(avctx, picture);
+                if (ret < 0)
+                    return ret;
+                else if (ret) {
                     if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
                         *got_output = 1;
                 }
@@ -2450,7 +2462,10 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
     if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {
         /* special case for last picture */
         if (s2->low_delay == 0 && s2->next_picture_ptr) {
-            *picture = s2->next_picture_ptr->f;
+            int ret = av_frame_ref(picture, &s2->next_picture_ptr->f);
+            if (ret < 0)
+                return ret;
+
             s2->next_picture_ptr = NULL;
 
             *got_output = 1;
index d7c928df03185d507f4e0afb204ef2e185dfbdbb..628ca679a7c7b3a51248eda399dd20ca0c7fbedf 100644 (file)
@@ -89,7 +89,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my,
     uint16_t time_pb= s->pb_time;
     int p_mx, p_my;
 
-    p_mx = s->next_picture.f.motion_val[0][xy][0];
+    p_mx = s->next_picture.motion_val[0][xy][0];
     if((unsigned)(p_mx + tab_bias) < tab_size){
         s->mv[0][i][0] = s->direct_scale_mv[0][p_mx + tab_bias] + mx;
         s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx
@@ -99,7 +99,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my,
         s->mv[1][i][0] = mx ? s->mv[0][i][0] - p_mx
                             : p_mx*(time_pb - time_pp)/time_pp;
     }
-    p_my = s->next_picture.f.motion_val[0][xy][1];
+    p_my = s->next_picture.motion_val[0][xy][1];
     if((unsigned)(p_my + tab_bias) < tab_size){
         s->mv[0][i][1] = s->direct_scale_mv[0][p_my + tab_bias] + my;
         s->mv[1][i][1] = my ? s->mv[0][i][1] - p_my
@@ -120,7 +120,7 @@ static inline void ff_mpeg4_set_one_direct_mv(MpegEncContext *s, int mx, int my,
  */
 int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){
     const int mb_index= s->mb_x + s->mb_y*s->mb_stride;
-    const int colocated_mb_type = s->next_picture.f.mb_type[mb_index];
+    const int colocated_mb_type = s->next_picture.mb_type[mb_index];
     uint16_t time_pp;
     uint16_t time_pb;
     int i;
@@ -137,7 +137,7 @@ int ff_mpeg4_set_direct_mv(MpegEncContext *s, int mx, int my){
     } else if(IS_INTERLACED(colocated_mb_type)){
         s->mv_type = MV_TYPE_FIELD;
         for(i=0; i<2; i++){
-            int field_select = s->next_picture.f.ref_index[0][4 * mb_index + 2 * i];
+            int field_select = s->next_picture.ref_index[0][4 * mb_index + 2 * i];
             s->field_select[0][i]= field_select;
             s->field_select[1][i]= i;
             if(s->top_field_first){
index 17b119072f9d598f5e0582588633c159d8876646..8ebae2e0852e8ffd9e948b05a444c6c6191996a9 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include "error_resilience.h"
+#include "internal.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
 #include "h263.h"
@@ -56,7 +57,7 @@ void ff_mpeg4_pred_ac(MpegEncContext * s, int16_t *block, int n,
 {
     int i;
     int16_t *ac_val, *ac_val1;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t * const qscale_table = s->current_picture.qscale_table;
 
     /* find prediction */
     ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
@@ -377,9 +378,9 @@ int ff_mpeg4_decode_video_packet_header(MpegEncContext *s)
     if(s->pict_type == AV_PICTURE_TYPE_B){
         int mb_x = 0, mb_y = 0;
 
-        while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) {
+        while (s->next_picture.mbskip_table[s->mb_index2xy[mb_num]]) {
             if (!mb_x)
-                ff_thread_await_progress(&s->next_picture_ptr->f, mb_y++, 0);
+                ff_thread_await_progress(&s->next_picture_ptr->tf, mb_y++, 0);
             mb_num++;
             if (++mb_x == s->mb_width) mb_x = 0;
         }
@@ -572,13 +573,13 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){
                 }while(cbpc == 8);
 
                 s->cbp_table[xy]= cbpc & 3;
-                s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+                s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
                 s->mb_intra = 1;
 
                 if(cbpc & 4) {
                     ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
                 }
-                s->current_picture.f.qscale_table[xy]= s->qscale;
+                s->current_picture.qscale_table[xy]= s->qscale;
 
                 s->mbintra_table[xy]= 1;
                 for(i=0; i<6; i++){
@@ -594,7 +595,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){
                 s->pred_dir_table[xy]= dir;
             }else{ /* P/S_TYPE */
                 int mx, my, pred_x, pred_y, bits;
-                int16_t * const mot_val = s->current_picture.f.motion_val[0][s->block_index[0]];
+                int16_t * const mot_val = s->current_picture.motion_val[0][s->block_index[0]];
                 const int stride= s->b8_stride*2;
 
 try_again:
@@ -606,11 +607,11 @@ try_again:
                 if(bits&0x10000){
                     /* skip mb */
                     if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
-                        s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
+                        s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
                         mx= get_amv(s, 0);
                         my= get_amv(s, 1);
                     }else{
-                        s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+                        s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
                         mx=my=0;
                     }
                     mot_val[0       ]= mot_val[2       ]=
@@ -636,7 +637,7 @@ try_again:
                 s->mb_intra = ((cbpc & 4) != 0);
 
                 if(s->mb_intra){
-                    s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+                    s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
                     s->mbintra_table[xy]= 1;
                     mot_val[0       ]= mot_val[2       ]=
                     mot_val[0+stride]= mot_val[2+stride]= 0;
@@ -662,11 +663,11 @@ try_again:
                             my = ff_h263_decode_motion(s, pred_y, s->f_code);
                             if (my >= 0xffff)
                                 return -1;
-                            s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+                            s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
                         } else {
                             mx = get_amv(s, 0);
                             my = get_amv(s, 1);
-                            s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
+                            s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_GMC | MB_TYPE_L0;
                         }
 
                         mot_val[0       ]= mot_val[2       ] =
@@ -675,7 +676,7 @@ try_again:
                         mot_val[1+stride]= mot_val[3+stride]= my;
                     } else {
                         int i;
-                        s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+                        s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
                         for(i=0;i<4;i++) {
                             int16_t *mot_val= ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                             mx = ff_h263_decode_motion(s, pred_x, s->f_code);
@@ -727,9 +728,9 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
                 }
 
                 s->cbp_table[xy]|= cbpy<<2;
-                s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
+                s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
             }else{ /* P || S_TYPE */
-                if (IS_INTRA(s->current_picture.f.mb_type[xy])) {
+                if (IS_INTRA(s->current_picture.mb_type[xy])) {
                     int dir=0,i;
                     int ac_pred = get_bits1(&s->gb);
                     int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
@@ -742,7 +743,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
                     if(s->cbp_table[xy] & 8) {
                         ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
                     }
-                    s->current_picture.f.qscale_table[xy] = s->qscale;
+                    s->current_picture.qscale_table[xy] = s->qscale;
 
                     for(i=0; i<6; i++){
                         int dc_pred_dir;
@@ -756,10 +757,10 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
                     }
                     s->cbp_table[xy]&= 3; //remove dquant
                     s->cbp_table[xy]|= cbpy<<2;
-                    s->current_picture.f.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
+                    s->current_picture.mb_type[xy] |= ac_pred*MB_TYPE_ACPRED;
                     s->pred_dir_table[xy]= dir;
-                } else if (IS_SKIP(s->current_picture.f.mb_type[xy])) {
-                    s->current_picture.f.qscale_table[xy] = s->qscale;
+                } else if (IS_SKIP(s->current_picture.mb_type[xy])) {
+                    s->current_picture.qscale_table[xy] = s->qscale;
                     s->cbp_table[xy]= 0;
                 }else{
                     int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
@@ -772,7 +773,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){
                     if(s->cbp_table[xy] & 8) {
                         ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
                     }
-                    s->current_picture.f.qscale_table[xy] = s->qscale;
+                    s->current_picture.qscale_table[xy] = s->qscale;
 
                     s->cbp_table[xy]&= 3; //remove dquant
                     s->cbp_table[xy]|= (cbpy^0xf)<<2;
@@ -1071,20 +1072,20 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
     int cbp, mb_type;
     const int xy= s->mb_x + s->mb_y*s->mb_stride;
 
-    mb_type = s->current_picture.f.mb_type[xy];
+    mb_type = s->current_picture.mb_type[xy];
     cbp = s->cbp_table[xy];
 
     s->use_intra_dc_vlc= s->qscale < s->intra_dc_threshold;
 
-    if (s->current_picture.f.qscale_table[xy] != s->qscale) {
-        ff_set_qscale(s, s->current_picture.f.qscale_table[xy]);
+    if (s->current_picture.qscale_table[xy] != s->qscale) {
+        ff_set_qscale(s, s->current_picture.qscale_table[xy]);
     }
 
     if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
         int i;
         for(i=0; i<4; i++){
-            s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-            s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+            s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
+            s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
         }
         s->mb_intra = IS_INTRA(mb_type);
 
@@ -1102,7 +1103,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
                 s->mb_skipped = 1;
             }
         }else if(s->mb_intra){
-            s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]);
+            s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
         }else if(!s->mb_intra){
 //            s->mcsel= 0; //FIXME do we need to init that
 
@@ -1115,7 +1116,7 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
         }
     } else { /* I-Frame */
         s->mb_intra = 1;
-        s->ac_pred = IS_ACPRED(s->current_picture.f.mb_type[xy]);
+        s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
     }
 
     if (!IS_SKIP(mb_type)) {
@@ -1168,14 +1169,14 @@ static int mpeg4_decode_mb(MpegEncContext *s,
                 s->mv_dir = MV_DIR_FORWARD;
                 s->mv_type = MV_TYPE_16X16;
                 if(s->pict_type==AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
-                    s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
+                    s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
                     s->mcsel=1;
                     s->mv[0][0][0]= get_amv(s, 0);
                     s->mv[0][0][1]= get_amv(s, 1);
 
                     s->mb_skipped = 0;
                 }else{
-                    s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+                    s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
                     s->mcsel=0;
                     s->mv[0][0][0] = 0;
                     s->mv[0][0][1] = 0;
@@ -1210,7 +1211,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
         s->mv_dir = MV_DIR_FORWARD;
         if ((cbpc & 16) == 0) {
             if(s->mcsel){
-                s->current_picture.f.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
+                s->current_picture.mb_type[xy] = MB_TYPE_GMC | MB_TYPE_16x16 | MB_TYPE_L0;
                 /* 16x16 global motion prediction */
                 s->mv_type = MV_TYPE_16X16;
                 mx= get_amv(s, 0);
@@ -1218,7 +1219,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
                 s->mv[0][0][0] = mx;
                 s->mv[0][0][1] = my;
             }else if((!s->progressive_sequence) && get_bits1(&s->gb)){
-                s->current_picture.f.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED;
+                s->current_picture.mb_type[xy] = MB_TYPE_16x8 | MB_TYPE_L0 | MB_TYPE_INTERLACED;
                 /* 16x8 field motion prediction */
                 s->mv_type= MV_TYPE_FIELD;
 
@@ -1240,7 +1241,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
                     s->mv[0][i][1] = my;
                 }
             }else{
-                s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+                s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
                 /* 16x16 motion prediction */
                 s->mv_type = MV_TYPE_16X16;
                 ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
@@ -1257,7 +1258,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
                 s->mv[0][0][1] = my;
             }
         } else {
-            s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
             s->mv_type = MV_TYPE_8X8;
             for(i=0;i<4;i++) {
                 mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
@@ -1290,11 +1291,11 @@ static int mpeg4_decode_mb(MpegEncContext *s,
                 s->last_mv[i][1][1]= 0;
             }
 
-            ff_thread_await_progress(&s->next_picture_ptr->f, s->mb_y, 0);
+            ff_thread_await_progress(&s->next_picture_ptr->tf, s->mb_y, 0);
         }
 
         /* if we skipped it in the future P Frame than skip it now too */
-        s->mb_skipped = s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
+        s->mb_skipped = s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
 
         if(s->mb_skipped){
                 /* skip mb */
@@ -1307,7 +1308,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
             s->mv[0][0][1] = 0;
             s->mv[1][0][0] = 0;
             s->mv[1][0][1] = 0;
-            s->current_picture.f.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+            s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
             goto end;
         }
 
@@ -1413,7 +1414,7 @@ static int mpeg4_decode_mb(MpegEncContext *s,
             s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
             mb_type |= ff_mpeg4_set_direct_mv(s, mx, my);
         }
-        s->current_picture.f.mb_type[xy] = mb_type;
+        s->current_picture.mb_type[xy] = mb_type;
     } else { /* I-Frame */
         do{
             cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
@@ -1428,9 +1429,9 @@ static int mpeg4_decode_mb(MpegEncContext *s,
 intra:
         s->ac_pred = get_bits1(&s->gb);
         if(s->ac_pred)
-            s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
+            s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
         else
-            s->current_picture.f.mb_type[xy] = MB_TYPE_INTRA;
+            s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
 
         cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
         if(cbpy<0){
@@ -1471,12 +1472,12 @@ end:
         if(mpeg4_is_resync(s)){
             const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
 
-            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) {
-                ff_thread_await_progress(&s->next_picture_ptr->f,
+            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.mbskip_table[xy + delta]) {
+                ff_thread_await_progress(&s->next_picture_ptr->tf,
                                         (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0);
             }
 
-            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta])
+            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.mbskip_table[xy + delta])
                 return SLICE_OK;
             return SLICE_END;
         }
@@ -2236,6 +2237,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
     s->time_increment_bits = 4; /* default value for broken headers */
     avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
index 9bb1f9a0bc2d63feb6590f8798e1a4cda34d95c3..fb4d7a874323a9c9a567705164d324dbe38fef99 100644 (file)
@@ -126,7 +126,7 @@ static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const
 {
     int score= 0;
     int i, n;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t * const qscale_table = s->current_picture.qscale_table;
 
     memcpy(zigzag_last_index, s->block_last_index, sizeof(int)*6);
 
@@ -203,7 +203,7 @@ static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const
  */
 void ff_clean_mpeg4_qscales(MpegEncContext *s){
     int i;
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t * const qscale_table = s->current_picture.qscale_table;
 
     ff_clean_h263_qscales(s);
 
@@ -499,7 +499,7 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
             assert(mb_type>=0);
 
             /* nothing to do if this MB was skipped in the next P Frame */
-            if (s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ...
+            if (s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ...
                 s->skip_count++;
                 s->mv[0][0][0]=
                 s->mv[0][0][1]=
@@ -643,7 +643,7 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
                             break;
 
                         b_pic = pic->f.data[0] + offset;
-                        if (pic->f.type != FF_BUFFER_TYPE_SHARED)
+                        if (!pic->shared)
                             b_pic+= INPLACE_OFFSET;
                         diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
                         if(diff>s->qscale*70){ //FIXME check that 70 is optimal
@@ -747,8 +747,8 @@ void ff_mpeg4_encode_mb(MpegEncContext * s,
                     /* motion vectors: 8x8 mode*/
                     ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
 
-                    ff_h263_encode_motion_vector(s, s->current_picture.f.motion_val[0][ s->block_index[i] ][0] - pred_x,
-                                                    s->current_picture.f.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
+                    ff_h263_encode_motion_vector(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x,
+                                                    s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
                 }
             }
 
index 721f0965a761a90165055ede7a1f2c3564f18578..e3e19422a46a7689f901153938edf60fbed0cbff 100644 (file)
@@ -1611,7 +1611,7 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
     if (!samples) {
         av_assert0(s->frame != NULL);
         s->frame->nb_samples = s->avctx->frame_size;
-        if ((ret = ff_get_buffer(s->avctx, s->frame)) < 0) {
+        if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -1907,7 +1907,7 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = MPA_FRAME_SIZE;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index bee32d545250a9181df0cded81d1748478407cc0..b48640f8fc281d05b86a936b2ddc3a2b197816b0 100644 (file)
@@ -27,6 +27,7 @@
  * The simplest mpeg encoder (well, it was the simplest!).
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "dsputil.h"
@@ -233,28 +234,6 @@ av_cold int ff_dct_common_init(MpegEncContext *s)
     return 0;
 }
 
-void ff_copy_picture(Picture *dst, Picture *src)
-{
-    *dst = *src;
-    dst->f.type = FF_BUFFER_TYPE_COPY;
-}
-
-/**
- * Release a frame buffer
- */
-static void free_frame_buffer(MpegEncContext *s, Picture *pic)
-{
-    /* WM Image / Screen codecs allocate internal buffers with different
-     * dimensions / colorspaces; ignore user-defined callbacks for these. */
-    if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
-        s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
-        s->codec_id != AV_CODEC_ID_MSS2)
-        ff_thread_release_buffer(s->avctx, &pic->f);
-    else
-        avcodec_default_release_buffer(s->avctx, &pic->f);
-    av_freep(&pic->hwaccel_picture_private);
-}
-
 int ff_mpv_frame_size_alloc(MpegEncContext *s, int linesize)
 {
     int alloc_size = FFALIGN(FFABS(linesize) + 32, 32);
@@ -298,16 +277,22 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
         }
     }
 
+    pic->tf.f = &pic->f;
     if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
         s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
         s->codec_id != AV_CODEC_ID_MSS2)
-        r = ff_thread_get_buffer(s->avctx, &pic->f);
-    else
-        r = avcodec_default_get_buffer(s->avctx, &pic->f);
-
-    if (r < 0 || !pic->f.type || !pic->f.data[0]) {
-        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %p)\n",
-               r, pic->f.type, pic->f.data[0]);
+        r = ff_thread_get_buffer(s->avctx, &pic->tf,
+                                 pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
+    else {
+        pic->f.width  = s->avctx->width;
+        pic->f.height = s->avctx->height;
+        pic->f.format = s->avctx->pix_fmt;
+        r = avcodec_default_get_buffer2(s->avctx, &pic->f, 0);
+    }
+
+    if (r < 0 || !pic->f.data[0]) {
+        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n",
+               r, pic->f.data[0]);
         av_freep(&pic->hwaccel_picture_private);
         return -1;
     }
@@ -316,14 +301,14 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
                         s->uvlinesize != pic->f.linesize[1])) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed (stride changed)\n");
-        free_frame_buffer(s, pic);
+        ff_mpeg_unref_picture(s, pic);
         return -1;
     }
 
     if (pic->f.linesize[1] != pic->f.linesize[2]) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed (uv stride mismatch)\n");
-        free_frame_buffer(s, pic);
+        ff_mpeg_unref_picture(s, pic);
         return -1;
     }
 
@@ -331,33 +316,105 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)
         (ret = ff_mpv_frame_size_alloc(s, pic->f.linesize[0])) < 0) {
         av_log(s->avctx, AV_LOG_ERROR,
                "get_buffer() failed to allocate context scratch buffers.\n");
-        free_frame_buffer(s, pic);
+        ff_mpeg_unref_picture(s, pic);
         return ret;
     }
 
     return 0;
 }
 
-/**
- * Allocate a Picture.
- * The pixels are allocated/set by calling get_buffer() if shared = 0
- */
-int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
+static void free_picture_tables(Picture *pic)
 {
-    const int big_mb_num = s->mb_stride * (s->mb_height + 1) + 1;
+    int i;
 
-    // the + 1 is needed so memset(,,stride*height) does not sig11
+    av_buffer_unref(&pic->mb_var_buf);
+    av_buffer_unref(&pic->mc_mb_var_buf);
+    av_buffer_unref(&pic->mb_mean_buf);
+    av_buffer_unref(&pic->mbskip_table_buf);
+    av_buffer_unref(&pic->qscale_table_buf);
+    av_buffer_unref(&pic->mb_type_buf);
 
+    for (i = 0; i < 2; i++) {
+        av_buffer_unref(&pic->motion_val_buf[i]);
+        av_buffer_unref(&pic->ref_index_buf[i]);
+    }
+}
+
+static int alloc_picture_tables(MpegEncContext *s, Picture *pic)
+{
+    const int big_mb_num    = s->mb_stride * (s->mb_height + 1) + 1;
     const int mb_array_size = s->mb_stride * s->mb_height;
     const int b8_array_size = s->b8_stride * s->mb_height * 2;
-    const int b4_array_size = s->b4_stride * s->mb_height * 4;
     int i;
-    int r = -1;
+
+
+    pic->mbskip_table_buf = av_buffer_allocz(mb_array_size + 2);
+    pic->qscale_table_buf = av_buffer_allocz(big_mb_num + s->mb_stride);
+    pic->mb_type_buf      = av_buffer_allocz((big_mb_num + s->mb_stride) *
+                                             sizeof(uint32_t));
+    if (!pic->mbskip_table_buf || !pic->qscale_table_buf || !pic->mb_type_buf)
+        return AVERROR(ENOMEM);
+
+    if (s->encoding) {
+        pic->mb_var_buf    = av_buffer_allocz(mb_array_size * sizeof(int16_t));
+        pic->mc_mb_var_buf = av_buffer_allocz(mb_array_size * sizeof(int16_t));
+        pic->mb_mean_buf   = av_buffer_allocz(mb_array_size);
+        if (!pic->mb_var_buf || !pic->mc_mb_var_buf || !pic->mb_mean_buf)
+            return AVERROR(ENOMEM);
+    }
+
+    if (s->out_format == FMT_H263 || s->encoding ||
+               (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) {
+        int mv_size        = 2 * (b8_array_size + 4) * sizeof(int16_t);
+        int ref_index_size = 4 * mb_array_size;
+
+        for (i = 0; mv_size && i < 2; i++) {
+            pic->motion_val_buf[i] = av_buffer_allocz(mv_size);
+            pic->ref_index_buf[i]  = av_buffer_allocz(ref_index_size);
+            if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i])
+                return AVERROR(ENOMEM);
+        }
+    }
+
+    return 0;
+}
+
+static int make_tables_writable(Picture *pic)
+{
+    int ret, i;
+#define MAKE_WRITABLE(table) \
+do {\
+    if (pic->table &&\
+       (ret = av_buffer_make_writable(&pic->table)) < 0)\
+    return ret;\
+} while (0)
+
+    MAKE_WRITABLE(mb_var_buf);
+    MAKE_WRITABLE(mc_mb_var_buf);
+    MAKE_WRITABLE(mb_mean_buf);
+    MAKE_WRITABLE(mbskip_table_buf);
+    MAKE_WRITABLE(qscale_table_buf);
+    MAKE_WRITABLE(mb_type_buf);
+
+    for (i = 0; i < 2; i++) {
+        MAKE_WRITABLE(motion_val_buf[i]);
+        MAKE_WRITABLE(ref_index_buf[i]);
+    }
+
+    return 0;
+}
+
+/**
+ * Allocate a Picture.
+ * The pixels are allocated/set by calling get_buffer() if shared = 0
+ */
+int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
+{
+    int i, ret;
 
     if (shared) {
         assert(pic->f.data[0]);
-        assert(pic->f.type == 0 || pic->f.type == FF_BUFFER_TYPE_SHARED);
-        pic->f.type = FF_BUFFER_TYPE_SHARED;
+        pic->shared = 1;
     } else {
         assert(!pic->f.data[0]);
 
@@ -368,101 +425,138 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared)
         s->uvlinesize = pic->f.linesize[1];
     }
 
-    if (pic->f.qscale_table == NULL) {
-        if (s->encoding) {
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_var,
-                              mb_array_size * sizeof(int16_t), fail)
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->mc_mb_var,
-                              mb_array_size * sizeof(int16_t), fail)
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_mean,
-                              mb_array_size * sizeof(int8_t ), fail)
-        }
+    if (!pic->qscale_table_buf)
+        ret = alloc_picture_tables(s, pic);
+    else
+        ret = make_tables_writable(pic);
+    if (ret < 0)
+        goto fail;
 
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.mbskip_table,
-                          mb_array_size * sizeof(uint8_t) + 2, fail)// the + 2 is for the slice end check
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->qscale_table_base,
-                          (big_mb_num + s->mb_stride) * sizeof(uint8_t),
-                          fail)
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->mb_type_base,
-                          (big_mb_num + s->mb_stride) * sizeof(uint32_t),
-                          fail)
-        pic->f.mb_type = pic->mb_type_base + 2 * s->mb_stride + 1;
-        pic->f.qscale_table = pic->qscale_table_base + 2 * s->mb_stride + 1;
-        if (s->out_format == FMT_H264) {
-            for (i = 0; i < 2; i++) {
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i],
-                                  2 * (b4_array_size + 4) * sizeof(int16_t),
-                                  fail)
-                pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i],
-                                  4 * mb_array_size * sizeof(uint8_t), fail)
-            }
-            pic->f.motion_subsample_log2 = 2;
-        } else if (s->out_format == FMT_H263 || s->encoding ||
-                   (s->avctx->debug & FF_DEBUG_MV) || s->avctx->debug_mv) {
-            for (i = 0; i < 2; i++) {
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->motion_val_base[i],
-                                  2 * (b8_array_size + 4) * sizeof(int16_t),
-                                  fail)
-                pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
-                FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.ref_index[i],
-                                  4 * mb_array_size * sizeof(uint8_t), fail)
-            }
-            pic->f.motion_subsample_log2 = 3;
-        }
-        if (s->avctx->debug&FF_DEBUG_DCT_COEFF) {
-            FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.dct_coeff,
-                              64 * mb_array_size * sizeof(int16_t) * 6, fail)
-        }
-        pic->f.qstride = s->mb_stride;
-        FF_ALLOCZ_OR_GOTO(s->avctx, pic->f.pan_scan,
-                          1 * sizeof(AVPanScan), fail)
+    if (s->encoding) {
+        pic->mb_var    = (uint16_t*)pic->mb_var_buf->data;
+        pic->mc_mb_var = (uint16_t*)pic->mc_mb_var_buf->data;
+        pic->mb_mean   = pic->mb_mean_buf->data;
     }
 
-    pic->owner2 = s;
+    pic->mbskip_table = pic->mbskip_table_buf->data;
+    pic->qscale_table = pic->qscale_table_buf->data + 2 * s->mb_stride + 1;
+    pic->mb_type      = (uint32_t*)pic->mb_type_buf->data + 2 * s->mb_stride + 1;
+
+    if (pic->motion_val_buf[0]) {
+        for (i = 0; i < 2; i++) {
+            pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
+            pic->ref_index[i]  = pic->ref_index_buf[i]->data;
+        }
+    }
 
     return 0;
-fail: // for  the FF_ALLOCZ_OR_GOTO macro
-    if (r >= 0)
-        free_frame_buffer(s, pic);
-    return -1;
+fail:
+    av_log(s->avctx, AV_LOG_ERROR, "Error allocating a picture.\n");
+    ff_mpeg_unref_picture(s, pic);
+    free_picture_tables(pic);
+    return AVERROR(ENOMEM);
 }
 
 /**
  * Deallocate a picture.
  */
-static void free_picture(MpegEncContext *s, Picture *pic)
+void ff_mpeg_unref_picture(MpegEncContext *s, Picture *pic)
 {
-    int i;
+    int off = offsetof(Picture, mb_mean) + sizeof(pic->mb_mean);
+
+    pic->tf.f = &pic->f;
+    /* WM Image / Screen codecs allocate internal buffers with different
+     * dimensions / colorspaces; ignore user-defined callbacks for these. */
+    if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&
+        s->codec_id != AV_CODEC_ID_VC1IMAGE  &&
+        s->codec_id != AV_CODEC_ID_MSS2)
+        ff_thread_release_buffer(s->avctx, &pic->tf);
+    else
+        av_frame_unref(&pic->f);
+
+    av_buffer_unref(&pic->hwaccel_priv_buf);
 
-    if (pic->f.data[0] && pic->f.type != FF_BUFFER_TYPE_SHARED) {
-        free_frame_buffer(s, pic);
-    }
-
-    av_freep(&pic->mb_var);
-    av_freep(&pic->mc_mb_var);
-    av_freep(&pic->mb_mean);
-    av_freep(&pic->f.mbskip_table);
-    av_freep(&pic->qscale_table_base);
-    pic->f.qscale_table = NULL;
-    av_freep(&pic->mb_type_base);
-    pic->f.mb_type = NULL;
-    av_freep(&pic->f.dct_coeff);
-    av_freep(&pic->f.pan_scan);
-    pic->f.mb_type = NULL;
+    memset((uint8_t*)pic + off, 0, sizeof(*pic) - off);
+}
+
+static int update_picture_tables(Picture *dst, Picture *src)
+{
+     int i;
+
+#define UPDATE_TABLE(table)\
+do {\
+    if (src->table &&\
+        (!dst->table || dst->table->buffer != src->table->buffer)) {\
+        av_buffer_unref(&dst->table);\
+        dst->table = av_buffer_ref(src->table);\
+        if (!dst->table) {\
+            free_picture_tables(dst);\
+            return AVERROR(ENOMEM);\
+        }\
+    }\
+} while (0)
+
+    UPDATE_TABLE(mb_var_buf);
+    UPDATE_TABLE(mc_mb_var_buf);
+    UPDATE_TABLE(mb_mean_buf);
+    UPDATE_TABLE(mbskip_table_buf);
+    UPDATE_TABLE(qscale_table_buf);
+    UPDATE_TABLE(mb_type_buf);
     for (i = 0; i < 2; i++) {
-        av_freep(&pic->motion_val_base[i]);
-        av_freep(&pic->f.ref_index[i]);
-        pic->f.motion_val[i] = NULL;
+        UPDATE_TABLE(motion_val_buf[i]);
+        UPDATE_TABLE(ref_index_buf[i]);
     }
 
-    if (pic->f.type == FF_BUFFER_TYPE_SHARED) {
-        for (i = 0; i < 4; i++) {
-            pic->f.base[i] =
-            pic->f.data[i] = NULL;
-        }
-        pic->f.type = 0;
+    dst->mb_var        = src->mb_var;
+    dst->mc_mb_var     = src->mc_mb_var;
+    dst->mb_mean       = src->mb_mean;
+    dst->mbskip_table  = src->mbskip_table;
+    dst->qscale_table  = src->qscale_table;
+    dst->mb_type       = src->mb_type;
+    for (i = 0; i < 2; i++) {
+        dst->motion_val[i] = src->motion_val[i];
+        dst->ref_index[i]  = src->ref_index[i];
     }
+
+    return 0;
+}
+
+int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src)
+{
+    int ret;
+
+    av_assert0(!dst->f.buf[0]);
+    av_assert0(src->f.buf[0]);
+
+    src->tf.f = &src->f;
+    dst->tf.f = &dst->f;
+    ret = ff_thread_ref_frame(&dst->tf, &src->tf);
+    if (ret < 0)
+        goto fail;
+
+    ret = update_picture_tables(dst, src);
+    if (ret < 0)
+        goto fail;
+
+    if (src->hwaccel_picture_private) {
+        dst->hwaccel_priv_buf = av_buffer_ref(src->hwaccel_priv_buf);
+        if (!dst->hwaccel_priv_buf)
+            goto fail;
+        dst->hwaccel_picture_private = dst->hwaccel_priv_buf->data;
+    }
+
+    dst->field_picture           = src->field_picture;
+    dst->mb_var_sum              = src->mb_var_sum;
+    dst->mc_mb_var_sum           = src->mc_mb_var_sum;
+    dst->b_frame_score           = src->b_frame_score;
+    dst->needs_realloc           = src->needs_realloc;
+    dst->reference               = src->reference;
+    dst->shared                  = src->shared;
+
+    return 0;
+fail:
+    ff_mpeg_unref_picture(s, dst);
+    return ret;
 }
 
 static int init_duplicate_context(MpegEncContext *s)
@@ -583,7 +677,7 @@ int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src)
 int ff_mpeg_update_thread_context(AVCodecContext *dst,
                                   const AVCodecContext *src)
 {
-    int i;
+    int i, ret;
     MpegEncContext *s = dst->priv_data, *s1 = src->priv_data;
 
     if (dst == src || !s1->context_initialized)
@@ -595,8 +689,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
         memcpy(s, s1, sizeof(MpegEncContext));
 
         s->avctx                 = dst;
-        s->picture_range_start  += MAX_PICTURE_COUNT;
-        s->picture_range_end    += MAX_PICTURE_COUNT;
         s->bitstream_buffer      = NULL;
         s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0;
 
@@ -621,13 +713,27 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
     s->picture_number       = s1->picture_number;
     s->input_picture_number = s1->input_picture_number;
 
-    memcpy(s->picture, s1->picture, s1->picture_count * sizeof(Picture));
-    memcpy(&s->last_picture, &s1->last_picture,
-           (char *) &s1->last_picture_ptr - (char *) &s1->last_picture);
-
-    // reset s->picture[].f.extended_data to s->picture[].f.data
-    for (i = 0; i < s->picture_count; i++)
-        s->picture[i].f.extended_data = s->picture[i].f.data;
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        ff_mpeg_unref_picture(s, &s->picture[i]);
+        if (s1->picture[i].f.data[0] &&
+            (ret = ff_mpeg_ref_picture(s, &s->picture[i], &s1->picture[i])) < 0)
+            return ret;
+    }
+
+#define UPDATE_PICTURE(pic)\
+do {\
+    ff_mpeg_unref_picture(s, &s->pic);\
+    if (s1->pic.f.data[0])\
+        ret = ff_mpeg_ref_picture(s, &s->pic, &s1->pic);\
+    else\
+        ret = update_picture_tables(&s->pic, &s1->pic);\
+    if (ret < 0)\
+        return ret;\
+} while (0)
+
+    UPDATE_PICTURE(current_picture);
+    UPDATE_PICTURE(last_picture);
+    UPDATE_PICTURE(next_picture);
 
     s->last_picture_ptr    = REBASE_PICTURE(s1->last_picture_ptr,    s, s1);
     s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1);
@@ -717,9 +823,6 @@ void ff_MPV_common_defaults(MpegEncContext *s)
     s->f_code                = 1;
     s->b_code                = 1;
 
-    s->picture_range_start   = 0;
-    s->picture_range_end     = MAX_PICTURE_COUNT;
-
     s->slice_context_count   = 1;
 }
 
@@ -1006,12 +1109,17 @@ av_cold int ff_MPV_common_init(MpegEncContext *s)
         }
     }
 
-    s->picture_count = MAX_PICTURE_COUNT * FFMAX(1, s->avctx->thread_count);
     FF_ALLOCZ_OR_GOTO(s->avctx, s->picture,
-                      s->picture_count * sizeof(Picture), fail);
-    for (i = 0; i < s->picture_count; i++) {
+                      MAX_PICTURE_COUNT * sizeof(Picture), fail);
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
         avcodec_get_frame_defaults(&s->picture[i].f);
     }
+    memset(&s->next_picture, 0, sizeof(s->next_picture));
+    memset(&s->last_picture, 0, sizeof(s->last_picture));
+    memset(&s->current_picture, 0, sizeof(s->current_picture));
+    avcodec_get_frame_defaults(&s->next_picture.f);
+    avcodec_get_frame_defaults(&s->last_picture.f);
+    avcodec_get_frame_defaults(&s->current_picture.f);
 
     if (s->width && s->height) {
         if (init_context_frame(s))
@@ -1125,10 +1233,11 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s)
     } else
         free_duplicate_context(s);
 
-    free_context_frame(s);
+    if ((err = free_context_frame(s)) < 0)
+        return err;
 
     if (s->picture)
-        for (i = 0; i < s->picture_count; i++) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
                 s->picture[i].needs_realloc = 1;
         }
 
@@ -1214,18 +1323,24 @@ void ff_MPV_common_end(MpegEncContext *s)
     av_freep(&s->reordered_input_picture);
     av_freep(&s->dct_offset);
 
-    if (s->picture && !s->avctx->internal->is_copy) {
-        for (i = 0; i < s->picture_count; i++) {
-            free_picture(s, &s->picture[i]);
+    if (s->picture) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            free_picture_tables(&s->picture[i]);
+            ff_mpeg_unref_picture(s, &s->picture[i]);
         }
     }
     av_freep(&s->picture);
+    free_picture_tables(&s->last_picture);
+    ff_mpeg_unref_picture(s, &s->last_picture);
+    free_picture_tables(&s->current_picture);
+    ff_mpeg_unref_picture(s, &s->current_picture);
+    free_picture_tables(&s->next_picture);
+    ff_mpeg_unref_picture(s, &s->next_picture);
+    free_picture_tables(&s->new_picture);
+    ff_mpeg_unref_picture(s, &s->new_picture);
 
     free_context_frame(s);
 
-    if (!(s->avctx->active_thread_type & FF_THREAD_FRAME))
-        avcodec_default_free_buffers(s->avctx);
-
     s->context_initialized      = 0;
     s->last_picture_ptr         =
     s->next_picture_ptr         =
@@ -1330,12 +1445,10 @@ void ff_release_unused_pictures(MpegEncContext*s, int remove_current)
     int i;
 
     /* release non reference frames */
-    for (i = 0; i < s->picture_count; i++) {
-        if (s->picture[i].f.data[0] && !s->picture[i].f.reference &&
-            (!s->picture[i].owner2 || s->picture[i].owner2 == s) &&
-            (remove_current || &s->picture[i] !=  s->current_picture_ptr)
-            /* && s->picture[i].type!= FF_BUFFER_TYPE_SHARED */) {
-            free_frame_buffer(s, &s->picture[i]);
+    for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+        if (!s->picture[i].reference &&
+            (remove_current || &s->picture[i] !=  s->current_picture_ptr)) {
+            ff_mpeg_unref_picture(s, &s->picture[i]);
         }
     }
 }
@@ -1344,9 +1457,8 @@ static inline int pic_is_unused(MpegEncContext *s, Picture *pic)
 {
     if (pic->f.data[0] == NULL)
         return 1;
-    if (pic->needs_realloc && !(pic->f.reference & DELAYED_PIC_REF))
-        if (!pic->owner2 || pic->owner2 == s)
-            return 1;
+    if (pic->needs_realloc && !(pic->reference & DELAYED_PIC_REF))
+        return 1;
     return 0;
 }
 
@@ -1355,16 +1467,12 @@ static int find_unused_picture(MpegEncContext *s, int shared)
     int i;
 
     if (shared) {
-        for (i = s->picture_range_start; i < s->picture_range_end; i++) {
-            if (s->picture[i].f.data[0] == NULL && s->picture[i].f.type == 0)
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            if (s->picture[i].f.data[0] == NULL)
                 return i;
         }
     } else {
-        for (i = s->picture_range_start; i < s->picture_range_end; i++) {
-            if (pic_is_unused(s, &s->picture[i]) && s->picture[i].f.type != 0)
-                return i; // FIXME
-        }
-        for (i = s->picture_range_start; i < s->picture_range_end; i++) {
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
             if (pic_is_unused(s, &s->picture[i]))
                 return i;
         }
@@ -1377,10 +1485,11 @@ int ff_find_unused_picture(MpegEncContext *s, int shared)
 {
     int ret = find_unused_picture(s, shared);
 
-    if (ret >= 0 && ret < s->picture_range_end) {
+    if (ret >= 0 && ret < MAX_PICTURE_COUNT) {
         if (s->picture[ret].needs_realloc) {
             s->picture[ret].needs_realloc = 0;
-            free_picture(s, &s->picture[ret]);
+            free_picture_tables(&s->picture[ret]);
+            ff_mpeg_unref_picture(s, &s->picture[ret]);
             avcodec_get_frame_defaults(&s->picture[ret].f);
         }
     }
@@ -1414,7 +1523,7 @@ static void update_noise_reduction(MpegEncContext *s)
  */
 int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
 {
-    int i;
+    int i, ret;
     Picture *pic;
     s->mb_skipped = 0;
 
@@ -1423,22 +1532,20 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
         if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
             s->last_picture_ptr != s->next_picture_ptr &&
             s->last_picture_ptr->f.data[0]) {
-            if (s->last_picture_ptr->owner2 == s)
-                free_frame_buffer(s, s->last_picture_ptr);
+            ff_mpeg_unref_picture(s, s->last_picture_ptr);
         }
 
         /* release forgotten pictures */
         /* if (mpeg124/h263) */
         if (!s->encoding) {
-            for (i = 0; i < s->picture_count; i++) {
-                if (s->picture[i].owner2 == s && s->picture[i].f.data[0] &&
-                    &s->picture[i] != s->last_picture_ptr &&
+            for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+                if (&s->picture[i] != s->last_picture_ptr &&
                     &s->picture[i] != s->next_picture_ptr &&
-                    s->picture[i].f.reference && !s->picture[i].needs_realloc) {
+                    s->picture[i].reference && !s->picture[i].needs_realloc) {
                     if (!(avctx->active_thread_type & FF_THREAD_FRAME))
                         av_log(avctx, AV_LOG_ERROR,
                                "releasing zombie picture\n");
-                    free_frame_buffer(s, &s->picture[i]);
+                    ff_mpeg_unref_picture(s, &s->picture[i]);
                 }
             }
         }
@@ -1461,12 +1568,12 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
             pic = &s->picture[i];
         }
 
-        pic->f.reference = 0;
+        pic->reference = 0;
         if (!s->droppable) {
             if (s->codec_id == AV_CODEC_ID_H264)
-                pic->f.reference = s->picture_structure;
+                pic->reference = s->picture_structure;
             else if (s->pict_type != AV_PICTURE_TYPE_B)
-                pic->f.reference = 3;
+                pic->reference = 3;
         }
 
         pic->f.coded_picture_number = s->coded_picture_number++;
@@ -1493,9 +1600,12 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     //     s->current_picture_ptr->quality = s->new_picture_ptr->quality;
     s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
 
-    ff_copy_picture(&s->current_picture, s->current_picture_ptr);
+    ff_mpeg_unref_picture(s, &s->current_picture);
+    if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,
+                                   s->current_picture_ptr)) < 0)
+        return ret;
 
-    if (s->pict_type != AV_PICTURE_TYPE_B) {
+    if (s->codec_id != AV_CODEC_ID_H264 && s->pict_type != AV_PICTURE_TYPE_B) {
         s->last_picture_ptr = s->next_picture_ptr;
         if (!s->droppable)
             s->next_picture_ptr = s->current_picture_ptr;
@@ -1543,9 +1653,8 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
                    (avctx->height >> v_chroma_shift) *
                    s->last_picture_ptr->f.linesize[2]);
 
-            ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 1);
-            s->last_picture_ptr->f.reference = 3;
+            ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0);
+            ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1);
         }
         if ((s->next_picture_ptr == NULL ||
              s->next_picture_ptr->f.data[0] == NULL) &&
@@ -1561,27 +1670,31 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
                 s->next_picture_ptr = NULL;
                 return -1;
             }
-            ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 0);
-            ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 1);
-            s->next_picture_ptr->f.reference = 3;
+            ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0);
+            ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1);
         }
     }
 
-    if (s->last_picture_ptr)
-        ff_copy_picture(&s->last_picture, s->last_picture_ptr);
-    if (s->next_picture_ptr)
-        ff_copy_picture(&s->next_picture, s->next_picture_ptr);
+    if (s->codec_id != AV_CODEC_ID_H264) {
+        if (s->last_picture_ptr) {
+            ff_mpeg_unref_picture(s, &s->last_picture);
+            if (s->last_picture_ptr->f.data[0] &&
+                (ret = ff_mpeg_ref_picture(s, &s->last_picture,
+                                           s->last_picture_ptr)) < 0)
+                return ret;
+        }
+        if (s->next_picture_ptr) {
+            ff_mpeg_unref_picture(s, &s->next_picture);
+            if (s->next_picture_ptr->f.data[0] &&
+                (ret = ff_mpeg_ref_picture(s, &s->next_picture,
+                                           s->next_picture_ptr)) < 0)
+                return ret;
+        }
 
-    if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) {
-        if (s->next_picture_ptr)
-            s->next_picture_ptr->owner2 = s;
-        if (s->last_picture_ptr)
-            s->last_picture_ptr->owner2 = s;
+        assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
+                                                     s->last_picture_ptr->f.data[0]));
     }
 
-    assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
-                                                 s->last_picture_ptr->f.data[0]));
-
     if (s->picture_structure!= PICT_FRAME && s->out_format != FMT_H264) {
         int i;
         for (i = 0; i < 4; i++) {
@@ -1635,7 +1748,7 @@ void ff_MPV_frame_end(MpegEncContext *s)
               !s->avctx->hwaccel &&
               !(s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
               s->unrestricted_mv &&
-              s->current_picture.f.reference &&
+              s->current_picture.reference &&
               !s->intra_only &&
               !(s->flags & CODEC_FLAG_EMU_EDGE)) {
        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
@@ -1675,11 +1788,9 @@ void ff_MPV_frame_end(MpegEncContext *s)
 
     if (s->encoding) {
         /* release non-reference frames */
-        for (i = 0; i < s->picture_count; i++) {
-            if (s->picture[i].f.data[0] && !s->picture[i].f.reference
-                /* && s->picture[i].type != FF_BUFFER_TYPE_SHARED */) {
-                free_frame_buffer(s, &s->picture[i]);
-            }
+        for (i = 0; i < MAX_PICTURE_COUNT; i++) {
+            if (!s->picture[i].reference)
+                ff_mpeg_unref_picture(s, &s->picture[i]);
         }
     }
     // clear copies, to avoid confusion
@@ -1690,9 +1801,8 @@ void ff_MPV_frame_end(MpegEncContext *s)
 #endif
     s->avctx->coded_frame = &s->current_picture_ptr->f;
 
-    if (s->codec_id != AV_CODEC_ID_H264 && s->current_picture.f.reference) {
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
-    }
+    if (s->codec_id != AV_CODEC_ID_H264 && s->current_picture.reference)
+        ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
 }
 
 /**
@@ -1786,10 +1896,12 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
 /**
  * Print debugging info for the given picture.
  */
-void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
+void ff_print_debug_info(MpegEncContext *s, Picture *p)
 {
-    if (s->avctx->hwaccel || !pict || !pict->mb_type)
+    AVFrame *pict;
+    if (s->avctx->hwaccel || !p || !p->mb_type)
         return;
+    pict = &p->f;
 
     if (s->avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {
         int x,y;
@@ -1825,10 +1937,10 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
                 }
                 if (s->avctx->debug & FF_DEBUG_QP) {
                     av_log(s->avctx, AV_LOG_DEBUG, "%2d",
-                           pict->qscale_table[x + y * s->mb_stride]);
+                           p->qscale_table[x + y * s->mb_stride]);
                 }
                 if (s->avctx->debug & FF_DEBUG_MB_TYPE) {
-                    int mb_type = pict->mb_type[x + y * s->mb_stride];
+                    int mb_type = p->mb_type[x + y * s->mb_stride];
                     // Type & MV direction
                     if (IS_PCM(mb_type))
                         av_log(s->avctx, AV_LOG_DEBUG, "P");
@@ -1902,7 +2014,6 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
                               pict->linesize[i] * height >> v_chroma_shift);
             pict->data[i] = s->visualization_buffer[i];
         }
-        pict->type   = FF_BUFFER_TYPE_COPY;
         ptr          = pict->data[0];
         block_height = 16 >> v_chroma_shift;
 
@@ -1910,7 +2021,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
             int mb_x;
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                 const int mb_index = mb_x + mb_y * s->mb_stride;
-                if ((s->avctx->debug_mv) && pict->motion_val) {
+                if ((s->avctx->debug_mv) && p->motion_val) {
                     int type;
                     for (type = 0; type < 3; type++) {
                         int direction = 0;
@@ -1934,46 +2045,46 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
                             direction = 1;
                             break;
                         }
-                        if (!USES_LIST(pict->mb_type[mb_index], direction))
+                        if (!USES_LIST(p->mb_type[mb_index], direction))
                             continue;
 
-                        if (IS_8X8(pict->mb_type[mb_index])) {
+                        if (IS_8X8(p->mb_type[mb_index])) {
                             int i;
                             for (i = 0; i < 4; i++) {
                                 int sx = mb_x * 16 + 4 + 8 * (i & 1);
                                 int sy = mb_y * 16 + 4 + 8 * (i >> 1);
                                 int xy = (mb_x * 2 + (i & 1) +
                                           (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = (pict->motion_val[direction][xy][0] >> shift) + sx;
-                                int my = (pict->motion_val[direction][xy][1] >> shift) + sy;
+                                int mx = (p->motion_val[direction][xy][0] >> shift) + sx;
+                                int my = (p->motion_val[direction][xy][1] >> shift) + sy;
                                 draw_arrow(ptr, sx, sy, mx, my, width,
                                            height, s->linesize, 100);
                             }
-                        } else if (IS_16X8(pict->mb_type[mb_index])) {
+                        } else if (IS_16X8(p->mb_type[mb_index])) {
                             int i;
                             for (i = 0; i < 2; i++) {
                                 int sx = mb_x * 16 + 8;
                                 int sy = mb_y * 16 + 4 + 8 * i;
                                 int xy = (mb_x * 2 + (mb_y * 2 + i) * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = (pict->motion_val[direction][xy][0] >> shift);
-                                int my = (pict->motion_val[direction][xy][1] >> shift);
+                                int mx = (p->motion_val[direction][xy][0] >> shift);
+                                int my = (p->motion_val[direction][xy][1] >> shift);
 
-                                if (IS_INTERLACED(pict->mb_type[mb_index]))
+                                if (IS_INTERLACED(p->mb_type[mb_index]))
                                     my *= 2;
 
                             draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
                                        height, s->linesize, 100);
                             }
-                        } else if (IS_8X16(pict->mb_type[mb_index])) {
+                        } else if (IS_8X16(p->mb_type[mb_index])) {
                             int i;
                             for (i = 0; i < 2; i++) {
                                 int sx = mb_x * 16 + 4 + 8 * i;
                                 int sy = mb_y * 16 + 8;
                                 int xy = (mb_x * 2 + i + mb_y * 2 * mv_stride) << (mv_sample_log2 - 1);
-                                int mx = pict->motion_val[direction][xy][0] >> shift;
-                                int my = pict->motion_val[direction][xy][1] >> shift;
+                                int mx = p->motion_val[direction][xy][0] >> shift;
+                                int my = p->motion_val[direction][xy][1] >> shift;
 
-                                if (IS_INTERLACED(pict->mb_type[mb_index]))
+                                if (IS_INTERLACED(p->mb_type[mb_index]))
                                     my *= 2;
 
                                 draw_arrow(ptr, sx, sy, mx + sx, my + sy, width,
@@ -1983,14 +2094,14 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
                               int sx = mb_x * 16 + 8;
                               int sy = mb_y * 16 + 8;
                               int xy = (mb_x + mb_y * mv_stride) << mv_sample_log2;
-                              int mx = pict->motion_val[direction][xy][0] >> shift + sx;
-                              int my = pict->motion_val[direction][xy][1] >> shift + sy;
+                              int mx = p->motion_val[direction][xy][0] >> shift + sx;
+                              int my = p->motion_val[direction][xy][1] >> shift + sy;
                               draw_arrow(ptr, sx, sy, mx, my, width, height, s->linesize, 100);
                         }
                     }
                 }
-                if ((s->avctx->debug & FF_DEBUG_VIS_QP) && pict->motion_val) {
-                    uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) *
+                if ((s->avctx->debug & FF_DEBUG_VIS_QP) && p->motion_val) {
+                    uint64_t c = (p->qscale_table[mb_index] * 128 / 31) *
                                  0x0101010101010101ULL;
                     int y;
                     for (y = 0; y < block_height; y++) {
@@ -2003,8 +2114,8 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
                     }
                 }
                 if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&
-                    pict->motion_val) {
-                    int mb_type = pict->mb_type[mb_index];
+                    p->motion_val) {
+                    int mb_type = p->mb_type[mb_index];
                     uint64_t u,v;
                     int y;
 #define COLOR(theta, r) \
@@ -2068,7 +2179,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
                             int xy = (mb_x * 2 + (i & 1) +
                                      (mb_y * 2 + (i >> 1)) * mv_stride) << (mv_sample_log2 - 1);
                             // FIXME bidir
-                            int32_t *mv = (int32_t *) &pict->motion_val[0][xy];
+                            int32_t *mv = (int32_t *) &p->motion_val[0][xy];
                             if (mv[0] != mv[dm] ||
                                 mv[dm * mv_stride] != mv[dm * (mv_stride + 1)])
                                 for (y = 0; y < 8; y++)
@@ -2209,20 +2320,18 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
     }
 
     if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
-       /* save DCT coefficients */
+       /* print DCT coefficients */
        int i,j;
-       int16_t *dct = &s->current_picture.f.dct_coeff[mb_xy * 64 * 6];
        av_log(s->avctx, AV_LOG_DEBUG, "DCT coeffs of MB at %dx%d:\n", s->mb_x, s->mb_y);
        for(i=0; i<6; i++){
            for(j=0; j<64; j++){
-               *dct++ = block[i][s->dsp.idct_permutation[j]];
-               av_log(s->avctx, AV_LOG_DEBUG, "%5d", dct[-1]);
+               av_log(s->avctx, AV_LOG_DEBUG, "%5d", block[i][s->dsp.idct_permutation[j]]);
            }
            av_log(s->avctx, AV_LOG_DEBUG, "\n");
        }
     }
 
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    s->current_picture.qscale_table[mb_xy] = s->qscale;
 
     /* update DC predictors for P macroblocks */
     if (!s->mb_intra) {
@@ -2257,7 +2366,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
                 s->mb_skipped= 0;
                 assert(s->pict_type!=AV_PICTURE_TYPE_I);
                 *mbskip_ptr = 1;
-            } else if(!s->current_picture.f.reference) {
+            } else if(!s->current_picture.reference) {
                 *mbskip_ptr = 1;
             } else{
                 *mbskip_ptr = 0; /* not skipped */
@@ -2284,12 +2393,12 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
 
                 if(HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) {
                     if (s->mv_dir & MV_DIR_FORWARD) {
-                        ff_thread_await_progress(&s->last_picture_ptr->f,
+                        ff_thread_await_progress(&s->last_picture_ptr->tf,
                                                  ff_MPV_lowest_referenced_row(s, 0),
                                                  0);
                     }
                     if (s->mv_dir & MV_DIR_BACKWARD) {
-                        ff_thread_await_progress(&s->next_picture_ptr->f,
+                        ff_thread_await_progress(&s->next_picture_ptr->tf,
                                                  ff_MPV_lowest_referenced_row(s, 1),
                                                  0);
                     }
@@ -2459,7 +2568,7 @@ void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
     if (!avctx->hwaccel &&
         !(avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) &&
         draw_edges &&
-        cur->f.reference &&
+        cur->reference &&
         !(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
         int *linesize = cur->f.linesize;
         int sides = 0, edge_h;
@@ -2595,12 +2704,8 @@ void ff_mpeg_flush(AVCodecContext *avctx){
     if(s==NULL || s->picture==NULL)
         return;
 
-    for(i=0; i<s->picture_count; i++){
-       if (s->picture[i].f.data[0] &&
-           (s->picture[i].f.type == FF_BUFFER_TYPE_INTERNAL ||
-            s->picture[i].f.type == FF_BUFFER_TYPE_USER))
-        free_frame_buffer(s, &s->picture[i]);
-    }
+    for (i = 0; i < MAX_PICTURE_COUNT; i++)
+        ff_mpeg_unref_picture(s, &s->picture[i]);
     s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL;
 
     s->mb_x= s->mb_y= 0;
@@ -2853,7 +2958,7 @@ void ff_set_qscale(MpegEncContext * s, int qscale)
 void ff_MPV_report_decode_progress(MpegEncContext *s)
 {
     if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->er.error_occurred)
-        ff_thread_report_progress(&s->current_picture_ptr->f, s->mb_y, 0);
+        ff_thread_report_progress(&s->current_picture_ptr->tf, s->mb_y, 0);
 }
 
 #if CONFIG_ERROR_RESILIENCE
index 532a70a43e1d879ffefd9d0167c3c1c8329209a3..51c7495a04a38898b4e9eaedd83b1107641b9447 100644 (file)
@@ -37,6 +37,7 @@
 #include "parser.h"
 #include "mpeg12data.h"
 #include "rl.h"
+#include "thread.h"
 #include "videodsp.h"
 
 #include "libavutil/opt.h"
@@ -94,10 +95,38 @@ struct MpegEncContext;
  */
 typedef struct Picture{
     struct AVFrame f;
+    ThreadFrame tf;
+
+    AVBufferRef *qscale_table_buf;
+    int8_t *qscale_table;
+
+    AVBufferRef *motion_val_buf[2];
+    int16_t (*motion_val[2])[2];
+
+    AVBufferRef *mb_type_buf;
+    uint32_t *mb_type;
+
+    AVBufferRef *mbskip_table_buf;
+    uint8_t *mbskip_table;
+
+    AVBufferRef *ref_index_buf[2];
+    int8_t *ref_index[2];
+
+    AVBufferRef *mb_var_buf;
+    uint16_t *mb_var;           ///< Table for MB variances
+
+    AVBufferRef *mc_mb_var_buf;
+    uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
+
+    AVBufferRef *mb_mean_buf;
+    uint8_t *mb_mean;           ///< Table for MB luminance
+
+    AVBufferRef *hwaccel_priv_buf;
+    /**
+     * hardware accelerator private data
+     */
+    void *hwaccel_picture_private;
 
-    int8_t *qscale_table_base;
-    int16_t (*motion_val_base[2])[2];
-    uint32_t *mb_type_base;
 #define MB_TYPE_INTRA MB_TYPE_INTRA4x4 //default mb_type if there is just one type
 #define IS_INTRA4x4(a)   ((a)&MB_TYPE_INTRA4x4)
 #define IS_INTRA16x16(a) ((a)&MB_TYPE_INTRA16x16)
@@ -137,16 +166,12 @@ typedef struct Picture{
 
     int mb_var_sum;             ///< sum of MB variance for current frame
     int mc_mb_var_sum;          ///< motion compensated MB variance for current frame
-    uint16_t *mb_var;           ///< Table for MB variances
-    uint16_t *mc_mb_var;        ///< Table for motion compensated MB variances
-    uint8_t *mb_mean;           ///< Table for MB luminance
+
     int b_frame_score;          /* */
-    void *owner2;               ///< pointer to the context that allocated this picture
     int needs_realloc;          ///< Picture needs to be reallocated (eg due to a frame size change)
-    /**
-     * hardware accelerator private data
-     */
-    void *hwaccel_picture_private;
+
+    int reference;
+    int shared;
 } Picture;
 
 /**
@@ -315,8 +340,6 @@ typedef struct MpegEncContext {
     Picture *last_picture_ptr;     ///< pointer to the previous picture.
     Picture *next_picture_ptr;     ///< pointer to the next picture (for bidir pred)
     Picture *current_picture_ptr;  ///< pointer to the current picture
-    int picture_count;             ///< number of allocated pictures (MAX_PICTURE_COUNT * avctx->thread_count)
-    int picture_range_start, picture_range_end; ///< the part of picture that this context can allocate in
     uint8_t *visualization_buffer[3]; ///< temporary buffer vor MV visualization
     int last_dc[3];                ///< last DC values for MPEG1
     int16_t *dc_val_base;
@@ -705,7 +728,7 @@ typedef struct MpegEncContext {
 
 #define REBASE_PICTURE(pic, new_ctx, old_ctx)             \
     ((pic && pic >= old_ctx->picture &&                   \
-      pic < old_ctx->picture + old_ctx->picture_count) ?  \
+      pic < old_ctx->picture + MAX_PICTURE_COUNT) ?  \
         &new_ctx->picture[pic - old_ctx->picture] : NULL)
 
 /* mpegvideo_enc common options */
@@ -770,7 +793,7 @@ void ff_draw_horiz_band(AVCodecContext *avctx, DSPContext *dsp, Picture *cur,
                         int v_edge_pos, int h_edge_pos);
 void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h);
 void ff_mpeg_flush(AVCodecContext *avctx);
-void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
+void ff_print_debug_info(MpegEncContext *s, Picture *p);
 void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix);
 void ff_release_unused_pictures(MpegEncContext *s, int remove_current);
 int ff_find_unused_picture(MpegEncContext *s, int shared);
@@ -790,7 +813,6 @@ void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][6
 int ff_dct_quantize_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow);
 
 void ff_init_block_index(MpegEncContext *s);
-void ff_copy_picture(Picture *dst, Picture *src);
 
 void ff_MPV_motion(MpegEncContext *s,
                    uint8_t *dest_y, uint8_t *dest_cb,
@@ -917,4 +939,7 @@ void ff_wmv2_encode_mb(MpegEncContext * s,
                        int16_t block[6][64],
                        int motion_x, int motion_y);
 
+int ff_mpeg_ref_picture(MpegEncContext *s, Picture *dst, Picture *src);
+void ff_mpeg_unref_picture(MpegEncContext *s, Picture *picture);
+
 #endif /* AVCODEC_MPEGVIDEO_H */
index bf094e6be179e6c0fd90a240cbe375a839b6d7b1..96e2c73b71528456bc7ba3671b8f778499779e93 100644 (file)
@@ -177,7 +177,7 @@ void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix)
  */
 void ff_init_qscale_tab(MpegEncContext *s)
 {
-    int8_t * const qscale_table = s->current_picture.f.qscale_table;
+    int8_t * const qscale_table = s->current_picture.qscale_table;
     int i;
 
     for (i = 0; i < s->mb_num; i++) {
@@ -871,9 +871,9 @@ static int get_intra_count(MpegEncContext *s, uint8_t *src,
 
 static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
 {
-    AVFrame *pic = NULL;
+    Picture *pic = NULL;
     int64_t pts;
-    int i, display_picture_number = 0;
+    int i, display_picture_number = 0, ret;
     const int encoding_delay = s->max_b_frames ? s->max_b_frames :
                                                  (s->low_delay ? 0 : 1);
     int direct = 1;
@@ -912,7 +912,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
     }
 
     if (pic_arg) {
-        if (encoding_delay && !(s->flags & CODEC_FLAG_INPUT_PRESERVED))
+        if (!pic_arg->buf[0]);
             direct = 0;
         if (pic_arg->linesize[0] != s->linesize)
             direct = 0;
@@ -929,14 +929,12 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
             if (i < 0)
                 return i;
 
-            pic = &s->picture[i].f;
+            pic = &s->picture[i];
             pic->reference = 3;
 
-            for (i = 0; i < 4; i++) {
-                pic->data[i]     = pic_arg->data[i];
-                pic->linesize[i] = pic_arg->linesize[i];
-            }
-            if (ff_alloc_picture(s, (Picture *) pic, 1) < 0) {
+            if ((ret = av_frame_ref(&pic->f, pic_arg)) < 0)
+                return ret;
+            if (ff_alloc_picture(s, pic, 1) < 0) {
                 return -1;
             }
         } else {
@@ -944,16 +942,16 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
             if (i < 0)
                 return i;
 
-            pic = &s->picture[i].f;
+            pic = &s->picture[i];
             pic->reference = 3;
 
-            if (ff_alloc_picture(s, (Picture *) pic, 0) < 0) {
+            if (ff_alloc_picture(s, pic, 0) < 0) {
                 return -1;
             }
 
-            if (pic->data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
-                pic->data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
-                pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
+            if (pic->f.data[0] + INPLACE_OFFSET == pic_arg->data[0] &&
+                pic->f.data[1] + INPLACE_OFFSET == pic_arg->data[1] &&
+                pic->f.data[2] + INPLACE_OFFSET == pic_arg->data[2]) {
                 // empty
             } else {
                 int h_chroma_shift, v_chroma_shift;
@@ -969,7 +967,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
                     int w = s->width  >> h_shift;
                     int h = s->height >> v_shift;
                     uint8_t *src = pic_arg->data[i];
-                    uint8_t *dst = pic->data[i];
+                    uint8_t *dst = pic->f.data[i];
 
                     if (!s->avctx->rc_buffer_size)
                         dst += INPLACE_OFFSET;
@@ -986,9 +984,9 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
                 }
             }
         }
-        copy_picture_attributes(s, pic, pic_arg);
-        pic->display_picture_number = display_picture_number;
-        pic->pts = pts; // we set this here to avoid modifiying pic_arg
+        copy_picture_attributes(s, &pic->f, pic_arg);
+        pic->f.display_picture_number = display_picture_number;
+        pic->f.pts = pts; // we set this here to avoid modifiying pic_arg
     }
 
     /* shift buffer entries */
@@ -1011,7 +1009,7 @@ static int skip_check(MpegEncContext *s, Picture *p, Picture *ref)
         const int bw = plane ? 1 : 2;
         for (y = 0; y < s->mb_height * bw; y++) {
             for (x = 0; x < s->mb_width * bw; x++) {
-                int off = p->f.type == FF_BUFFER_TYPE_SHARED ? 0 : 16;
+                int off = p->shared ? 0 : 16;
                 uint8_t *dptr = p->f.data[plane] + 8 * (x + y * stride) + off;
                 uint8_t *rptr = ref->f.data[plane] + 8 * (x + y * stride);
                 int v   = s->dsp.frame_skip_cmp[1](s, dptr, rptr, stride, 8);
@@ -1107,7 +1105,7 @@ static int estimate_best_b_count(MpegEncContext *s)
         if (pre_input_ptr && (!i || s->input_picture[i - 1])) {
             pre_input = *pre_input_ptr;
 
-            if (pre_input.f.type != FF_BUFFER_TYPE_SHARED && i) {
+            if (!pre_input.shared && i) {
                 pre_input.f.data[0] += INPLACE_OFFSET;
                 pre_input.f.data[1] += INPLACE_OFFSET;
                 pre_input.f.data[2] += INPLACE_OFFSET;
@@ -1178,7 +1176,7 @@ static int estimate_best_b_count(MpegEncContext *s)
 
 static int select_input_picture(MpegEncContext *s)
 {
-    int i;
+    int i, ret;
 
     for (i = 1; i < MAX_PICTURE_COUNT; i++)
         s->reordered_input_picture[i - 1] = s->reordered_input_picture[i];
@@ -1199,17 +1197,7 @@ static int select_input_picture(MpegEncContext *s)
                 if (s->picture_in_gop_number < s->gop_size &&
                     skip_check(s, s->input_picture[0], s->next_picture_ptr)) {
                     // FIXME check that te gop check above is +-1 correct
-                    if (s->input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED) {
-                        for (i = 0; i < 4; i++)
-                            s->input_picture[0]->f.data[i] = NULL;
-                        s->input_picture[0]->f.type = 0;
-                    } else {
-                        assert(s->input_picture[0]->f.type == FF_BUFFER_TYPE_USER ||
-                               s->input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL);
-
-                        s->avctx->release_buffer(s->avctx,
-                                                 &s->input_picture[0]->f);
-                    }
+                    av_frame_unref(&s->input_picture[0]->f);
 
                     emms_c();
                     ff_vbv_update(s, 0);
@@ -1313,14 +1301,15 @@ static int select_input_picture(MpegEncContext *s)
     }
 no_output_pic:
     if (s->reordered_input_picture[0]) {
-        s->reordered_input_picture[0]->f.reference =
+        s->reordered_input_picture[0]->reference =
            s->reordered_input_picture[0]->f.pict_type !=
                AV_PICTURE_TYPE_B ? 3 : 0;
 
-        ff_copy_picture(&s->new_picture, s->reordered_input_picture[0]);
+        ff_mpeg_unref_picture(s, &s->new_picture);
+        if ((ret = ff_mpeg_ref_picture(s, &s->new_picture, s->reordered_input_picture[0])))
+            return ret;
 
-        if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_SHARED ||
-            s->avctx->rc_buffer_size) {
+        if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) {
             // input is a shared pix, so we can't modifiy it -> alloc a new
             // one & ensure that the shared one is reuseable
 
@@ -1330,41 +1319,34 @@ no_output_pic:
                 return i;
             pic = &s->picture[i];
 
-            pic->f.reference = s->reordered_input_picture[0]->f.reference;
+            pic->reference = s->reordered_input_picture[0]->reference;
             if (ff_alloc_picture(s, pic, 0) < 0) {
                 return -1;
             }
 
-            /* mark us unused / free shared pic */
-            if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL)
-                s->avctx->release_buffer(s->avctx,
-                                         &s->reordered_input_picture[0]->f);
-            for (i = 0; i < 4; i++)
-                s->reordered_input_picture[0]->f.data[i] = NULL;
-            s->reordered_input_picture[0]->f.type = 0;
-
             copy_picture_attributes(s, &pic->f,
                                     &s->reordered_input_picture[0]->f);
 
+            /* mark us unused / free shared pic */
+            av_frame_unref(&s->reordered_input_picture[0]->f);
+            s->reordered_input_picture[0]->shared = 0;
+
             s->current_picture_ptr = pic;
         } else {
             // input is not a shared pix -> reuse buffer for current_pix
-
-            assert(s->reordered_input_picture[0]->f.type ==
-                       FF_BUFFER_TYPE_USER ||
-                   s->reordered_input_picture[0]->f.type ==
-                       FF_BUFFER_TYPE_INTERNAL);
-
             s->current_picture_ptr = s->reordered_input_picture[0];
             for (i = 0; i < 4; i++) {
                 s->new_picture.f.data[i] += INPLACE_OFFSET;
             }
         }
-        ff_copy_picture(&s->current_picture, s->current_picture_ptr);
+        ff_mpeg_unref_picture(s, &s->current_picture);
+        if ((ret = ff_mpeg_ref_picture(s, &s->current_picture,
+                                       s->current_picture_ptr)) < 0)
+            return ret;
 
         s->picture_number = s->new_picture.f.display_picture_number;
     } else {
-        memset(&s->new_picture, 0, sizeof(Picture));
+        ff_mpeg_unref_picture(s, &s->new_picture);
     }
     return 0;
 }
@@ -1712,7 +1694,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s,
         update_qscale(s);
 
         if (!(s->mpv_flags & FF_MPV_FLAG_QP_RD)) {
-            s->qscale = s->current_picture_ptr->f.qscale_table[mb_xy];
+            s->qscale = s->current_picture_ptr->qscale_table[mb_xy];
             s->dquant = s->qscale - last_qp;
 
             if (s->out_format == FMT_H263) {
@@ -2586,8 +2568,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     s->mv_type = MV_TYPE_8X8;
                     s->mb_intra= 0;
                     for(i=0; i<4; i++){
-                        s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-                        s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
+                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                     }
                     encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb,
                                  &dmin, &next_block, 0, 0);
@@ -2773,7 +2755,7 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     }
                 }
 
-                s->current_picture.f.qscale_table[xy] = best_s.qscale;
+                s->current_picture.qscale_table[xy] = best_s.qscale;
 
                 copy_context_after_encode(s, &best_s, -1);
 
@@ -2840,8 +2822,8 @@ static int encode_thread(AVCodecContext *c, void *arg){
                     s->mv_type = MV_TYPE_8X8;
                     s->mb_intra= 0;
                     for(i=0; i<4; i++){
-                        s->mv[0][i][0] = s->current_picture.f.motion_val[0][s->block_index[i]][0];
-                        s->mv[0][i][1] = s->current_picture.f.motion_val[0][s->block_index[i]][1];
+                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
+                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                     }
                     break;
                 case CANDIDATE_MB_TYPE_DIRECT:
index 24507a457565d0b0626a947752118d151a9936d5..0c86cfdafe645962678784df336315e629b66eaf 100644 (file)
@@ -640,7 +640,7 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s,
 
     if(!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B){
         LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
-        AVFrame *cur_frame = &s->current_picture.f;
+        Picture *cur_frame = &s->current_picture;
         const int xy= s->mb_x + s->mb_y*s->mb_stride;
         const int mot_stride= s->b8_stride;
         const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
index 6ebc3078351574f97087b8fd0dd048d3fa509e08..e95c91ff3adc7a08e87cc2a4a90a51bb02c4ab97 100644 (file)
@@ -178,7 +178,7 @@ void ff_xvmc_decode_mb(MpegEncContext *s)
 
     // Do I need to export quant when I could not perform postprocessing?
     // Anyway, it doesn't hurt.
-    s->current_picture.f.qscale_table[mb_xy] = s->qscale;
+    s->current_picture.qscale_table[mb_xy] = s->qscale;
 
     // start of XVMC-specific code
     render = (struct xvmc_pix_fmt*)s->current_picture.f.data[2];
index aeb6f5e7e42f7717c61af74687cc319afd57a0da..e22a8e40f5b0328a5228c4f66ba9cb5f64ff3975 100644 (file)
@@ -496,7 +496,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     int cbp, code, i;
     uint8_t *coded_val;
-    uint32_t * const mb_type_ptr = &s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride];
+    uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride];
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
         if (s->use_skip_mb_code) {
index c301b0c979b89066058db30a026d1d25858eff0f..24fa523363879eb5ee54b4827e6b231a83d7de6e 100644 (file)
@@ -33,6 +33,7 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "msrledec.h"
 
 typedef struct MsrleContext {
@@ -83,9 +84,7 @@ static int msrle_decode_frame(AVCodecContext *avctx,
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -128,8 +127,10 @@ static int msrle_decode_frame(AVCodecContext *avctx,
         ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb);
     }
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -140,8 +141,7 @@ static av_cold int msrle_decode_end(AVCodecContext *avctx)
     MsrleContext *s = avctx->priv_data;
 
     /* release the last frame */
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index c9edb2e2d7d445f7e7fd00322ec4d8a6ccb3b10c..dffdde5a1509aa0ed70026d33af7500fbd129b5c 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "mss12.h"
 
 typedef struct MSS1Context {
@@ -150,10 +151,7 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     init_get_bits(&gb, buf, buf_size * 8);
     arith_init(&acoder, &gb);
 
-    ctx->pic.reference    = 3;
-    ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
-                            FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &ctx->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &ctx->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -180,8 +178,10 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     memcpy(ctx->pic.data[1], c->pal, AVPALETTE_SIZE);
     ctx->pic.palette_has_changed = pal_changed;
 
+    if ((ret = av_frame_ref(data, &ctx->pic)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = ctx->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -206,8 +206,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx)
 {
     MSS1Context * const ctx = avctx->priv_data;
 
-    if (ctx->pic.data[0])
-        avctx->release_buffer(avctx, &ctx->pic);
+    av_frame_unref(&ctx->pic);
     ff_mss12_decode_end(&ctx->ctx);
 
     return 0;
index 190a09deff4cd707795782d02d8752e5590706d8..6881f28824e60a733d03f0c39da65993b7a62466 100644 (file)
@@ -34,7 +34,6 @@
 typedef struct MSS2Context {
     VC1Context     v;
     int            split_position;
-    AVFrame        pic;
     AVFrame        last_pic;
     MSS12Context   c;
     MSS2DSPContext dsp;
@@ -470,6 +469,7 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int buf_size       = avpkt->size;
     MSS2Context *ctx = avctx->priv_data;
     MSS12Context *c  = &ctx->c;
+    AVFrame *frame   = data;
     GetBitContext gb;
     GetByteContext gB;
     ArithCoder acoder;
@@ -523,8 +523,8 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
 
     avctx->pix_fmt = is_555 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24;
-    if (ctx->pic.data[0] && ctx->pic.format != avctx->pix_fmt)
-        avctx->release_buffer(avctx, &ctx->pic);
+    if (ctx->last_pic.format != avctx->pix_fmt)
+        av_frame_unref(&ctx->last_pic);
 
     if (has_wmv9) {
         bytestream2_init(&gB, buf, buf_size + ARITH2_PADDING);
@@ -596,25 +596,15 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     if (c->mvX < 0 || c->mvY < 0) {
-        FFSWAP(AVFrame, ctx->pic, ctx->last_pic);
         FFSWAP(uint8_t *, c->pal_pic, c->last_pal_pic);
 
-        if (ctx->pic.data[0])
-            avctx->release_buffer(avctx, &ctx->pic);
-
-        ctx->pic.reference    = 3;
-        ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                                FF_BUFFER_HINTS_READABLE |
-                                FF_BUFFER_HINTS_PRESERVE |
-                                FF_BUFFER_HINTS_REUSABLE;
-
-        if ((ret = ff_get_buffer(avctx, &ctx->pic)) < 0) {
+        if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
 
         if (ctx->last_pic.data[0]) {
-            av_assert0(ctx->pic.linesize[0] == ctx->last_pic.linesize[0]);
+            av_assert0(frame->linesize[0] == ctx->last_pic.linesize[0]);
             c->last_rgb_pic = ctx->last_pic.data[0] +
                               ctx->last_pic.linesize[0] * (avctx->height - 1);
         } else {
@@ -622,28 +612,21 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             return AVERROR_INVALIDDATA;
         }
     } else {
-        if (ctx->last_pic.data[0])
-            avctx->release_buffer(avctx, &ctx->last_pic);
-
-        ctx->pic.reference    = 3;
-        ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                                FF_BUFFER_HINTS_READABLE |
-                                FF_BUFFER_HINTS_PRESERVE |
-                                FF_BUFFER_HINTS_REUSABLE;
-
-        if ((ret = avctx->reget_buffer(avctx, &ctx->pic)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, &ctx->last_pic)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
+        if ((ret = av_frame_ref(frame, &ctx->last_pic)) < 0)
+            return ret;
 
         c->last_rgb_pic = NULL;
     }
-    c->rgb_pic    = ctx->pic.data[0] +
-                    ctx->pic.linesize[0] * (avctx->height - 1);
-    c->rgb_stride = -ctx->pic.linesize[0];
+    c->rgb_pic    = frame->data[0] +
+                    frame->linesize[0] * (avctx->height - 1);
+    c->rgb_stride = -frame->linesize[0];
 
-    ctx->pic.key_frame = keyframe;
-    ctx->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    frame->key_frame = keyframe;
+    frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
 
     if (is_555) {
         bytestream2_init(&gB, buf, buf_size);
@@ -746,8 +729,14 @@ static int mss2_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (buf_size)
         av_log(avctx, AV_LOG_WARNING, "buffer not fully consumed\n");
 
+    if (c->mvX < 0 || c->mvY < 0) {
+        av_frame_unref(&ctx->last_pic);
+        ret = av_frame_ref(&ctx->last_pic, frame);
+        if (ret < 0)
+            return ret;
+    }
+
     *got_frame       = 1;
-    *(AVFrame *)data = ctx->pic;
 
     return avpkt->size;
 }
@@ -817,10 +806,7 @@ static av_cold int mss2_decode_end(AVCodecContext *avctx)
 {
     MSS2Context *const ctx = avctx->priv_data;
 
-    if (ctx->pic.data[0])
-        avctx->release_buffer(avctx, &ctx->pic);
-    if (ctx->last_pic.data[0])
-        avctx->release_buffer(avctx, &ctx->last_pic);
+    av_frame_unref(&ctx->last_pic);
 
     ff_mss12_decode_end(&ctx->c);
     av_freep(&ctx->c.pal_pic);
@@ -836,7 +822,6 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx)
     MSS12Context *c = &ctx->c;
     int ret;
     c->avctx = avctx;
-    avctx->coded_frame = &ctx->pic;
     if (ret = ff_mss12_decode_init(c, 1, &ctx->sc[0], &ctx->sc[1]))
         return ret;
     c->pal_stride   = c->mask_stride;
index 689daeee5d9ed95123d55e9811e76d37e35a76b7..fa5b99c454591936d36b630746a52ad7ad3b0f1f 100644 (file)
@@ -27,6 +27,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "dsputil.h"
+#include "internal.h"
 #include "mss34dsp.h"
 
 #define HEADER_SIZE 27
@@ -730,18 +731,16 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return buf_size;
     c->got_error = 0;
 
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
     c->pic.key_frame = keyframe;
     c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
     if (!bytestream2_get_bytes_left(&gb)) {
+        if ((ret = av_frame_ref(data, &c->pic)) < 0)
+            return ret;
         *got_frame      = 1;
-        *(AVFrame*)data = c->pic;
 
         return buf_size;
     }
@@ -798,8 +797,10 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         dst[2] += c->pic.linesize[2] * 8;
     }
 
+    if ((ret = av_frame_ref(data, &c->pic)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
 
     return buf_size;
 }
@@ -836,7 +837,6 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx)
     }
 
     avctx->pix_fmt     = AV_PIX_FMT_YUV420P;
-    avctx->coded_frame = &c->pic;
 
     init_coders(c);
 
@@ -848,8 +848,7 @@ static av_cold int mss3_decode_end(AVCodecContext *avctx)
     MSS3Context * const c = avctx->priv_data;
     int i;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(&c->pic);
     for (i = 0; i < 3; i++)
         av_freep(&c->dct_coder[i].prev_dc);
 
index f4e4d8ddb47cb589c4741c77c35839f0de409783..a74c363dda5537e1f9a628ebed1192b528174114 100644 (file)
@@ -29,6 +29,7 @@
 #include "bytestream.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "mss34dsp.h"
 #include "unary.h"
 
@@ -553,11 +554,7 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID    |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -566,7 +563,8 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                                                    : AV_PICTURE_TYPE_P;
     if (frame_type == SKIP_FRAME) {
         *got_frame      = 1;
-        *(AVFrame*)data = c->pic;
+        if ((ret = av_frame_ref(data, &c->pic)) < 0)
+            return ret;
 
         return buf_size;
     }
@@ -622,8 +620,10 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         dst[2] += c->pic.linesize[2] * 16;
     }
 
+    if ((ret = av_frame_ref(data, &c->pic)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
 
     return buf_size;
 }
@@ -649,7 +649,6 @@ static av_cold int mss4_decode_init(AVCodecContext *avctx)
     }
 
     avctx->pix_fmt     = AV_PIX_FMT_YUV444P;
-    avctx->coded_frame = &c->pic;
 
     return 0;
 }
@@ -659,8 +658,7 @@ static av_cold int mss4_decode_end(AVCodecContext *avctx)
     MSS4Context * const c = avctx->priv_data;
     int i;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(&c->pic);
     for (i = 0; i < 3; i++)
         av_freep(&c->prev_dc[i]);
     mss4_free_vlcs(c);
index 860a89311847197676c12086681e6b909e69370f..d0aee12d49bb124b6d51d78048fe38731eca92c5 100644 (file)
@@ -34,6 +34,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 #define PALETTE_COUNT 256
 #define CHECK_STREAM_PTR(n) \
@@ -292,15 +293,14 @@ static int msvideo1_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     Msvideo1Context *s = avctx->priv_data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (s->mode_8bit) {
@@ -317,8 +317,10 @@ static int msvideo1_decode_frame(AVCodecContext *avctx,
     else
         msvideo1_decode_16bit(s);
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -328,8 +330,7 @@ static av_cold int msvideo1_decode_end(AVCodecContext *avctx)
 {
     Msvideo1Context *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index d81e9fc8535fea85637e8593f6b17ce68628c9ab..68c06c2cd9b05a7253d0e28de11f4d1393096373 100644 (file)
@@ -46,7 +46,6 @@ static av_cold int mxpeg_decode_init(AVCodecContext *avctx)
 {
     MXpegDecodeContext *s = avctx->priv_data;
 
-    s->picture[0].reference = s->picture[1].reference = 3;
     s->jpg.picture_ptr      = &s->picture[0];
     return ff_mjpeg_decode_init(avctx);
 }
@@ -167,7 +166,6 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
     const uint8_t *unescaped_buf_ptr;
     int unescaped_buf_size;
     int start_code;
-    AVFrame *picture = data;
     int ret;
 
     buf_ptr = buf;
@@ -248,9 +246,9 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
                         break;
                     }
                     /* use stored SOF data to allocate current picture */
-                    if (jpg->picture_ptr->data[0])
-                        avctx->release_buffer(avctx, jpg->picture_ptr);
-                    if (ff_get_buffer(avctx, jpg->picture_ptr) < 0) {
+                    av_frame_unref(jpg->picture_ptr);
+                    if (ff_get_buffer(avctx, jpg->picture_ptr,
+                                      AV_GET_BUFFER_FLAG_REF) < 0) {
                         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                         return AVERROR(ENOMEM);
                     }
@@ -269,7 +267,8 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
 
                     /* allocate dummy reference picture if needed */
                     if (!reference_ptr->data[0] &&
-                        ff_get_buffer(avctx, reference_ptr) < 0) {
+                        ff_get_buffer(avctx, reference_ptr,
+                                      AV_GET_BUFFER_FLAG_REF) < 0) {
                         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                         return AVERROR(ENOMEM);
                     }
@@ -293,8 +292,11 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
 
 the_end:
     if (jpg->got_picture) {
+        int ret = av_frame_ref(data, jpg->picture_ptr);
+        if (ret < 0)
+            return ret;
         *got_frame = 1;
-        *picture = *jpg->picture_ptr;
+
         s->picture_index ^= 1;
         jpg->picture_ptr = &s->picture[s->picture_index];
 
@@ -318,10 +320,8 @@ static av_cold int mxpeg_decode_end(AVCodecContext *avctx)
     jpg->picture_ptr = NULL;
     ff_mjpeg_decode_end(avctx);
 
-    for (i = 0; i < 2; ++i) {
-        if (s->picture[i].data[0])
-            avctx->release_buffer(avctx, &s->picture[i]);
-    }
+    for (i = 0; i < 2; ++i)
+        av_frame_unref(&s->picture[i]);
 
     av_freep(&s->mxm_bitmask);
     av_freep(&s->completion_bitmask);
index d78916b1c97363e2e97c3f4bd4ee2f606b5ef11f..cfd0709f0a5d2f472474beb5e208e956bda2a3b2 100644 (file)
@@ -166,7 +166,7 @@ static int decode_tag(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = NELLY_SAMPLES * blocks;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 193bed6e71bc004561e7f454e08c1e995fd0a4fd..4d5063fad7ff9843d7d21bca8787949f98ad3dd2 100644 (file)
@@ -27,6 +27,7 @@
 #include "libavutil/lzo.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "rtjpeg.h"
 
 typedef struct {
@@ -220,14 +221,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         buf_size -= RTJPEG_HEADER_SIZE;
     }
 
-    if (keyframe && c->pic.data[0]) {
-        avctx->release_buffer(avctx, &c->pic);
+    if (keyframe) {
+        av_frame_unref(&c->pic);
         init_frame = 1;
     }
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID    | FF_BUFFER_HINTS_READABLE |
-                          FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    result = avctx->reget_buffer(avctx, &c->pic);
+
+    result = ff_reget_buffer(avctx, &c->pic);
     if (result < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return result;
@@ -269,7 +268,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    *picture   = c->pic;
+    if ((result = av_frame_ref(picture, &c->pic)) < 0)
+        return result;
+
     *got_frame = 1;
     return orig_size;
 }
@@ -304,8 +305,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
     NuvContext *c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(&c->pic);
 
     return 0;
 }
index fc2a18422100dab398a7d2b0ab5c1cd6996b46a4..d140552711d0a0df174b58b088811f8bdba473dd 100644 (file)
@@ -88,8 +88,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
     av_opt_set_defaults(s);
 
     s->time_base           = (AVRational){0,1};
-    s->get_buffer          = avcodec_default_get_buffer;
-    s->release_buffer      = avcodec_default_release_buffer;
+    s->get_buffer2         = avcodec_default_get_buffer2;
     s->get_format          = avcodec_default_get_format;
     s->execute             = avcodec_default_execute;
     s->execute2            = avcodec_default_execute2;
@@ -97,7 +96,6 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
     s->pix_fmt             = AV_PIX_FMT_NONE;
     s->sample_fmt          = AV_SAMPLE_FMT_NONE;
 
-    s->reget_buffer        = avcodec_default_reget_buffer;
     s->reordered_opaque    = AV_NOPTS_VALUE;
     if(codec && codec->priv_data_size){
         if(!s->priv_data){
index 7d0795a5805bfc64a663c2abf9c537fee515db15..28ce352628c4aab316924c44e9b905bf03c5fecf 100644 (file)
@@ -403,6 +403,7 @@ static const AVOption options[]={
 {"s32p", "32-bit signed integer planar",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
 {"fltp", "32-bit float planar",           0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
 {"dblp", "64-bit double planar",          0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|D },
 {NULL},
 };
 
index 41bcb3e39518d7a44d40faf0bfec7497d06764c9..e13e2b06c3ce6c5353c672be8f7ac43debc2cbc1 100644 (file)
@@ -152,7 +152,7 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = samples;
-    if ((retval = ff_get_buffer(avctx, frame)) < 0) {
+    if ((retval = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return retval;
     }
index 64a230ae03067c95fa9f03ae2df5266c8d0c9c11..c56a95e3b55d4d256fdf11a6c5927a3953dd7ca0 100644 (file)
@@ -299,7 +299,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = n * samples_per_block / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 04770a9ad24a815d9ce59133f6349e8427d88be9..949ea1ca70431bca3d38bd33423cb445be973ba8 100644 (file)
 #include "get_bits.h"
 #include "internal.h"
 
-typedef struct PCXContext {
-    AVFrame picture;
-} PCXContext;
-
-static av_cold int pcx_init(AVCodecContext *avctx) {
-    PCXContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
-
-    return 0;
-}
-
 /**
  * @return advanced src pointer
  */
@@ -81,9 +68,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt) {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
-    PCXContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = data;
     int compressed, xmin, ymin, xmax, ymax;
     unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x,
                  bytes_per_scanline;
@@ -141,14 +126,11 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     buf += 128;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
     if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
         return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -230,7 +212,6 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         pcx_palette(&palette, (uint32_t *) p->data[1], 16);
     }
 
-    *picture = s->picture;
     *got_frame = 1;
 
     ret = buf - bufstart;
@@ -239,22 +220,10 @@ end:
     return ret;
 }
 
-static av_cold int pcx_end(AVCodecContext *avctx) {
-    PCXContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_pcx_decoder = {
     .name           = "pcx",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PCX,
-    .priv_data_size = sizeof(PCXContext),
-    .init           = pcx_init,
-    .close          = pcx_end,
     .decode         = pcx_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"),
index 16f930730b7ebf74298c963a63f01cdc7325cb51..322d3d4ad2ed97e049d2aa41508af492192c59dc 100644 (file)
 #include "internal.h"
 
 typedef struct PicContext {
-    AVFrame frame;
     int width, height;
     int nb_planes;
     GetByteContext g;
 } PicContext;
 
-static void picmemset_8bpp(PicContext *s, int value, int run, int *x, int *y)
+static void picmemset_8bpp(PicContext *s, AVFrame *frame, int value, int run,
+                           int *x, int *y)
 {
     while (run > 0) {
-        uint8_t *d = s->frame.data[0] + *y * s->frame.linesize[0];
+        uint8_t *d = frame->data[0] + *y * frame->linesize[0];
         if (*x + run >= s->width) {
             int n = s->width - *x;
             memset(d + *x, value, n);
@@ -57,7 +57,7 @@ static void picmemset_8bpp(PicContext *s, int value, int run, int *x, int *y)
     }
 }
 
-static void picmemset(PicContext *s, int value, int run,
+static void picmemset(PicContext *s, AVFrame *frame, int value, int run,
                       int *x, int *y, int *plane, int bits_per_plane)
 {
     uint8_t *d;
@@ -68,7 +68,7 @@ static void picmemset(PicContext *s, int value, int run,
     while (run > 0) {
         int j;
         for (j = 8-bits_per_plane; j >= 0; j -= bits_per_plane) {
-            d = s->frame.data[0] + *y * s->frame.linesize[0];
+            d = frame->data[0] + *y * frame->linesize[0];
             d[*x] |= (value >> j) & mask;
             *x += 1;
             if (*x == s->width) {
@@ -102,9 +102,10 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     PicContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     uint32_t *palette;
     int bits_per_plane, bpp, etype, esize, npal, pos_after_pal;
-    int i, x, y, plane, tmp;
+    int i, x, y, plane, tmp, ret;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
 
@@ -143,20 +144,18 @@ static int decode_frame(AVCodecContext *avctx,
         if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
             return -1;
         avcodec_set_dimensions(avctx, s->width, s->height);
-        if (s->frame.data[0])
-            avctx->release_buffer(avctx, &s->frame);
     }
 
-    if (ff_get_buffer(avctx, &s->frame) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
-    memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]);
-    s->frame.pict_type           = AV_PICTURE_TYPE_I;
-    s->frame.palette_has_changed = 1;
+    memset(frame->data[0], 0, s->height * frame->linesize[0]);
+    frame->pict_type           = AV_PICTURE_TYPE_I;
+    frame->palette_has_changed = 1;
 
     pos_after_pal = bytestream2_tell(&s->g) + esize;
-    palette = (uint32_t*)s->frame.data[1];
+    palette = (uint32_t*)frame->data[1];
     if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) {
         int idx = bytestream2_get_byte(&s->g);
         npal = 4;
@@ -225,11 +224,11 @@ static int decode_frame(AVCodecContext *avctx,
                     break;
 
                 if (bits_per_plane == 8) {
-                    picmemset_8bpp(s, val, run, &x, &y);
+                    picmemset_8bpp(s, frame, val, run, &x, &y);
                     if (y < 0)
                         break;
                 } else {
-                    picmemset(s, val, run, &x, &y, &plane, bits_per_plane);
+                    picmemset(s, frame, val, run, &x, &y, &plane, bits_per_plane);
                 }
             }
         }
@@ -239,24 +238,14 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
     return avpkt->size;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    PicContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-    return 0;
-}
-
 AVCodec ff_pictor_decoder = {
     .name           = "pictor",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PICTOR,
     .priv_data_size = sizeof(PicContext),
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"),
index b4e1faeae898ea02bbce136dd0bf54c32bdcb4b1..5b82298d227982f987aed380ccb82d0f6c96ca84 100644 (file)
@@ -37,8 +37,7 @@ typedef struct PNGDecContext {
     PNGDSPContext dsp;
 
     GetByteContext gb;
-    AVFrame picture1, picture2;
-    AVFrame *current_picture, *last_picture;
+    AVFrame *prev;
 
     int state;
     int width, height;
@@ -392,16 +391,11 @@ static int decode_frame(AVCodecContext *avctx,
     PNGDecContext * const s = avctx->priv_data;
     const uint8_t *buf      = avpkt->data;
     int buf_size            = avpkt->size;
-    AVFrame *picture        = data;
+    AVFrame *p              = data;
     uint8_t *crow_buf_base  = NULL;
-    AVFrame *p;
     uint32_t tag, length;
     int ret;
 
-    FFSWAP(AVFrame *, s->current_picture, s->last_picture);
-    avctx->coded_frame = s->current_picture;
-    p = s->current_picture;
-
     /* check signature */
     if (buf_size < 8 ||
         memcmp(buf, ff_pngsig, 8) != 0 &&
@@ -492,11 +486,8 @@ static int decode_frame(AVCodecContext *avctx,
                 } else {
                     goto fail;
                 }
-                if (p->data[0])
-                    avctx->release_buffer(avctx, p);
 
-                p->reference = 0;
-                if (ff_get_buffer(avctx, p) < 0) {
+                if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) {
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     goto fail;
                 }
@@ -597,11 +588,11 @@ static int decode_frame(AVCodecContext *avctx,
     }
  exit_loop:
      /* handle p-frames only if a predecessor frame is available */
-     if (s->last_picture->data[0] != NULL) {
+     if (s->prev->data[0]) {
          if (!(avpkt->flags & AV_PKT_FLAG_KEY)) {
             int i, j;
-            uint8_t *pd      = s->current_picture->data[0];
-            uint8_t *pd_last = s->last_picture->data[0];
+            uint8_t *pd      = p->data[0];
+            uint8_t *pd_last = s->prev->data[0];
 
             for (j = 0; j < s->height; j++) {
                 for (i = 0; i < s->width * s->bpp; i++) {
@@ -613,7 +604,10 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    *picture   = *s->current_picture;
+     av_frame_unref(s->prev);
+     if ((ret = av_frame_ref(s->prev, p)) < 0)
+         goto fail;
+
     *got_frame = 1;
 
     ret = bytestream2_tell(&s->gb);
@@ -633,10 +627,10 @@ static av_cold int png_dec_init(AVCodecContext *avctx)
 {
     PNGDecContext *s = avctx->priv_data;
 
-    s->current_picture = &s->picture1;
-    s->last_picture    = &s->picture2;
-    avcodec_get_frame_defaults(&s->picture1);
-    avcodec_get_frame_defaults(&s->picture2);
+    s->prev = av_frame_alloc();
+    if (!s->prev)
+        return AVERROR(ENOMEM);
+
     ff_pngdsp_init(&s->dsp);
 
     return 0;
@@ -646,10 +640,7 @@ static av_cold int png_dec_end(AVCodecContext *avctx)
 {
     PNGDecContext *s = avctx->priv_data;
 
-    if (s->picture1.data[0])
-        avctx->release_buffer(avctx, &s->picture1);
-    if (s->picture2.data[0])
-        avctx->release_buffer(avctx, &s->picture2);
+    av_frame_free(&s->prev);
 
     return 0;
 }
index 5f2fa4966ce7d861d2572fdb54ff60f335db0a89..9d7c68dc647244baba2b95a806653b87acd7a90c 100644 (file)
@@ -185,16 +185,6 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
     return 0;
 }
 
-av_cold int ff_pnm_end(AVCodecContext *avctx)
-{
-    PNMContext *s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 av_cold int ff_pnm_init(AVCodecContext *avctx)
 {
     PNMContext *s = avctx->priv_data;
index efba0d81834ba362d58180e2ec0b9f0c9da342b5..ec5ebdb4fe6b99ade1e7224578631f0f1f52e98c 100644 (file)
@@ -34,7 +34,6 @@ typedef struct PNMContext {
 } PNMContext;
 
 int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s);
-int ff_pnm_end(AVCodecContext *avctx);
 int ff_pnm_init(AVCodecContext *avctx);
 
 #endif /* AVCODEC_PNM_H */
index c9b873d46884d2a4ccb6b4f0c4071a78784fdb87..38056fbbe13a2de73f66c4c1e99f74898326a53b 100644 (file)
@@ -32,8 +32,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf   = avpkt->data;
     int buf_size         = avpkt->size;
     PNMContext * const s = avctx->priv_data;
-    AVFrame *picture     = data;
-    AVFrame * const p    = &s->picture;
+    AVFrame * const p    = data;
     int i, j, n, linesize, h, upgrade = 0;
     unsigned char *ptr;
     int components, sample_len, ret;
@@ -45,11 +44,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
     if ((ret = ff_pnm_decode_header(avctx, s)) < 0)
         return ret;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -226,7 +221,6 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
         }
         break;
     }
-    *picture   = s->picture;
     *got_frame = 1;
 
     return s->bytestream - s->bytestream_start;
@@ -239,8 +233,6 @@ AVCodec ff_pgm_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"),
@@ -253,8 +245,6 @@ AVCodec ff_pgmyuv_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PGMYUV,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"),
@@ -267,8 +257,6 @@ AVCodec ff_ppm_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PPM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"),
@@ -281,8 +269,6 @@ AVCodec ff_pbm_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PBM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"),
@@ -295,8 +281,6 @@ AVCodec ff_pam_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PAM,
     .priv_data_size = sizeof(PNMContext),
-    .init           = ff_pnm_init,
-    .close          = ff_pnm_end,
     .decode         = pnm_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
index f4c6b6d951cd8f2a3802cabfd92bb1fbf10cc755..27226c04ca47e76544452f5b240fcc45ac89e32e 100644 (file)
@@ -53,7 +53,7 @@ typedef struct {
 
 typedef struct {
     ProresDSPContext dsp;
-    AVFrame    picture;
+    AVFrame    *frame;
     ScanTable  scantable;
     int        scantable_type;           ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced
 
@@ -88,11 +88,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
     ff_proresdsp_init(&ctx->dsp);
 
-    avctx->coded_frame = &ctx->picture;
-    avcodec_get_frame_defaults(&ctx->picture);
-    ctx->picture.type      = AV_PICTURE_TYPE_I;
-    ctx->picture.key_frame = 1;
-
     ctx->scantable_type = -1;   // set scantable type to uninitialized
     memset(ctx->qmat_luma, 4, 64);
     memset(ctx->qmat_chroma, 4, 64);
@@ -163,10 +158,10 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
     }
 
     if (ctx->frame_type) {      /* if interlaced */
-        ctx->picture.interlaced_frame = 1;
-        ctx->picture.top_field_first  = ctx->frame_type & 1;
+        ctx->frame->interlaced_frame = 1;
+        ctx->frame->top_field_first  = ctx->frame_type & 1;
     } else {
-        ctx->picture.interlaced_frame = 0;
+        ctx->frame->interlaced_frame = 0;
     }
 
     avctx->color_primaries = buf[14];
@@ -247,8 +242,8 @@ static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
 
     ctx->num_x_mbs = (avctx->width + 15) >> 4;
     ctx->num_y_mbs = (avctx->height +
-                      (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
-                     (4 + ctx->picture.interlaced_frame);
+                      (1 << (4 + ctx->frame->interlaced_frame)) - 1) >>
+                     (4 + ctx->frame->interlaced_frame);
 
     remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
     num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
@@ -482,7 +477,7 @@ static int decode_slice(AVCodecContext *avctx, void *tdata)
     int mbs_per_slice = td->slice_width;
     const uint8_t *buf;
     uint8_t *y_data, *u_data, *v_data;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = ctx->frame;
     int i, sf, slice_width_factor;
     int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
     int y_linesize, u_linesize, v_linesize;
@@ -606,11 +601,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     ProresContext *ctx = avctx->priv_data;
-    AVFrame *picture   = avctx->coded_frame;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int frame_hdr_size, pic_num, pic_data_size;
 
+    ctx->frame            = data;
+    ctx->frame->pict_type = AV_PICTURE_TYPE_I;
+    ctx->frame->key_frame = 1;
+
     /* check frame atom container */
     if (buf_size < 28 || buf_size < AV_RB32(buf) ||
         AV_RB32(buf + 4) != FRAME_ID) {
@@ -626,14 +624,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     MOVE_DATA_PTR(frame_hdr_size);
 
-    if (picture->data[0])
-        avctx->release_buffer(avctx, picture);
-
-    picture->reference = 0;
-    if (ff_get_buffer(avctx, picture) < 0)
+    if (ff_get_buffer(avctx, ctx->frame, 0) < 0)
         return -1;
 
-    for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
+    for (pic_num = 0; ctx->frame->interlaced_frame - pic_num + 1; pic_num++) {
         pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
         if (pic_data_size < 0)
             return AVERROR_INVALIDDATA;
@@ -644,8 +638,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         MOVE_DATA_PTR(pic_data_size);
     }
 
-    *got_frame       = 1;
-    *(AVFrame*) data = *avctx->coded_frame;
+    ctx->frame = NULL;
+    *got_frame = 1;
 
     return avpkt->size;
 }
@@ -655,9 +649,6 @@ static av_cold int decode_close(AVCodecContext *avctx)
 {
     ProresContext *ctx = avctx->priv_data;
 
-    if (ctx->picture.data[0])
-        avctx->release_buffer(avctx, &ctx->picture);
-
     av_freep(&ctx->slice_data);
 
     return 0;
index 751fca8d6d472f792e94645401f606e49739e575..280c08ed8ba4482d1c16af7f2b3c2b140b1c7232 100644 (file)
@@ -52,6 +52,7 @@
 #include "avcodec.h"
 #include "internal.h"
 #include "thread.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 
 #if HAVE_PTHREADS
@@ -80,9 +81,6 @@ typedef struct ThreadContext {
     int done;
 } ThreadContext;
 
-/// Max number of frame buffers that can be allocated when using frame threads.
-#define MAX_BUFFERS (32+1)
-
 /**
  * Context used by codec threads and stored in their AVCodecContext thread_opaque.
  */
@@ -122,16 +120,12 @@ typedef struct PerThreadContext {
      * Array of frames passed to ff_thread_release_buffer().
      * Frames are released after all threads referencing them are finished.
      */
-    AVFrame released_buffers[MAX_BUFFERS];
-    int     num_released_buffers;
-
-    /**
-     * Array of progress values used by ff_thread_get_buffer().
-     */
-    int     progress[MAX_BUFFERS][2];
-    uint8_t progress_used[MAX_BUFFERS];
+    AVFrame *released_buffers;
+    int  num_released_buffers;
+    int      released_buffers_allocated;
 
     AVFrame *requested_frame;       ///< AVFrame the codec passed to get_buffer()
+    int      requested_flags;       ///< flags passed to get_buffer() for requested_frame
 } PerThreadContext;
 
 /**
@@ -459,8 +453,11 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
     dst->flags          = src->flags;
 
     dst->draw_horiz_band= src->draw_horiz_band;
+    dst->get_buffer2    = src->get_buffer2;
+#if FF_API_GET_BUFFER
     dst->get_buffer     = src->get_buffer;
     dst->release_buffer = src->release_buffer;
+#endif
 
     dst->opaque   = src->opaque;
     dst->debug    = src->debug;
@@ -492,14 +489,6 @@ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src)
 #undef copy_fields
 }
 
-static void free_progress(AVFrame *f)
-{
-    PerThreadContext *p = f->owner->thread_opaque;
-    int *progress = f->thread_opaque;
-
-    p->progress_used[(progress - p->progress[0]) / 2] = 0;
-}
-
 /// Releases the buffers that this decoding thread was the last user of.
 static void release_delayed_buffers(PerThreadContext *p)
 {
@@ -509,11 +498,13 @@ static void release_delayed_buffers(PerThreadContext *p)
         AVFrame *f;
 
         pthread_mutex_lock(&fctx->buffer_mutex);
+
+        // fix extended data in case the caller screwed it up
+        av_assert0(p->avctx->codec_type == AVMEDIA_TYPE_VIDEO);
         f = &p->released_buffers[--p->num_released_buffers];
-        free_progress(f);
-        f->thread_opaque = NULL;
+        f->extended_data = f->data;
+        av_frame_unref(f);
 
-        f->owner->release_buffer(f->owner, f);
         pthread_mutex_unlock(&fctx->buffer_mutex);
     }
 }
@@ -567,15 +558,18 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
      * and it calls back to the client here.
      */
 
-    if (!p->avctx->thread_safe_callbacks &&
-         p->avctx->get_buffer != avcodec_default_get_buffer) {
+    if (!p->avctx->thread_safe_callbacks && (
+#if FF_API_GET_BUFFER
+         p->avctx->get_buffer ||
+#endif
+         p->avctx->get_buffer2 != avcodec_default_get_buffer2)) {
         while (p->state != STATE_SETUP_FINISHED && p->state != STATE_INPUT_READY) {
             pthread_mutex_lock(&p->progress_mutex);
             while (p->state == STATE_SETTING_UP)
                 pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
 
             if (p->state == STATE_GET_BUFFER) {
-                p->result = ff_get_buffer(p->avctx, p->requested_frame);
+                p->result = ff_get_buffer(p->avctx, p->requested_frame, p->requested_flags);
                 p->state  = STATE_SETTING_UP;
                 pthread_cond_signal(&p->progress_cond);
             }
@@ -637,7 +631,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
             pthread_mutex_unlock(&p->progress_mutex);
         }
 
-        *picture = p->frame;
+        av_frame_move_ref(picture, &p->frame);
         *got_picture_ptr = p->got_frame;
         picture->pkt_dts = p->avpkt.dts;
 
@@ -662,10 +656,10 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
     return (p->result >= 0) ? avpkt->size : p->result;
 }
 
-void ff_thread_report_progress(AVFrame *f, int n, int field)
+void ff_thread_report_progress(ThreadFrame *f, int n, int field)
 {
     PerThreadContext *p;
-    int *progress = f->thread_opaque;
+    int *progress = f->progress ? (int*)f->progress->data : NULL;
 
     if (!progress || progress[field] >= n) return;
 
@@ -680,10 +674,10 @@ void ff_thread_report_progress(AVFrame *f, int n, int field)
     pthread_mutex_unlock(&p->progress_mutex);
 }
 
-void ff_thread_await_progress(AVFrame *f, int n, int field)
+void ff_thread_await_progress(ThreadFrame *f, int n, int field)
 {
     PerThreadContext *p;
-    int *progress = f->thread_opaque;
+    int *progress = f->progress ? (int*)f->progress->data : NULL;
 
     if (!progress || progress[field] >= n) return;
 
@@ -760,8 +754,6 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count)
     for (i = 0; i < thread_count; i++) {
         PerThreadContext *p = &fctx->threads[i];
 
-        avcodec_default_free_buffers(p->avctx);
-
         pthread_mutex_destroy(&p->mutex);
         pthread_mutex_destroy(&p->progress_mutex);
         pthread_cond_destroy(&p->input_cond);
@@ -769,6 +761,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count)
         pthread_cond_destroy(&p->output_cond);
         av_buffer_unref(&p->avpkt.buf);
         av_freep(&p->buf);
+        av_freep(&p->released_buffers);
 
         if (i) {
             av_freep(&p->avctx->priv_data);
@@ -901,34 +894,15 @@ void ff_thread_flush(AVCodecContext *avctx)
     }
 }
 
-static int *allocate_progress(PerThreadContext *p)
-{
-    int i;
-
-    for (i = 0; i < MAX_BUFFERS; i++)
-        if (!p->progress_used[i]) break;
-
-    if (i == MAX_BUFFERS) {
-        av_log(p->avctx, AV_LOG_ERROR, "allocate_progress() overflow\n");
-        return NULL;
-    }
-
-    p->progress_used[i] = 1;
-
-    return p->progress[i];
-}
-
-int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
+int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
 {
     PerThreadContext *p = avctx->thread_opaque;
-    int *progress, err;
+    int err;
 
     f->owner = avctx;
 
-    if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
-        f->thread_opaque = NULL;
-        return ff_get_buffer(avctx, f);
-    }
+    if (!(avctx->active_thread_type & FF_THREAD_FRAME))
+        return ff_get_buffer(avctx, f->f, flags);
 
     if (p->state != STATE_SETTING_UP &&
         (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) {
@@ -936,22 +910,27 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
         return -1;
     }
 
-    pthread_mutex_lock(&p->parent->buffer_mutex);
-    f->thread_opaque = progress = allocate_progress(p);
+    if (avctx->internal->allocate_progress) {
+        int *progress;
+        f->progress = av_buffer_alloc(2 * sizeof(int));
+        if (!f->progress) {
+            return AVERROR(ENOMEM);
+        }
+        progress = (int*)f->progress->data;
 
-    if (!progress) {
-        pthread_mutex_unlock(&p->parent->buffer_mutex);
-        return -1;
+        progress[0] = progress[1] = -1;
     }
 
-    progress[0] =
-    progress[1] = -1;
-
-    if (avctx->thread_safe_callbacks ||
-        avctx->get_buffer == avcodec_default_get_buffer) {
-        err = ff_get_buffer(avctx, f);
+    pthread_mutex_lock(&p->parent->buffer_mutex);
+    if (avctx->thread_safe_callbacks || (
+#if FF_API_GET_BUFFER
+        !avctx->get_buffer &&
+#endif
+        avctx->get_buffer2 == avcodec_default_get_buffer2)) {
+        err = ff_get_buffer(avctx, f->f, flags);
     } else {
-        p->requested_frame = f;
+        p->requested_frame = f->f;
+        p->requested_flags = flags;
         p->state = STATE_GET_BUFFER;
         pthread_mutex_lock(&p->progress_mutex);
         pthread_cond_signal(&p->progress_cond);
@@ -967,41 +946,60 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
             ff_thread_finish_setup(avctx);
     }
 
-    if (err) {
-        free_progress(f);
-        f->thread_opaque = NULL;
-    }
+    if (err)
+        av_buffer_unref(&f->progress);
+
     pthread_mutex_unlock(&p->parent->buffer_mutex);
 
     return err;
 }
 
-void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
+void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
 {
     PerThreadContext *p = avctx->thread_opaque;
     FrameThreadContext *fctx;
+    AVFrame *dst, *tmp;
+    int can_direct_free = !(avctx->active_thread_type & FF_THREAD_FRAME) ||
+                          avctx->thread_safe_callbacks                   ||
+                          (
+#if FF_API_GET_BUFFER
+                           !avctx->get_buffer &&
+#endif
+                           avctx->get_buffer2 == avcodec_default_get_buffer2);
 
-    if (!f->data[0])
+    if (!f->f->data[0])
         return;
 
-    if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
-        avctx->release_buffer(avctx, f);
-        return;
-    }
+    if (avctx->debug & FF_DEBUG_BUFFERS)
+        av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
 
-    if (p->num_released_buffers >= MAX_BUFFERS) {
-        av_log(p->avctx, AV_LOG_ERROR, "too many thread_release_buffer calls!\n");
+    av_buffer_unref(&f->progress);
+    f->owner    = NULL;
+
+    if (can_direct_free) {
+        av_frame_unref(f->f);
         return;
     }
 
-    if(avctx->debug & FF_DEBUG_BUFFERS)
-        av_log(avctx, AV_LOG_DEBUG, "thread_release_buffer called on pic %p\n", f);
-
     fctx = p->parent;
     pthread_mutex_lock(&fctx->buffer_mutex);
-    p->released_buffers[p->num_released_buffers++] = *f;
+
+    if (p->num_released_buffers + 1 >= INT_MAX / sizeof(*p->released_buffers))
+        goto fail;
+    tmp = av_fast_realloc(p->released_buffers, &p->released_buffers_allocated,
+                          (p->num_released_buffers + 1) *
+                          sizeof(*p->released_buffers));
+    if (!tmp)
+        goto fail;
+    p->released_buffers = tmp;
+
+    dst = &p->released_buffers[p->num_released_buffers];
+    av_frame_move_ref(dst, f->f);
+
+    p->num_released_buffers++;
+
+fail:
     pthread_mutex_unlock(&fctx->buffer_mutex);
-    memset(f->data, 0, sizeof(f->data));
 }
 
 /**
index e8f8bdd72cfbdd205bed2342bd08a273291555d7..f5288439446fee9a3dfaf2a807f01ceb08285053 100644 (file)
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct PTXContext {
-    AVFrame picture;
-} PTXContext;
-
-static av_cold int ptx_init(AVCodecContext *avctx) {
-    PTXContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
-
-    return 0;
-}
-
 static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt) {
     const uint8_t *buf = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
-    PTXContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = data;
     unsigned int offset, w, h, y, stride, bytes_per_pixel;
     int ret;
     uint8_t *ptr;
@@ -70,14 +55,11 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     buf += offset;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
     if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
         return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -99,7 +81,6 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         buf += w*bytes_per_pixel;
     }
 
-    *picture = s->picture;
     *got_frame = 1;
 
     if (y < h) {
@@ -110,22 +91,10 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     return offset + w*h*bytes_per_pixel;
 }
 
-static av_cold int ptx_end(AVCodecContext *avctx) {
-    PTXContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_ptx_decoder = {
     .name           = "ptx",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PTX,
-    .priv_data_size = sizeof(PTXContext),
-    .init           = ptx_init,
-    .close          = ptx_end,
     .decode         = ptx_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("V.Flash PTX image"),
index 9c7855d78e1cafbce8b450ddc306c6705a19a491..e7f269913866d3a2d48395fd5b7bcec79f6d822d 100644 (file)
@@ -695,7 +695,7 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 160;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 082a64f35edafe20cad59f7b42e422d4b0617110..91ef524ad6842b7b1715ad1e3328ba0a233ce1a6 100644 (file)
@@ -1934,7 +1934,7 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 16 * s->frame_size;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 78ceca69ac6f67d13a832e91a25e1cf644ae1e56..0dc72d0daa4cabf67904d519c3f56bb2f2e2001a 100644 (file)
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct QdrawContext {
-    AVCodecContext *avctx;
-    AVFrame pic;
-} QdrawContext;
-
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         AVPacket *avpkt)
@@ -41,26 +36,21 @@ static int decode_frame(AVCodecContext *avctx,
     const uint8_t *buf     = avpkt->data;
     const uint8_t *buf_end = avpkt->data + avpkt->size;
     int buf_size           = avpkt->size;
-    QdrawContext * const a = avctx->priv_data;
-    AVFrame * const p      = &a->pic;
+    AVFrame * const p      = data;
     uint8_t* outdata;
     int colors;
     int i, ret;
     uint32_t *pal;
     int r, g, b;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
     p->pict_type = AV_PICTURE_TYPE_I;
     p->key_frame = 1;
 
-    outdata = a->pic.data[0];
+    outdata = p->data[0];
 
     if (buf_end - buf < 0x68 + 4)
         return AVERROR_INVALIDDATA;
@@ -118,14 +108,14 @@ static int decode_frame(AVCodecContext *avctx,
             code = *buf++;
             if (code & 0x80 ) { /* run */
                 pix = *buf++;
-                if ((out + (257 - code)) > (outdata +  a->pic.linesize[0]))
+                if ((out + (257 - code)) > (outdata +  p->linesize[0]))
                     break;
                 memset(out, pix, 257 - code);
                 out   += 257 - code;
                 tsize += 257 - code;
                 left  -= 2;
             } else { /* copy */
-                if ((out + code) > (outdata +  a->pic.linesize[0]))
+                if ((out + code) > (outdata +  p->linesize[0]))
                     break;
                 if (buf_end - buf < code + 1)
                     return AVERROR_INVALIDDATA;
@@ -137,11 +127,10 @@ static int decode_frame(AVCodecContext *avctx,
             }
         }
         buf = next;
-        outdata += a->pic.linesize[0];
+        outdata += p->linesize[0];
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = a->pic;
 
     return buf_size;
 }
@@ -153,24 +142,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    QdrawContext * const a = avctx->priv_data;
-    AVFrame *pic = &a->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    return 0;
-}
-
 AVCodec ff_qdraw_decoder = {
     .name           = "qdraw",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_QDRAW,
-    .priv_data_size = sizeof(QdrawContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
index c295543c3851777f204934466e7bdc443001af6b..afcb2dfc97619c1dbe5523bd21d8b3813dd5964b 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct QpegContext{
     AVCodecContext *avctx;
@@ -256,8 +257,7 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     bytestream2_init(&a->buffer, avpkt->data, avpkt->size);
-    p->reference = 3;
-    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -280,8 +280,10 @@ static int decode_frame(AVCodecContext *avctx,
     }
     memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE);
 
+    if ((ret = av_frame_ref(data, &a->pic)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = a->pic;
 
     return avpkt->size;
 }
@@ -300,8 +302,7 @@ static av_cold int decode_end(AVCodecContext *avctx){
     QpegContext * const a = avctx->priv_data;
     AVFrame * const p = &a->pic;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
+    av_frame_unref(p);
 
     av_free(a->refdata);
     return 0;
index cc31592f019a404cdf266637da2c861d4cf6258e..7a1213f6011757d4e10cac0af30cf4ec1f5ab403 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct QtrleContext {
     AVCodecContext *avctx;
@@ -400,10 +401,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
     int ret;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -487,8 +485,9 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
     }
 
 done:
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -498,8 +497,7 @@ static av_cold int qtrle_decode_end(AVCodecContext *avctx)
 {
     QtrleContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index 7fd663b9a35089acfa5beb84c1c0c9e14a0a38c7..35150d8602dcfc09980bca5a1d57cf508239e8b6 100644 (file)
@@ -30,8 +30,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     avctx->pix_fmt             = AV_PIX_FMT_RGB48;
     avctx->bits_per_raw_sample = 10;
 
-    avctx->coded_frame         = avcodec_alloc_frame();
-
     return 0;
 }
 
@@ -39,21 +37,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     int h, w, ret;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint32_t *src = (const uint32_t *)avpkt->data;
     int aligned_width = FFALIGN(avctx->width, 64);
     uint8_t *dst_line;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < 4 * aligned_width * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
         return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     pic->pict_type = AV_PICTURE_TYPE_I;
@@ -83,28 +77,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = *avctx->coded_frame;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 #if CONFIG_R210_DECODER
 AVCodec ff_r210_decoder = {
     .name           = "r210",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_R210,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
@@ -116,7 +98,6 @@ AVCodec ff_r10k_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_R10K,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
index d3c81ca6a15ffa3990c64fbc11a9a397b58377ff..e2d116c20174bdc2b0e235bff98325d6325389a7 100644 (file)
@@ -78,7 +78,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = NBLOCKS * BLOCKSIZE;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 744824ba6bdd5129df9fbc8635eb903b3ca16f1f..5cccbe9a0c1efbc2d717944a95cc7925259b69d4 100644 (file)
@@ -191,7 +191,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index b163a895abc99dcdbbf402a290ba208c4fe5bf00..91c984f083a725d7731c69921af7240d366a6561 100644 (file)
@@ -460,7 +460,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     }
 
     frame->nb_samples = ctx->max_frame_size;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Me fail get_buffer()? That's unpossible!\n");
         return ret;
     }
index ab93d49e07805518b8c87955cbccd482d72afccf..59a6dd676d454a6204e700771fa1ac6d97ae227e 100644 (file)
 
 #include "avcodec.h"
 #include "raw.h"
+#include "libavutil/buffer.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 
 typedef struct RawVideoContext {
-    uint32_t palette[AVPALETTE_COUNT];
-    unsigned char *buffer;  /* block of memory for holding one frame */
-    int            length;  /* number of bytes in buffer */
+    AVBufferRef *palette;
+    int frame_size;  /* size of the frame in bytes */
     int flip;
-    AVFrame pic;             ///< AVCodecContext.coded_frame
+    int is_2_4_bpp; // 2 or 4 bpp raw in avi/mov
+    int is_yuv2;
 } RawVideoContext;
 
 static const PixelFormatTag pix_fmt_bps_avi[] = {
@@ -77,6 +78,7 @@ static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags,
 static av_cold int raw_init_decoder(AVCodecContext *avctx)
 {
     RawVideoContext *context = avctx->priv_data;
+    const AVPixFmtDescriptor *desc;
 
     if (avctx->codec_tag == MKTAG('r', 'a', 'w', ' '))
         avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_mov,
@@ -90,20 +92,28 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx)
         avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi,
                                       avctx->bits_per_coded_sample);
 
-    avpriv_set_systematic_pal2(context->palette, avctx->pix_fmt);
-    context->length = avpicture_get_size(avctx->pix_fmt, avctx->width,
-                                         avctx->height);
-    if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
-        avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
-       (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) {
-        context->buffer = av_malloc(context->length);
-        if (!context->buffer)
-            return -1;
+    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    if (!desc) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (desc->flags & (PIX_FMT_PAL || PIX_FMT_PSEUDOPAL)) {
+        context->palette = av_buffer_alloc(AVPALETTE_SIZE);
+        if (!context->palette)
+            return AVERROR(ENOMEM);
+        if (desc->flags & PIX_FMT_PSEUDOPAL)
+            avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt);
+        else
+            memset(context->palette->data, 0, AVPALETTE_SIZE);
     }
-    context->pic.pict_type = AV_PICTURE_TYPE_I;
-    context->pic.key_frame = 1;
 
-    avctx->coded_frame = &context->pic;
+    context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width,
+                                             avctx->height);
+    if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
+        avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
+       (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' ')))
+        context->is_2_4_bpp = 1;
 
     if ((avctx->extradata_size >= 9 &&
          !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
@@ -111,6 +121,10 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx)
         avctx->codec_tag == MKTAG('W','R','A','W'))
         context->flip = 1;
 
+    if (avctx->codec_tag == AV_RL32("yuv2") &&
+        avctx->pix_fmt   == AV_PIX_FMT_YUYV422)
+        context->is_yuv2 = 1;
+
     return 0;
 }
 
@@ -127,26 +141,33 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
     RawVideoContext *context       = avctx->priv_data;
     const uint8_t *buf             = avpkt->data;
     int buf_size                   = avpkt->size;
+    int need_copy                  = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2;
     int res;
 
     AVFrame   *frame   = data;
     AVPicture *picture = data;
 
-    frame->pict_type        = avctx->coded_frame->pict_type;
-    frame->interlaced_frame = avctx->coded_frame->interlaced_frame;
-    frame->top_field_first  = avctx->coded_frame->top_field_first;
+    frame->pict_type        = AV_PICTURE_TYPE_I;
+    frame->key_frame        = 1;
     frame->reordered_opaque = avctx->reordered_opaque;
     frame->pkt_pts          = avctx->pkt->pts;
 
-    if (buf_size < context->length - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ?
-                                      AVPALETTE_SIZE : 0))
+    if (buf_size < context->frame_size - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ?
+                                          AVPALETTE_SIZE : 0))
         return -1;
 
+    if (need_copy)
+        frame->buf[0] = av_buffer_alloc(context->frame_size);
+    else
+        frame->buf[0] = av_buffer_ref(avpkt->buf);
+    if (!frame->buf[0])
+        return AVERROR(ENOMEM);
+
     //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
-    if (context->buffer) {
+    if (context->is_2_4_bpp) {
         int i;
-        uint8_t *dst = context->buffer;
-        buf_size = context->length - AVPALETTE_SIZE;
+        uint8_t *dst = frame->buf[0]->data;
+        buf_size = context->frame_size - AVPALETTE_SIZE;
         if (avctx->bits_per_coded_sample == 4) {
             for (i = 0; 2 * i + 1 < buf_size; i++) {
                 dst[2 * i + 0] = buf[i] >> 4;
@@ -161,28 +182,40 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
             }
         }
         buf = dst;
+    } else if (need_copy) {
+        memcpy(frame->buf[0]->data, buf, FFMIN(buf_size, context->frame_size));
+        buf = frame->buf[0]->data;
     }
 
     if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
         avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
-        buf += buf_size - context->length;
+        buf += buf_size - context->frame_size;
 
     if ((res = avpicture_fill(picture, buf, avctx->pix_fmt,
                               avctx->width, avctx->height)) < 0)
         return res;
-    if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->length) ||
-        (desc->flags & PIX_FMT_PSEUDOPAL)) {
-        frame->data[1] = context->palette;
-    }
+
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
                                                      NULL);
 
         if (pal) {
-            memcpy(frame->data[1], pal, AVPALETTE_SIZE);
+            av_buffer_unref(&context->palette);
+            context->palette = av_buffer_alloc(AVPALETTE_SIZE);
+            if (!context->palette)
+                return AVERROR(ENOMEM);
+            memcpy(context->palette->data, pal, AVPALETTE_SIZE);
             frame->palette_has_changed = 1;
         }
     }
+
+    if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) ||
+        (desc->flags & PIX_FMT_PSEUDOPAL)) {
+        frame->buf[1]  = av_buffer_ref(context->palette);
+        if (!frame->buf[1])
+            return AVERROR(ENOMEM);
+        frame->data[1] = frame->buf[1]->data;
+    }
     if (avctx->pix_fmt == AV_PIX_FMT_BGR24 &&
         ((frame->linesize[0] + 3) & ~3) * avctx->height <= buf_size)
         frame->linesize[0] = (frame->linesize[0] + 3) & ~3;
@@ -215,7 +248,7 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx)
 {
     RawVideoContext *context = avctx->priv_data;
 
-    av_freep(&context->buffer);
+    av_buffer_unref(&context->palette);
     return 0;
 }
 
index 9973c287368300b044273f1ba494ee2d833ff61c..4f68f7e997f51330f73bd47fa743b3eb39c4248c 100644 (file)
@@ -41,7 +41,6 @@
 
 typedef struct Rl2Context {
     AVCodecContext *avctx;
-    AVFrame frame;
 
     uint16_t video_base;  ///< initial drawing offset
     uint32_t clr_count;   ///< number of used colors (currently unused)
@@ -177,29 +176,24 @@ static int rl2_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
+    AVFrame *frame     = data;
     const uint8_t *buf = avpkt->data;
     int ret, buf_size  = avpkt->size;
     Rl2Context *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    /** get buffer */
-    s->frame.reference = 0;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     /** run length decode */
-    rl2_rle_decode(s, buf, buf_size, s->frame.data[0], s->frame.linesize[0],
+    rl2_rle_decode(s, buf, buf_size, frame->data[0], frame->linesize[0],
                    s->video_base);
 
     /** make the palette available on the way out */
-    memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
+    memcpy(frame->data[1], s->palette, AVPALETTE_SIZE);
 
     *got_frame = 1;
-    *(AVFrame*)data = s->frame;
 
     /** report that the buffer was completely consumed */
     return buf_size;
@@ -215,9 +209,6 @@ static av_cold int rl2_decode_end(AVCodecContext *avctx)
 {
     Rl2Context *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
     av_free(s->back_frame);
 
     return 0;
index 3ee62c01b5fa3a5a241c85d4a4f6826ac206c393..ef561a32105e28de078eab21bba1314ae60b3214 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "roqvideo.h"
 
 static void roqvideo_decode_frame(RoqContext *ri)
@@ -168,8 +169,15 @@ static av_cold int roq_decode_init(AVCodecContext *avctx)
 
     s->width = avctx->width;
     s->height = avctx->height;
-    s->last_frame    = &s->frames[0];
-    s->current_frame = &s->frames[1];
+
+    s->last_frame    = av_frame_alloc();
+    s->current_frame = av_frame_alloc();
+    if (!s->current_frame || !s->last_frame) {
+        av_frame_free(&s->current_frame);
+        av_frame_free(&s->last_frame);
+        return AVERROR(ENOMEM);
+    }
+
     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
 
     return 0;
@@ -183,11 +191,11 @@ static int roq_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     RoqContext *s = avctx->priv_data;
     int copy= !s->current_frame->data[0];
+    int ret;
 
-    s->current_frame->reference = 3;
-    if (avctx->reget_buffer(avctx, s->current_frame)) {
+    if ((ret = ff_reget_buffer(avctx, s->current_frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "  RoQ: get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if(copy)
@@ -197,8 +205,9 @@ static int roq_decode_frame(AVCodecContext *avctx,
     bytestream2_init(&s->gb, buf, buf_size);
     roqvideo_decode_frame(s);
 
+    if ((ret = av_frame_ref(data, s->current_frame)) < 0)
+        return ret;
     *got_frame      = 1;
-    *(AVFrame*)data = *s->current_frame;
 
     /* shuffle frames */
     FFSWAP(AVFrame *, s->current_frame, s->last_frame);
@@ -210,11 +219,8 @@ static av_cold int roq_decode_end(AVCodecContext *avctx)
 {
     RoqContext *s = avctx->priv_data;
 
-    /* release the last frame */
-    if (s->last_frame->data[0])
-        avctx->release_buffer(avctx, s->last_frame);
-    if (s->current_frame->data[0])
-        avctx->release_buffer(avctx, s->current_frame);
+    av_frame_free(&s->current_frame);
+    av_frame_free(&s->last_frame);
 
     return 0;
 }
index 192f1eb6a39c3749458b0c873b83c150c3f3762e..636418a5d9f28ed5a7a290309f8d9814d953cc8c 100644 (file)
@@ -936,6 +936,22 @@ static void roq_encode_video(RoqContext *enc)
     enc->framesSinceKeyframe++;
 }
 
+static int roq_encode_end(AVCodecContext *avctx)
+{
+    RoqContext *enc = avctx->priv_data;
+
+    av_frame_free(&enc->current_frame);
+    av_frame_free(&enc->last_frame);
+
+    av_free(enc->tmpData);
+    av_free(enc->this_motion4);
+    av_free(enc->last_motion4);
+    av_free(enc->this_motion8);
+    av_free(enc->last_motion8);
+
+    return 0;
+}
+
 static int roq_encode_init(AVCodecContext *avctx)
 {
     RoqContext *enc = avctx->priv_data;
@@ -957,8 +973,12 @@ static int roq_encode_init(AVCodecContext *avctx)
     enc->framesSinceKeyframe = 0;
     enc->first_frame = 1;
 
-    enc->last_frame    = &enc->frames[0];
-    enc->current_frame = &enc->frames[1];
+    enc->last_frame    = av_frame_alloc();
+    enc->current_frame = av_frame_alloc();
+    if (!enc->last_frame || !enc->current_frame) {
+        roq_encode_end(avctx);
+        return AVERROR(ENOMEM);
+    }
 
     enc->tmpData      = av_malloc(sizeof(RoqTempdata));
 
@@ -1033,8 +1053,8 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     if (enc->first_frame) {
         /* Alloc memory for the reconstruction data (we must know the stride
          for that) */
-        if (ff_get_buffer(avctx, enc->current_frame) ||
-            ff_get_buffer(avctx, enc->last_frame)) {
+        if (ff_get_buffer(avctx, enc->current_frame, 0) ||
+            ff_get_buffer(avctx, enc->last_frame, 0)) {
             av_log(avctx, AV_LOG_ERROR, "  RoQ: get_buffer() failed\n");
             return -1;
         }
@@ -1056,22 +1076,6 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     return 0;
 }
 
-static int roq_encode_end(AVCodecContext *avctx)
-{
-    RoqContext *enc = avctx->priv_data;
-
-    avctx->release_buffer(avctx, enc->last_frame);
-    avctx->release_buffer(avctx, enc->current_frame);
-
-    av_free(enc->tmpData);
-    av_free(enc->this_motion4);
-    av_free(enc->last_motion4);
-    av_free(enc->this_motion8);
-    av_free(enc->last_motion8);
-
-    return 0;
-}
-
 AVCodec ff_roq_encoder = {
     .name                 = "roqvideo",
     .type                 = AVMEDIA_TYPE_VIDEO,
index ee36607393fb19d4c63d7fa56597085d10835b98..dd2b547afc05ff38e3470a65dd856f29d2659bd6 100644 (file)
@@ -41,6 +41,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct RpzaContext {
 
@@ -255,17 +256,17 @@ static int rpza_decode_frame(AVCodecContext *avctx,
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
 
     rpza_decode_stream(s);
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -275,8 +276,7 @@ static av_cold int rpza_decode_end(AVCodecContext *avctx)
 {
     RpzaContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index c3e977a7606211f0d1ea21ff3b2f905c87e2b6b4..7fd4ddfa42972ef8b5b1d7a3c9372d833fea6c00 100644 (file)
@@ -644,7 +644,7 @@ static int rv10_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     MpegEncContext *s = avctx->priv_data;
-    int i;
+    int i, ret;
     AVFrame *pict = data;
     int slice_count;
     const uint8_t *slices_hdr = NULL;
@@ -701,14 +701,17 @@ static int rv10_decode_frame(AVCodecContext *avctx,
         ff_MPV_frame_end(s);
 
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            *pict = s->current_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+                return ret;
+            ff_print_debug_info(s, s->current_picture_ptr);
         } else if (s->last_picture_ptr != NULL) {
-            *pict = s->last_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+                return ret;
+            ff_print_debug_info(s, s->last_picture_ptr);
         }
 
         if(s->last_picture_ptr || s->low_delay){
             *got_frame = 1;
-            ff_print_debug_info(s, pict);
         }
         s->current_picture_ptr= NULL; // so we can detect if frame_end was not called (find some nicer solution...)
     }
index ae99a823bf1a08c10f0f108e7d5be98283cc15de..32f523b4312ec40d0903ee0c6d0241bcd8ee8b23 100644 (file)
@@ -141,7 +141,7 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
 
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        int mbtype = s->current_picture_ptr->f.mb_type[mb_pos];
+        int mbtype = s->current_picture_ptr->mb_type[mb_pos];
         if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
             r->deblock_coefs[mb_pos] = 0xFFFF;
         if(IS_INTRA(mbtype))
@@ -153,9 +153,9 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
      */
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]];
+        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]];
         if(mb_x)
-            left_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - 1]];
+            left_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - 1]];
         for(j = 0; j < 16; j += 4){
             Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize + 4 * !mb_x;
             for(i = !mb_x; i < 4; i++, Y += 4){
@@ -195,9 +195,9 @@ static void rv30_loop_filter(RV34DecContext *r, int row)
     }
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos]];
+        cur_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos]];
         if(row)
-            top_lim = rv30_loop_filt_lim[s->current_picture_ptr->f.qscale_table[mb_pos - s->mb_stride]];
+            top_lim = rv30_loop_filt_lim[s->current_picture_ptr->qscale_table[mb_pos - s->mb_stride]];
         for(j = 4*!row; j < 16; j += 4){
             Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize;
             for(i = 0; i < 4; i++, Y += 4){
index bd64a4be7ce9e2f84ec09a0015ec03ac53f41eb8..aedf417da4a6bc239570686063ed3075624e2252 100644 (file)
@@ -357,7 +357,7 @@ static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
 
     r->is16 = get_bits1(gb);
     if(r->is16){
-        s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA16x16;
+        s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA16x16;
         r->block_type = RV34_MB_TYPE_INTRA16x16;
         t = get_bits(gb, 2);
         fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
@@ -367,7 +367,7 @@ static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
             if(!get_bits1(gb))
                 av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
         }
-        s->current_picture_ptr->f.mb_type[mb_pos] = MB_TYPE_INTRA;
+        s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA;
         r->block_type = RV34_MB_TYPE_INTRA;
         if(r->decode_intra_types(r, gb, intra_types) < 0)
             return -1;
@@ -393,7 +393,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
     r->block_type = r->decode_mb_info(r);
     if(r->block_type == -1)
         return -1;
-    s->current_picture_ptr->f.mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
+    s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
     r->mb_type[mb_pos] = r->block_type;
     if(r->block_type == RV34_MB_SKIP){
         if(s->pict_type == AV_PICTURE_TYPE_P)
@@ -401,7 +401,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
         if(s->pict_type == AV_PICTURE_TYPE_B)
             r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
     }
-    r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->f.mb_type[mb_pos]);
+    r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
     rv34_decode_mv(r, r->block_type);
     if(r->block_type == RV34_MB_SKIP){
         fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
@@ -410,7 +410,7 @@ static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
     r->chroma_vlc = 1;
     r->luma_vlc   = 0;
 
-    if(IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
+    if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
         if(r->is16){
             t = get_bits(gb, 2);
             fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
@@ -475,27 +475,27 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
         c_off = -1;
 
     if(avail[-1]){
-        A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][0];
-        A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-1][1];
+        A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
+        A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
     }
     if(avail[-4]){
-        B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][0];
-        B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride][1];
+        B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
+        B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
     }else{
         B[0] = A[0];
         B[1] = A[1];
     }
     if(!avail[c_off-4]){
         if(avail[-4] && (avail[-1] || r->rv30)){
-            C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][0];
-            C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride-1][1];
+            C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
+            C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
         }else{
             C[0] = A[0];
             C[1] = A[1];
         }
     }else{
-        C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][0];
-        C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos-s->b8_stride+c_off][1];
+        C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0];
+        C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1];
     }
     mx = mid_pred(A[0], B[0], C[0]);
     my = mid_pred(A[1], B[1], C[1]);
@@ -503,8 +503,8 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
     my += r->dmv[dmv_no][1];
     for(j = 0; j < part_sizes_h[block_type]; j++){
         for(i = 0; i < part_sizes_w[block_type]; i++){
-            s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
-            s->current_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
+            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
+            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
         }
     }
 }
@@ -555,25 +555,25 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
     int i, j;
     Picture *cur_pic = s->current_picture_ptr;
     const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
-    int type = cur_pic->f.mb_type[mb_pos];
+    int type = cur_pic->mb_type[mb_pos];
 
     if((r->avail_cache[6-1] & type) & mask){
-        A[0] = cur_pic->f.motion_val[dir][mv_pos - 1][0];
-        A[1] = cur_pic->f.motion_val[dir][mv_pos - 1][1];
+        A[0] = cur_pic->motion_val[dir][mv_pos - 1][0];
+        A[1] = cur_pic->motion_val[dir][mv_pos - 1][1];
         has_A = 1;
     }
     if((r->avail_cache[6-4] & type) & mask){
-        B[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][0];
-        B[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride][1];
+        B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0];
+        B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1];
         has_B = 1;
     }
     if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
-        C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][0];
-        C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride + 2][1];
+        C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0];
+        C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1];
         has_C = 1;
     }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
-        C[0] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][0];
-        C[1] = cur_pic->f.motion_val[dir][mv_pos - s->b8_stride - 1][1];
+        C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0];
+        C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1];
         has_C = 1;
     }
 
@@ -584,12 +584,12 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
 
     for(j = 0; j < 2; j++){
         for(i = 0; i < 2; i++){
-            cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
-            cur_pic->f.motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
+            cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
+            cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
         }
     }
     if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
-        ZERO8x2(cur_pic->f.motion_val[!dir][mv_pos], s->b8_stride);
+        ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
     }
 }
 
@@ -606,27 +606,27 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
     int* avail = r->avail_cache + avail_indexes[0];
 
     if(avail[-1]){
-        A[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][0];
-        A[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - 1][1];
+        A[0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
+        A[1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
     }
     if(avail[-4]){
-        B[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][0];
-        B[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride][1];
+        B[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
+        B[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
     }else{
         B[0] = A[0];
         B[1] = A[1];
     }
     if(!avail[-4 + 2]){
         if(avail[-4] && (avail[-1])){
-            C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][0];
-            C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride - 1][1];
+            C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][0];
+            C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][1];
         }else{
             C[0] = A[0];
             C[1] = A[1];
         }
     }else{
-        C[0] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][0];
-        C[1] = s->current_picture_ptr->f.motion_val[0][mv_pos - s->b8_stride + 2][1];
+        C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][0];
+        C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][1];
     }
     mx = mid_pred(A[0], B[0], C[0]);
     my = mid_pred(A[1], B[1], C[1]);
@@ -635,8 +635,8 @@ static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
     for(j = 0; j < 2; j++){
         for(i = 0; i < 2; i++){
             for(k = 0; k < 2; k++){
-                s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
-                s->current_picture_ptr->f.motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
+                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
+                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
             }
         }
     }
@@ -674,24 +674,24 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
 
     if(thirdpel){
         int chroma_mx, chroma_my;
-        mx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
-        my = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
-        lx = (s->current_picture_ptr->f.motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
-        ly = (s->current_picture_ptr->f.motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
-        chroma_mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
-        chroma_my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
+        mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
+        my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
+        lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
+        ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
+        chroma_mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
+        chroma_my = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
         umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
         umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
         uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
         uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
     }else{
         int cx, cy;
-        mx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] >> 2;
-        my = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] >> 2;
-        lx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] & 3;
-        ly = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] & 3;
-        cx = s->current_picture_ptr->f.motion_val[dir][mv_pos][0] / 2;
-        cy = s->current_picture_ptr->f.motion_val[dir][mv_pos][1] / 2;
+        mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
+        my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
+        lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
+        ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
+        cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
+        cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
         umx = cx >> 2;
         umy = cy >> 2;
         uvmx = (cx & 3) << 1;
@@ -704,7 +704,7 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
         /* wait for the referenced mb row to be finished */
         int mb_row = s->mb_y + ((yoff + my + 5 + 8 * height) >> 4);
-        AVFrame *f = dir ? &s->next_picture_ptr->f : &s->last_picture_ptr->f;
+        ThreadFrame *f = dir ? &s->next_picture_ptr->tf : &s->last_picture_ptr->tf;
         ff_thread_await_progress(f, mb_row, 0);
     }
 
@@ -853,11 +853,11 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
     switch(block_type){
     case RV34_MB_TYPE_INTRA:
     case RV34_MB_TYPE_INTRA16x16:
-        ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+        ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
         return 0;
     case RV34_MB_SKIP:
         if(s->pict_type == AV_PICTURE_TYPE_P){
-            ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+            ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
             rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
             break;
         }
@@ -865,23 +865,23 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
         //surprisingly, it uses motion scheme from next reference frame
         /* wait for the current mb row to be finished */
         if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
-            ff_thread_await_progress(&s->next_picture_ptr->f, FFMAX(0, s->mb_y-1), 0);
+            ff_thread_await_progress(&s->next_picture_ptr->tf, FFMAX(0, s->mb_y-1), 0);
 
-        next_bt = s->next_picture_ptr->f.mb_type[s->mb_x + s->mb_y * s->mb_stride];
+        next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
         if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
-            ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
-            ZERO8x2(s->current_picture_ptr->f.motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+            ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+            ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
         }else
             for(j = 0; j < 2; j++)
                 for(i = 0; i < 2; i++)
                     for(k = 0; k < 2; k++)
                         for(l = 0; l < 2; l++)
-                            s->current_picture_ptr->f.motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->f.motion_val[0][mv_pos + i + j*s->b8_stride][k]);
+                            s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]);
         if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
             rv34_mc_2mv(r, block_type);
         else
             rv34_mc_2mv_skip(r);
-        ZERO8x2(s->current_picture_ptr->f.motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+        ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
         break;
     case RV34_MB_P_16x16:
     case RV34_MB_P_MIX16x16:
@@ -1149,7 +1149,7 @@ static int rv34_set_deblock_coef(RV34DecContext *r)
     MpegEncContext *s = &r->s;
     int hmvmask = 0, vmvmask = 0, i, j;
     int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
-    int16_t (*motion_val)[2] = &s->current_picture_ptr->f.motion_val[0][midx];
+    int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx];
     for(j = 0; j < 16; j += 8){
         for(i = 0; i < 2; i++){
             if(is_mv_diff_gt_3(motion_val + i, 1))
@@ -1192,26 +1192,26 @@ static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
     if(s->mb_x && dist)
         r->avail_cache[5] =
-        r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
+        r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
     if(dist >= s->mb_width)
         r->avail_cache[2] =
-        r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
+        r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
-        r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
+        r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
     if(s->mb_x && dist > s->mb_width)
-        r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
+        r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
 
     s->qscale = r->si.quant;
     cbp = cbp2 = rv34_decode_inter_mb_header(r, intra_types);
     r->cbp_luma  [mb_pos] = cbp;
     r->cbp_chroma[mb_pos] = cbp >> 16;
     r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
-    s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
+    s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
 
     if(cbp == -1)
         return -1;
 
-    if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos])){
+    if (IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
         if(r->is16) rv34_output_i16x16(r, intra_types, cbp);
         else        rv34_output_intra(r, intra_types, cbp);
         return 0;
@@ -1294,21 +1294,21 @@ static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
     dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
     if(s->mb_x && dist)
         r->avail_cache[5] =
-        r->avail_cache[9] = s->current_picture_ptr->f.mb_type[mb_pos - 1];
+        r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
     if(dist >= s->mb_width)
         r->avail_cache[2] =
-        r->avail_cache[3] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride];
+        r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
     if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
-        r->avail_cache[4] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride + 1];
+        r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
     if(s->mb_x && dist > s->mb_width)
-        r->avail_cache[1] = s->current_picture_ptr->f.mb_type[mb_pos - s->mb_stride - 1];
+        r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
 
     s->qscale = r->si.quant;
     cbp = rv34_decode_intra_mb_header(r, intra_types);
     r->cbp_luma  [mb_pos] = cbp;
     r->cbp_chroma[mb_pos] = cbp >> 16;
     r->deblock_coefs[mb_pos] = 0xFFFF;
-    s->current_picture_ptr->f.qscale_table[mb_pos] = s->qscale;
+    s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
 
     if(cbp == -1)
         return -1;
@@ -1444,7 +1444,7 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
                 r->loop_filter(r, s->mb_y - 2);
 
             if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
-                ff_thread_report_progress(&s->current_picture_ptr->f,
+                ff_thread_report_progress(&s->current_picture_ptr->tf,
                                           s->mb_y - 2, 0);
 
         }
@@ -1503,6 +1503,8 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
     if(!intra_vlcs[0].cbppattern[0].bits)
         rv34_init_tables();
 
+    avctx->internal->allocate_progress = 1;
+
     return 0;
 }
 
@@ -1520,6 +1522,7 @@ int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
         if ((err = rv34_decoder_alloc(r)) < 0)
             return err;
     }
+
     return 0;
 }
 
@@ -1563,24 +1566,26 @@ static int finish_frame(AVCodecContext *avctx, AVFrame *pict)
 {
     RV34DecContext *r = avctx->priv_data;
     MpegEncContext *s = &r->s;
-    int got_picture = 0;
+    int got_picture = 0, ret;
 
     ff_er_frame_end(&s->er);
     ff_MPV_frame_end(s);
     s->mb_num_left = 0;
 
     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
-        ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
+        ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
 
     if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-        *pict = s->current_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->current_picture_ptr);
         got_picture = 1;
     } else if (s->last_picture_ptr != NULL) {
-        *pict = s->last_picture_ptr->f;
+        if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+            return ret;
+        ff_print_debug_info(s, s->last_picture_ptr);
         got_picture = 1;
     }
-    if (got_picture)
-        ff_print_debug_info(s, pict);
 
     return got_picture;
 }
@@ -1595,7 +1600,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
     MpegEncContext *s = &r->s;
     AVFrame *pict = data;
     SliceInfo si;
-    int i;
+    int i, ret;
     int slice_count;
     const uint8_t *slices_hdr = NULL;
     int last = 0;
@@ -1604,7 +1609,8 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
     if (buf_size == 0) {
         /* special case for last picture */
         if (s->low_delay==0 && s->next_picture_ptr) {
-            *pict = s->next_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
+                return ret;
             s->next_picture_ptr = NULL;
 
             *got_picture_ptr = 1;
@@ -1761,7 +1767,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
             if(r->loop_filter)
                 r->loop_filter(r, s->mb_height - 1);
 
-            *got_picture_ptr = finish_frame(avctx, pict);
+            ret = finish_frame(avctx, pict);
+            if (ret < 0)
+                return ret;
+            *got_picture_ptr = ret;
         } else if (HAVE_THREADS &&
                    (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
             av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n");
@@ -1770,7 +1779,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
             ff_er_frame_end(&s->er);
             ff_MPV_frame_end(s);
             s->mb_num_left = 0;
-            ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0);
+            ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
             return AVERROR_INVALIDDATA;
         }
     }
index 1f2deac3c9f4646bd7eb722481938a4ba5473570..6f8643dfbf7d34371c3513e57631476c014246a3 100644 (file)
@@ -363,7 +363,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
 
     mb_pos = row * s->mb_stride;
     for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
-        int mbtype = s->current_picture_ptr->f.mb_type[mb_pos];
+        int mbtype = s->current_picture_ptr->mb_type[mb_pos];
         if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
             r->cbp_luma  [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF;
         if(IS_INTRA(mbtype))
@@ -378,7 +378,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
         unsigned y_to_deblock;
         int c_to_deblock[2];
 
-        q = s->current_picture_ptr->f.qscale_table[mb_pos];
+        q = s->current_picture_ptr->qscale_table[mb_pos];
         alpha = rv40_alpha_tab[q];
         beta  = rv40_beta_tab [q];
         betaY = betaC = beta * 3;
@@ -393,7 +393,7 @@ static void rv40_loop_filter(RV34DecContext *r, int row)
             if(avail[i]){
                 int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride;
                 mvmasks[i] = r->deblock_coefs[pos];
-                mbtype [i] = s->current_picture_ptr->f.mb_type[pos];
+                mbtype [i] = s->current_picture_ptr->mb_type[pos];
                 cbp    [i] = r->cbp_luma[pos];
                 uvcbp[i][0] = r->cbp_chroma[pos] & 0xF;
                 uvcbp[i][1] = r->cbp_chroma[pos] >> 4;
index 061f0158bb53c2efca1e3762bc57c29e58a603fb..66d25f11b46d82ffff9571b446b8082539d019b4 100644 (file)
@@ -93,7 +93,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data,
     /* get output buffer */
     block_size = (avctx->bits_per_coded_sample + 4) / 4;
     frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 0e72751564609c1b3e445a1687549c8d0d39ec2b..a4b31288f29133565d28f31b8a1acfdd4b2ec4c3 100644 (file)
@@ -26,7 +26,6 @@
 #include "sgi.h"
 
 typedef struct SgiState {
-    AVFrame picture;
     unsigned int width;
     unsigned int height;
     unsigned int depth;
@@ -155,8 +154,7 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     SgiState *s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame *p = &s->picture;
+    AVFrame *p = data;
     unsigned int dimension, rle;
     int ret = 0;
     uint8_t *out_buf, *out_end;
@@ -206,11 +204,7 @@ static int decode_frame(AVCodecContext *avctx,
         return -1;
     avcodec_set_dimensions(avctx, s->width, s->height);
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if (ff_get_buffer(avctx, p) < 0) {
+    if (ff_get_buffer(avctx, p, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed.\n");
         return -1;
     }
@@ -232,7 +226,6 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     if (ret == 0) {
-        *picture   = s->picture;
         *got_frame = 1;
         return avpkt->size;
     } else {
@@ -240,32 +233,11 @@ static int decode_frame(AVCodecContext *avctx,
     }
 }
 
-static av_cold int sgi_init(AVCodecContext *avctx){
-    SgiState *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
-static av_cold int sgi_end(AVCodecContext *avctx)
-{
-    SgiState * const s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_sgi_decoder = {
     .name           = "sgi",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SGI,
     .priv_data_size = sizeof(SgiState),
-    .init           = sgi_init,
-    .close          = sgi_end,
     .decode         = decode_frame,
     .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),
     .capabilities   = CODEC_CAP_DR1,
index d6c9386c8aae882497c7c399a5a924abd14d0e44..152794617273ad10158cc17e48a2b2bd55885f7e 100644 (file)
@@ -593,7 +593,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data,
             if (s->cur_chan == s->channels) {
                 /* get output buffer */
                 frame->nb_samples = s->blocksize;
-                if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+                if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     return ret;
                 }
index a36cdeff957a7efbdc0fff8622c6738cfb6cee49..2d35841336260910d52776ae4a2ecc4626fadc4d 100644 (file)
@@ -543,7 +543,7 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data,
     /* get output buffer */
     frame->nb_samples = mode_par->frames_per_packet * subframe_size *
                         mode_par->subframe_count;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index bc75a17e63e5090c9e1111080ad6f310dfb97f13..c37fb14a4d268214b15c309fad21b5bed72984fb 100644 (file)
@@ -358,18 +358,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     GetByteContext gb2;
     GetBitContext gb;
     int blocks, blk, bw, bh;
-    int i;
+    int i, ret;
     int stride;
     int flags;
 
     if (avpkt->size <= 769)
         return 0;
 
-    smk->pic.reference = 1;
-    smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if(avctx->reget_buffer(avctx, &smk->pic) < 0){
+    if ((ret = ff_reget_buffer(avctx, &smk->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     /* make the palette available on the way out */
@@ -497,8 +495,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     }
 
+    if ((ret = av_frame_ref(data, &smk->pic)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = smk->pic;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -548,8 +548,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
     av_freep(&smk->full_tbl);
     av_freep(&smk->type_tbl);
 
-    if (smk->pic.data[0])
-        avctx->release_buffer(avctx, &smk->pic);
+    av_frame_unref(&smk->pic);
 
     return 0;
 }
@@ -614,7 +613,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = unp_size / (avctx->channels * (bits + 1));
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 1834003a3931f65cfe10c20f02fc907100f4ee8e..de81a43e9101a473794253e3dc27692953555a46 100644 (file)
@@ -35,6 +35,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define CPAIR 2
 #define CQUAD 4
@@ -429,15 +430,13 @@ static int smc_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     SmcContext *s = avctx->priv_data;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+    int ret;
 
     bytestream2_init(&s->gb, buf, buf_size);
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (pal) {
@@ -448,7 +447,8 @@ static int smc_decode_frame(AVCodecContext *avctx,
     smc_decode_stream(s);
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -458,8 +458,7 @@ static av_cold int smc_decode_end(AVCodecContext *avctx)
 {
     SmcContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     return 0;
 }
index a44cdf026a06bbd52eb392201852dae2bb505e94..56e915d047aa5f4c096b9f90612b4808ca18193a 100644 (file)
 #include "internal.h"
 #include "sunrast.h"
 
-typedef struct SUNRASTContext {
-    AVFrame picture;
-} SUNRASTContext;
-
-static av_cold int sunrast_init(AVCodecContext *avctx) {
-    SUNRASTContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
 static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf       = avpkt->data;
     const uint8_t *buf_end   = avpkt->data + avpkt->size;
-    SUNRASTContext * const s = avctx->priv_data;
-    AVFrame *picture         = data;
-    AVFrame * const p        = &s->picture;
+    AVFrame * const p        = data;
     unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen;
     uint8_t *ptr;
     const uint8_t *bufstart = buf;
@@ -105,12 +90,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
             return AVERROR_INVALIDDATA;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -181,28 +163,15 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return buf - bufstart;
 }
 
-static av_cold int sunrast_end(AVCodecContext *avctx) {
-    SUNRASTContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_sunrast_decoder = {
     .name           = "sunrast",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SUNRAST,
-    .priv_data_size = sizeof(SUNRASTContext),
-    .init           = sunrast_init,
-    .close          = sunrast_end,
     .decode         = sunrast_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
index dc041dd0d76a2f85abe043286037a75b334bc19a..c5d56ee75f0880a56ec7973826a6feea32bdb490 100644 (file)
@@ -60,7 +60,7 @@ typedef struct svq1_pmv_s {
 typedef struct SVQ1Context {
     DSPContext dsp;
     GetBitContext gb;
-    AVFrame *cur, *prev;
+    AVFrame *prev;
     int width;
     int height;
     int frame_code;
@@ -612,14 +612,11 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     SVQ1Context     *s = avctx->priv_data;
-    AVFrame       *cur = s->cur;
+    AVFrame       *cur = data;
     uint8_t *current;
     int result, i, x, y, width, height;
     svq1_pmv *pmv;
 
-    if (cur->data[0])
-        avctx->release_buffer(avctx, cur);
-
     /* initialize bit buffer */
     init_get_bits(&s->gb, buf, buf_size * 8);
 
@@ -651,7 +648,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         avctx->skip_frame >= AVDISCARD_ALL)
         return buf_size;
 
-    result = ff_get_buffer(avctx, cur);
+    result = ff_get_buffer(avctx, cur, s->nonref ? 0 : AV_GET_BUFFER_FLAG_REF);
     if (result < 0)
         return result;
 
@@ -722,9 +719,12 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *(AVFrame*)data = *cur;
-    if (!s->nonref)
-        FFSWAP(AVFrame*, s->cur, s->prev);
+    if (!s->nonref) {
+        av_frame_unref(s->prev);
+        result = av_frame_ref(s->prev, cur);
+        if (result < 0)
+            goto err;
+    }
 
     *got_frame = 1;
     result     = buf_size;
@@ -740,13 +740,9 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx)
     int i;
     int offset = 0;
 
-    s->cur  = avcodec_alloc_frame();
     s->prev = avcodec_alloc_frame();
-    if (!s->cur || !s->prev) {
-        avcodec_free_frame(&s->cur);
-        avcodec_free_frame(&s->prev);
+    if (!s->prev)
         return AVERROR(ENOMEM);
-    }
 
     s->width            = avctx->width  + 3 & ~3;
     s->height           = avctx->height + 3 & ~3;
@@ -797,11 +793,6 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx)
 {
     SVQ1Context *s = avctx->priv_data;
 
-    if (s->cur->data[0])
-        avctx->release_buffer(avctx, s->cur);
-    if (s->prev->data[0])
-        avctx->release_buffer(avctx, s->prev);
-    avcodec_free_frame(&s->cur);
     avcodec_free_frame(&s->prev);
 
     return 0;
@@ -811,10 +802,7 @@ static void svq1_flush(AVCodecContext *avctx)
 {
     SVQ1Context *s = avctx->priv_data;
 
-    if (s->cur->data[0])
-        avctx->release_buffer(avctx, s->cur);
-    if (s->prev->data[0])
-        avctx->release_buffer(avctx, s->prev);
+    av_frame_unref(s->prev);
 }
 
 AVCodec ff_svq1_decoder = {
index e654b4ecb300195c054737ec2f1edf3f185f40b3..22668958a9a404129df6e94052fc9deaca567025 100644 (file)
@@ -324,9 +324,9 @@ static int svq1_encode_plane(SVQ1Context *s, int plane,
         s->m.current_picture.mb_mean   = (uint8_t *)s->dummy;
         s->m.current_picture.mb_var    = (uint16_t *)s->dummy;
         s->m.current_picture.mc_mb_var = (uint16_t *)s->dummy;
-        s->m.current_picture.f.mb_type = s->dummy;
+        s->m.current_picture.mb_type = s->dummy;
 
-        s->m.current_picture.f.motion_val[0] = s->motion_val8[plane] + 2;
+        s->m.current_picture.motion_val[0]   = s->motion_val8[plane] + 2;
         s->m.p_mv_table                      = s->motion_val16[plane] +
                                                s->m.mb_stride + 1;
         s->m.dsp                             = s->dsp; // move
@@ -550,8 +550,8 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     }
 
     if (!s->current_picture.data[0]) {
-        ff_get_buffer(avctx, &s->current_picture);
-        ff_get_buffer(avctx, &s->last_picture);
+        ff_get_buffer(avctx, &s->current_picture, 0);
+        ff_get_buffer(avctx, &s->last_picture, 0);
         s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2);
     }
 
@@ -613,6 +613,9 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx)
         av_freep(&s->motion_val16[i]);
     }
 
+    av_frame_unref(&s->current_picture);
+    av_frame_unref(&s->last_picture);
+
     return 0;
 }
 
index 04c18587ced677091960d08f489582f2a68b3aea..f9d8d46d01273013a79c6957cf979eacfb7a9476 100644 (file)
@@ -370,8 +370,8 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
             if (mode != PREDICT_MODE) {
                 pred_motion(h, k, part_width >> 2, dir, 1, &mx, &my);
             } else {
-                mx = s->next_pic->f.motion_val[0][b_xy][0] << 1;
-                my = s->next_pic->f.motion_val[0][b_xy][1] << 1;
+                mx = s->next_pic->motion_val[0][b_xy][0] << 1;
+                my = s->next_pic->motion_val[0][b_xy][1] << 1;
 
                 if (dir == 0) {
                     mx = mx * h->frame_num_offset /
@@ -452,7 +452,7 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
             }
 
             /* write back motion vectors */
-            fill_rectangle(h->cur_pic.f.motion_val[dir][b_xy],
+            fill_rectangle(h->cur_pic.motion_val[dir][b_xy],
                            part_width >> 2, part_height >> 2, h->b_stride,
                            pack16to32(mx, my), 4);
         }
@@ -476,7 +476,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
 
     if (mb_type == 0) {           /* SKIP */
         if (h->pict_type == AV_PICTURE_TYPE_P ||
-            s->next_pic->f.mb_type[mb_xy] == -1) {
+            s->next_pic->mb_type[mb_xy] == -1) {
             svq3_mc_dir_part(s, 16 * h->mb_x, 16 * h->mb_y, 16, 16,
                              0, 0, 0, 0, 0, 0);
 
@@ -486,7 +486,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
 
             mb_type = MB_TYPE_SKIP;
         } else {
-            mb_type = FFMIN(s->next_pic->f.mb_type[mb_xy], 6);
+            mb_type = FFMIN(s->next_pic->mb_type[mb_xy], 6);
             if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0)
                 return -1;
             if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0)
@@ -516,21 +516,21 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
             if (h->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
                 for (i = 0; i < 4; i++)
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i * 8],
-                              h->cur_pic.f.motion_val[m][b_xy - 1 + i * h->b_stride]);
+                              h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]);
             } else {
                 for (i = 0; i < 4; i++)
                     AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i * 8]);
             }
             if (h->mb_y > 0) {
                 memcpy(h->mv_cache[m][scan8[0] - 1 * 8],
-                       h->cur_pic.f.motion_val[m][b_xy - h->b_stride],
+                       h->cur_pic.motion_val[m][b_xy - h->b_stride],
                        4 * 2 * sizeof(int16_t));
                 memset(&h->ref_cache[m][scan8[0] - 1 * 8],
                        (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
 
                 if (h->mb_x < h->mb_width - 1) {
                     AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1 * 8],
-                              h->cur_pic.f.motion_val[m][b_xy - h->b_stride + 4]);
+                              h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]);
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] =
                         (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||
                          h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
@@ -538,7 +538,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
                     h->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
                 if (h->mb_x > 0) {
                     AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1 * 8],
-                              h->cur_pic.f.motion_val[m][b_xy - h->b_stride - 1]);
+                              h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]);
                     h->ref_cache[m][scan8[0] - 1 - 1 * 8] =
                         (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
                 } else
@@ -561,7 +561,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
                     return -1;
             } else {
                 for (i = 0; i < 4; i++)
-                    memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride],
+                    memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
                            0, 4 * 2 * sizeof(int16_t));
             }
             if (mb_type != 1) {
@@ -569,7 +569,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
                     return -1;
             } else {
                 for (i = 0; i < 4; i++)
-                    memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride],
+                    memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
                            0, 4 * 2 * sizeof(int16_t));
             }
         }
@@ -651,11 +651,11 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
 
     if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) {
         for (i = 0; i < 4; i++)
-            memset(h->cur_pic.f.motion_val[0][b_xy + i * h->b_stride],
+            memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
                    0, 4 * 2 * sizeof(int16_t));
         if (h->pict_type == AV_PICTURE_TYPE_B) {
             for (i = 0; i < 4; i++)
-                memset(h->cur_pic.f.motion_val[1][b_xy + i * h->b_stride],
+                memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
                        0, 4 * 2 * sizeof(int16_t));
         }
     }
@@ -743,7 +743,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
     }
 
     h->cbp                              = cbp;
-    h->cur_pic.f.mb_type[mb_xy] = mb_type;
+    h->cur_pic.mb_type[mb_xy] = mb_type;
 
     if (IS_INTRA(mb_type))
         h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1);
@@ -1016,6 +1016,18 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
+static void free_picture(AVCodecContext *avctx, Picture *pic)
+{
+    int i;
+    for (i = 0; i < 2; i++) {
+        av_buffer_unref(&pic->motion_val_buf[i]);
+        av_buffer_unref(&pic->ref_index_buf[i]);
+    }
+    av_buffer_unref(&pic->mb_type_buf);
+
+    av_frame_unref(&pic->f);
+}
+
 static int get_buffer(AVCodecContext *avctx, Picture *pic)
 {
     SVQ3Context *s = avctx->priv_data;
@@ -1026,27 +1038,34 @@ static int get_buffer(AVCodecContext *avctx, Picture *pic)
     const int b4_array_size = b4_stride * h->mb_height * 4;
     int ret;
 
-    if (!pic->motion_val_base[0]) {
+    if (!pic->motion_val_buf[0]) {
         int i;
 
-        pic->mb_type_base = av_mallocz((big_mb_num + h->mb_stride) * sizeof(uint32_t));
-        if (!pic->mb_type_base)
+        pic->mb_type_buf = av_buffer_allocz((big_mb_num + h->mb_stride) * sizeof(uint32_t));
+        if (!pic->mb_type_buf)
             return AVERROR(ENOMEM);
-        pic->f.mb_type = pic->mb_type_base + 2 * h->mb_stride + 1;
+        pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * h->mb_stride + 1;
 
         for (i = 0; i < 2; i++) {
-            pic->motion_val_base[i] = av_mallocz(2 * (b4_array_size + 4) * sizeof(int16_t));
-            pic->f.ref_index[i]     = av_mallocz(4 * mb_array_size);
-            if (!pic->motion_val_base[i] || !pic->f.ref_index[i])
-                return AVERROR(ENOMEM);
+            pic->motion_val_buf[i] = av_buffer_allocz(2 * (b4_array_size + 4) * sizeof(int16_t));
+            pic->ref_index_buf[i]  = av_buffer_allocz(4 * mb_array_size);
+            if (!pic->motion_val_buf[i] || !pic->ref_index_buf[i]) {
+                ret = AVERROR(ENOMEM);
+                goto fail;
+            }
 
-            pic->f.motion_val[i] = pic->motion_val_base[i] + 4;
+            pic->motion_val[i] = (int16_t (*)[2])pic->motion_val_buf[i]->data + 4;
+            pic->ref_index[i]  = pic->ref_index_buf[i]->data;
         }
     }
     pic->f.motion_subsample_log2 = 2;
-    pic->f.reference = !(h->pict_type == AV_PICTURE_TYPE_B);
+    pic->reference = !(h->pict_type == AV_PICTURE_TYPE_B);
+
+    ret = ff_get_buffer(avctx, &pic->f,
+                        pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
+    if (ret < 0)
+        goto fail;
 
-    ret = ff_get_buffer(avctx, &pic->f);
     if (!h->edge_emu_buffer) {
         h->edge_emu_buffer = av_mallocz(pic->f.linesize[0] * 17);
         if (!h->edge_emu_buffer)
@@ -1056,6 +1075,9 @@ static int get_buffer(AVCodecContext *avctx, Picture *pic)
     h->linesize   = pic->f.linesize[0];
     h->uvlinesize = pic->f.linesize[1];
 
+    return 0;
+fail:
+    free_picture(avctx, pic);
     return ret;
 }
 
@@ -1071,7 +1093,9 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
     /* special case for last picture */
     if (buf_size == 0) {
         if (s->next_pic->f.data[0] && !h->low_delay && !s->last_frame_output) {
-            *(AVFrame *) data   = s->next_pic->f;
+            ret = av_frame_ref(data, &s->next_pic->f);
+            if (ret < 0)
+                return ret;
             s->last_frame_output = 1;
             *got_frame          = 1;
         }
@@ -1090,8 +1114,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
     if (h->pict_type != AV_PICTURE_TYPE_B)
         FFSWAP(Picture*, s->next_pic, s->last_pic);
 
-    if (s->cur_pic->f.data[0])
-        avctx->release_buffer(avctx, &s->cur_pic->f);
+    av_frame_unref(&s->cur_pic->f);
 
     /* for skipping the frame */
     s->cur_pic->f.pict_type = h->pict_type;
@@ -1102,7 +1125,11 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
         return ret;
 
     h->cur_pic_ptr = s->cur_pic;
+    av_frame_unref(&h->cur_pic.f);
     h->cur_pic     = *s->cur_pic;
+    ret = av_frame_ref(&h->cur_pic.f, &s->cur_pic->f);
+    if (ret < 0)
+        return ret;
 
     for (i = 0; i < 16; i++) {
         h->block_offset[i]           = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * h->linesize * ((scan8[i] - scan8[0]) >> 3);
@@ -1223,7 +1250,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
                 ff_h264_hl_decode_mb(h);
 
             if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay)
-                h->cur_pic.f.mb_type[h->mb_x + h->mb_y * h->mb_stride] =
+                h->cur_pic.mb_type[h->mb_x + h->mb_y * h->mb_stride] =
                     (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
         }
 
@@ -1233,9 +1260,11 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay)
-        *(AVFrame *)data = s->cur_pic->f;
-    else
-        *(AVFrame *)data = s->last_pic->f;
+        ret = av_frame_ref(data, &s->cur_pic->f);
+    else if (s->last_pic->f.data[0])
+        ret = av_frame_ref(data, &s->last_pic->f);
+    if (ret < 0)
+        return ret;
 
     /* Do not output the last pic after seeking. */
     if (s->last_pic->f.data[0] || h->low_delay)
@@ -1243,25 +1272,13 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
 
     if (h->pict_type != AV_PICTURE_TYPE_B) {
         FFSWAP(Picture*, s->cur_pic, s->next_pic);
+    } else {
+        av_frame_unref(&s->cur_pic->f);
     }
 
     return buf_size;
 }
 
-static void free_picture(AVCodecContext *avctx, Picture *pic)
-{
-    int i;
-    for (i = 0; i < 2; i++) {
-        av_freep(&pic->motion_val_base[i]);
-        av_freep(&pic->f.ref_index[i]);
-    }
-    av_freep(&pic->mb_type_base);
-
-    if (pic->f.data[0])
-        avctx->release_buffer(avctx, &pic->f);
-    av_freep(&pic);
-}
-
 static int svq3_decode_end(AVCodecContext *avctx)
 {
     SVQ3Context *s = avctx->priv_data;
@@ -1270,6 +1287,11 @@ static int svq3_decode_end(AVCodecContext *avctx)
     free_picture(avctx, s->cur_pic);
     free_picture(avctx, s->next_pic);
     free_picture(avctx, s->last_pic);
+    av_freep(&s->cur_pic);
+    av_freep(&s->next_pic);
+    av_freep(&s->last_pic);
+
+    av_frame_unref(&h->cur_pic.f);
 
     ff_h264_free_context(h);
 
index 48a424ebb7c52a49f09a5b8d40330e8a168eb090..a9b8c6664c622e8f82d470b4ba4787f99f7241a2 100644 (file)
@@ -740,7 +740,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data,
                                              : s->ti.frame_samples;
 
     frame->nb_samples = s->nb_samples;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0)
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     if (avctx->bits_per_coded_sample <= 16) {
index 54eea7df65d81aa084a89f9bdceea6f5bea393cf..993f02c0117d97ee144b312241a8396d29099518 100644 (file)
@@ -27,7 +27,6 @@
 #include "targa.h"
 
 typedef struct TargaContext {
-    AVFrame picture;
     GetByteContext gb;
 
     int color_type;
@@ -99,8 +98,7 @@ static int decode_frame(AVCodecContext *avctx,
                         AVPacket *avpkt)
 {
     TargaContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = data;
     uint8_t *dst;
     int stride;
     int idlen, compr, y, w, h, bpp, flags, ret;
@@ -144,14 +142,11 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
     if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
         return ret;
     if(w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = ff_get_buffer(avctx, p)) < 0){
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -232,37 +227,16 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return avpkt->size;
 }
 
-static av_cold int targa_init(AVCodecContext *avctx){
-    TargaContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
-static av_cold int targa_end(AVCodecContext *avctx){
-    TargaContext *s = avctx->priv_data;
-
-    if(s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_targa_decoder = {
     .name           = "targa",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TARGA,
     .priv_data_size = sizeof(TargaContext),
-    .init           = targa_init,
-    .close          = targa_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Truevision Targa image"),
index 99b0ce146a4761901da35151e09149e00fba7b84..864e67eb98b45c8db7c1a46879a9c8ce3f6b06e3 100644 (file)
 #ifndef AVCODEC_THREAD_H
 #define AVCODEC_THREAD_H
 
+#include "libavutil/buffer.h"
+
 #include "config.h"
 #include "avcodec.h"
 
+typedef struct ThreadFrame {
+    AVFrame *f;
+    AVCodecContext *owner;
+    // progress->data is an array of 2 ints holding progress for top/bottom
+    // fields
+    AVBufferRef *progress;
+} ThreadFrame;
+
 /**
  * Wait for decoding threads to finish and reset internal state.
  * Called by avcodec_flush_buffers().
@@ -71,7 +81,7 @@ void ff_thread_finish_setup(AVCodecContext *avctx);
  * @param field The field being decoded, for field-picture codecs.
  * 0 for top field or frame pictures, 1 for bottom field.
  */
-void ff_thread_report_progress(AVFrame *f, int progress, int field);
+void ff_thread_report_progress(ThreadFrame *f, int progress, int field);
 
 /**
  * Wait for earlier decoding threads to finish reference pictures.
@@ -85,7 +95,7 @@ void ff_thread_report_progress(AVFrame *f, int progress, int field);
  * @param field The field being referenced, for field-picture codecs.
  * 0 for top field or frame pictures, 1 for bottom field.
  */
-void ff_thread_await_progress(AVFrame *f, int progress, int field);
+void ff_thread_await_progress(ThreadFrame *f, int progress, int field);
 
 /**
  * Wrapper around get_buffer() for frame-multithreaded codecs.
@@ -95,7 +105,7 @@ void ff_thread_await_progress(AVFrame *f, int progress, int field);
  * @param avctx The current context.
  * @param f The frame to write into.
  */
-int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f);
+int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags);
 
 /**
  * Wrapper around release_buffer() frame-for multithreaded codecs.
@@ -108,7 +118,9 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f);
  * @param avctx The current context.
  * @param f The picture being released.
  */
-void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f);
+void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f);
+
+int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src);
 
 int ff_thread_init(AVCodecContext *s);
 void ff_thread_free(AVCodecContext *s);
index a9064eca2417a1a58d5a013ed9ee8bfbbb06fc95..5d5d69434bed749bfc4591c12f1c13736e000431 100644 (file)
@@ -27,6 +27,7 @@
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 
 typedef struct SeqVideoContext {
@@ -227,21 +228,21 @@ static int seqvideo_decode_frame(AVCodecContext *avctx,
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
+    int ret;
 
     SeqVideoContext *seq = avctx->priv_data;
 
-    seq->frame.reference = 1;
-    seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &seq->frame)) {
+    if ((ret = ff_reget_buffer(avctx, &seq->frame)) < 0) {
         av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     if (seqvideo_decode(seq, buf, buf_size))
         return AVERROR_INVALIDDATA;
 
+    if ((ret = av_frame_ref(data, &seq->frame)) < 0)
+        return ret;
     *got_frame       = 1;
-    *(AVFrame *)data = seq->frame;
 
     return buf_size;
 }
@@ -250,8 +251,7 @@ static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
 {
     SeqVideoContext *seq = avctx->priv_data;
 
-    if (seq->frame.data[0])
-        avctx->release_buffer(avctx, &seq->frame);
+    av_frame_unref(&seq->frame);
 
     return 0;
 }
index dd25190ecf5997030c5a407069c0d7a35edd3e0b..79c93cbb8a5a87ace2b6bd381c56d7049d01dcf3 100644 (file)
@@ -41,7 +41,6 @@
 
 typedef struct TiffContext {
     AVCodecContext *avctx;
-    AVFrame picture;
 
     int width, height;
     unsigned int bpp, bppcount;
@@ -245,7 +244,7 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
     return 0;
 }
 
-static int init_image(TiffContext *s)
+static int init_image(TiffContext *s, AVFrame *frame)
 {
     int i, ret;
     uint32_t *pal;
@@ -280,18 +279,16 @@ static int init_image(TiffContext *s)
             return ret;
         avcodec_set_dimensions(s->avctx, s->width, s->height);
     }
-    if (s->picture.data[0])
-        s->avctx->release_buffer(s->avctx, &s->picture);
-    if ((ret = ff_get_buffer(s->avctx, &s->picture)) < 0) {
+    if ((ret = ff_get_buffer(s->avctx, frame, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
     if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         if (s->palette_is_set) {
-            memcpy(s->picture.data[1], s->palette, sizeof(s->palette));
+            memcpy(frame->data[1], s->palette, sizeof(s->palette));
         } else {
             /* make default grayscale pal */
-            pal = (uint32_t *) s->picture.data[1];
+            pal = (uint32_t *) frame->data[1];
             for (i = 0; i < 256; i++)
                 pal[i] = i * 0x010101;
         }
@@ -545,8 +542,7 @@ static int decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     TiffContext *const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame *const p = &s->picture;
+    AVFrame *const p = data;
     const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
     unsigned off;
     int id, le, ret;
@@ -599,7 +595,7 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
     /* now we have the data and may start decoding */
-    if ((ret = init_image(s)) < 0)
+    if ((ret = init_image(s, p)) < 0)
         return ret;
 
     if (s->strips == 1 && !s->stripsize) {
@@ -647,14 +643,13 @@ static int decode_frame(AVCodecContext *avctx,
         uint8_t *src;
         int j;
 
-        src = s->picture.data[0];
+        src = p->data[0];
         for (j = 0; j < s->height; j++) {
-            for (i = 0; i < s->picture.linesize[0]; i++)
+            for (i = 0; i < p->linesize[0]; i++)
                 src[i] = 255 - src[i];
-            src += s->picture.linesize[0];
+            src += p->linesize[0];
         }
     }
-    *picture   = s->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -667,8 +662,6 @@ static av_cold int tiff_init(AVCodecContext *avctx)
     s->width = 0;
     s->height = 0;
     s->avctx = avctx;
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
     ff_lzw_decode_open(&s->lzw);
     ff_ccitt_unpack_init();
 
@@ -680,8 +673,6 @@ static av_cold int tiff_end(AVCodecContext *avctx)
     TiffContext *const s = avctx->priv_data;
 
     ff_lzw_decode_close(&s->lzw);
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
     return 0;
 }
 
index 29d8e15fd974fa47b2e4d6cf1ec0cf02ed780d7a..c1e4d253ec700f589da07d2e3af93dc4d14e23d2 100644 (file)
 
 #include "cga_data.h"
 
-typedef struct TMVContext {
-    AVFrame pic;
-} TMVContext;
-
 static int tmv_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
-    TMVContext *tmv    = avctx->priv_data;
+    AVFrame *frame     = data;
     const uint8_t *src = avpkt->data;
     uint8_t *dst;
     unsigned char_cols = avctx->width >> 3;
@@ -49,10 +45,7 @@ static int tmv_decode_frame(AVCodecContext *avctx, void *data,
     unsigned x, y, fg, bg, c;
     int ret;
 
-    if (tmv->pic.data[0])
-        avctx->release_buffer(avctx, &tmv->pic);
-
-    if ((ret = ff_get_buffer(avctx, &tmv->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -64,26 +57,26 @@ static int tmv_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    tmv->pic.pict_type = AV_PICTURE_TYPE_I;
-    tmv->pic.key_frame = 1;
-    dst                = tmv->pic.data[0];
+    frame->pict_type = AV_PICTURE_TYPE_I;
+    frame->key_frame = 1;
+    dst              = frame->data[0];
 
-    tmv->pic.palette_has_changed = 1;
-    memcpy(tmv->pic.data[1], ff_cga_palette, 16 * 4);
+    frame->palette_has_changed = 1;
+    memcpy(frame->data[1], ff_cga_palette, 16 * 4);
 
     for (y = 0; y < char_rows; y++) {
         for (x = 0; x < char_cols; x++) {
             c  = *src++;
             bg = *src  >> 4;
             fg = *src++ & 0xF;
-            ff_draw_pc_font(dst + x * 8, tmv->pic.linesize[0],
+            ff_draw_pc_font(dst + x * 8, frame->linesize[0],
                             ff_cga_font, 8, c, fg, bg);
         }
-        dst += tmv->pic.linesize[0] * 8;
+        dst += frame->linesize[0] * 8;
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = tmv->pic;
+
     return avpkt->size;
 }
 
@@ -93,23 +86,11 @@ static av_cold int tmv_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int tmv_decode_close(AVCodecContext *avctx)
-{
-    TMVContext *tmv = avctx->priv_data;
-
-    if (tmv->pic.data[0])
-        avctx->release_buffer(avctx, &tmv->pic);
-
-    return 0;
-}
-
 AVCodec ff_tmv_decoder = {
     .name           = "tmv",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TMV,
-    .priv_data_size = sizeof(TMVContext),
     .init           = tmv_decode_init,
-    .close          = tmv_decode_close,
     .decode         = tmv_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("8088flex TMV"),
index 73f705696541eb2948314aca0960dfd2ea417a9d..01d4694e14f1ab6b128a21f3cc05352316b75582 100644 (file)
@@ -34,6 +34,7 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
@@ -401,8 +402,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s)
 
     if (s->w != s->avctx->width || s->h != s->avctx->height ||
         new_pix_fmt != s->avctx->pix_fmt) {
-        if (s->frame.data[0])
-            s->avctx->release_buffer(s->avctx, &s->frame);
+        av_frame_unref(&s->frame);
         s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
         s->avctx->pix_fmt = new_pix_fmt;
         avcodec_set_dimensions(s->avctx, s->w, s->h);
@@ -852,10 +852,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx,
     if ((ret = truemotion1_decode_header(s)) < 0)
         return ret;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
-        FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -866,8 +863,10 @@ static int truemotion1_decode_frame(AVCodecContext *avctx,
         truemotion1_decode_16bit(s);
     }
 
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
+
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -877,9 +876,7 @@ static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
 {
     TrueMotion1Context *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
+    av_frame_unref(&s->frame);
     av_free(s->vert_pred);
 
     return 0;
index d517906e4372058ed1994db203b1aa86090e1c8f..2ecfb93161ee8147d8461f692ba697b64c9d0541 100644 (file)
@@ -28,6 +28,7 @@
 #include "bytestream.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
 
 #define TM2_ESCAPE 0x80000000
 #define TM2_DELTAS 64
@@ -847,9 +848,8 @@ static int decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
         return AVERROR(ENOMEM);
     }
-    p->reference = 1;
-    p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
+
+    if ((ret = ff_reget_buffer(avctx, p)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         av_free(swbuf);
         return ret;
@@ -883,10 +883,10 @@ static int decode_frame(AVCodecContext *avctx,
 
     l->cur = !l->cur;
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
+    ret = av_frame_ref(data, &l->pic);
     av_free(swbuf);
 
-    return buf_size;
+    return (ret < 0) ? ret : buf_size;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx)
@@ -968,8 +968,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
         av_free(l->V2_base);
     }
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+    av_frame_unref(pic);
 
     return 0;
 }
index 73f2de917f625b4ed81d17adda44d69046d15c7c..859983c574bcab7c459115bf7a44d2030d90cb9e 100644 (file)
@@ -325,7 +325,7 @@ static int truespeech_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = iterations * 240;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 0b3c7f1a60e2a0305dce81e22cae27373473e88d..ce88b0e754a140ac17f8a99a9113c32f2983ec4e 100644 (file)
@@ -47,7 +47,6 @@
 typedef struct TsccContext {
 
     AVCodecContext *avctx;
-    AVFrame pic;
 
     // Bits per pixel
     int bpp;
@@ -69,15 +68,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int buf_size = avpkt->size;
     CamtasiaContext * const c = avctx->priv_data;
     const unsigned char *encoded = buf;
+    AVFrame *frame = data;
     int zret; // Zlib return code
     int ret, len = buf_size;
 
-    if(c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0){
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -102,7 +97,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (zret != Z_DATA_ERROR) {
         bytestream2_init(&c->gb, c->decomp_buf,
                          c->decomp_size - c->zstream.avail_out);
-        ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, &c->gb);
+        ff_msrle_decode(avctx, (AVPicture*)frame, c->bpp, &c->gb);
     }
 
     /* make the palette available on the way out */
@@ -110,14 +105,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
         if (pal) {
-            c->pic.palette_has_changed = 1;
+            frame->palette_has_changed = 1;
             memcpy(c->pal, pal, AVPALETTE_SIZE);
         }
-        memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
+        memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -174,8 +168,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
     av_freep(&c->decomp_buf);
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
     inflateEnd(&c->zstream);
 
     return 0;
index b7f1b8899bc57bf5a6f561b47dcea2aa629517b3..439de91b40d1d5795362a8a74e7eba5ff3d42d75 100644 (file)
@@ -28,6 +28,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "tscc2data.h"
 
 typedef struct TSCC2Context {
@@ -229,17 +230,15 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    c->pic.reference    = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
 
     if (frame_type == 0) {
         *got_frame      = 1;
-        *(AVFrame*)data = c->pic;
+        if ((ret = av_frame_ref(data, &c->pic)) < 0)
+            return ret;
 
         return buf_size;
     }
@@ -323,7 +322,8 @@ static int tscc2_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
+    if ((ret = av_frame_ref(data, &c->pic)) < 0)
+        return ret;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -352,8 +352,6 @@ static av_cold int tscc2_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
-    avctx->coded_frame = &c->pic;
-
     return 0;
 }
 
@@ -361,8 +359,7 @@ static av_cold int tscc2_decode_end(AVCodecContext *avctx)
 {
     TSCC2Context * const c = avctx->priv_data;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(&c->pic);
     av_freep(&c->slice_quants);
     free_vlcs(c);
 
index e230fafbf65dc690aefd69980f000e95057dc48d..f8ad34f1908090c719ad55746d6dab6f23b05c59 100644 (file)
@@ -325,7 +325,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = framelen;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 339808131e41590ba6ca445de240bf5245d247c6..a4c1e938e01a8d91de40626fac55c73c7dbcad3e 100644 (file)
@@ -832,7 +832,7 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data,
     /* get output buffer */
     if (tctx->discarded_packets >= 2) {
         frame->nb_samples = mtab->size;
-        if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
index fc6e32f1f3bc42f7669156f85f8ab15e8bb99246..a2d123e49012417a5b47366824a9de906d04a916 100644 (file)
 #include "internal.h"
 #include "s3tc.h"
 
-typedef struct TXDContext {
-    AVFrame picture;
-} TXDContext;
-
-static av_cold int txd_init(AVCodecContext *avctx) {
-    TXDContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame = &s->picture;
-
-    return 0;
-}
-
 static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt) {
-    TXDContext * const s = avctx->priv_data;
     GetByteContext gb;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+    AVFrame * const p = data;
     unsigned int version, w, h, d3d_format, depth, stride, flags;
     unsigned int y, v;
     uint8_t *ptr;
@@ -78,14 +63,11 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_PATCHWELCOME;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
     if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
         return ret;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -135,7 +117,6 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         }
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return avpkt->size;
@@ -145,22 +126,10 @@ unsupported:
     return AVERROR_PATCHWELCOME;
 }
 
-static av_cold int txd_end(AVCodecContext *avctx) {
-    TXDContext *s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 AVCodec ff_txd_decoder = {
     .name           = "txd",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TXD,
-    .priv_data_size = sizeof(TXDContext),
-    .init           = txd_init,
-    .close          = txd_end,
     .decode         = txd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Renderware TXD (TeXture Dictionary) image"),
index 275319605d108a177217664017c129cf82c6be6f..e99c26725b601bffa943485c1092ef1671d1bccb 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #include "ulti_cb.h"
 
@@ -60,8 +61,7 @@ static av_cold int ulti_decode_end(AVCodecContext *avctx){
     UltimotionDecodeContext *s = avctx->priv_data;
     AVFrame *pic = &s->frame;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+    av_frame_unref(pic);
 
     return 0;
 }
@@ -221,15 +221,13 @@ static int ulti_decode_frame(AVCodecContext *avctx,
     int blocks = 0;
     int done = 0;
     int x = 0, y = 0;
-    int i;
+    int i, ret;
     int skip;
     int tmp;
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     bytestream2_init(&s->gb, buf, buf_size);
@@ -407,7 +405,8 @@ static int ulti_decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data= s->frame;
+    if ((ret = av_frame_ref(data, &s->frame)) < 0)
+        return ret;
 
     return buf_size;
 
index 091d34c1580618ceca6d58578aee7087597e9111..7e451bfa0b578f8ef66df82527860bd906dd1f57 100644 (file)
@@ -30,6 +30,7 @@
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/crc.h"
+#include "libavutil/frame.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
@@ -155,8 +156,6 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
     s->height       = height;
 }
 
-#define INTERNAL_BUFFER_SIZE (32 + 1)
-
 #if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX
 #   define STRIDE_ALIGN 16
 #else
@@ -304,87 +303,26 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
     return ret;
 }
 
-static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
-{
-    AVCodecInternal *avci = avctx->internal;
-    int buf_size, ret;
-
-    av_freep(&avci->audio_data);
-    buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
-                                          frame->nb_samples, avctx->sample_fmt,
-                                          0);
-    if (buf_size < 0)
-        return AVERROR(EINVAL);
-
-    frame->data[0] = av_mallocz(buf_size);
-    if (!frame->data[0])
-        return AVERROR(ENOMEM);
-
-    ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt,
-                                   frame->data[0], buf_size, 0);
-    if (ret < 0) {
-        av_freep(&frame->data[0]);
-        return ret;
-    }
-
-    avci->audio_data = frame->data[0];
-    if (avctx->debug & FF_DEBUG_BUFFERS)
-        av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
-                                    "internal audio buffer used\n", frame);
-
-    return 0;
-}
-
-static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
+static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame)
 {
-    int i;
-    int w = s->width;
-    int h = s->height;
-    InternalBuffer *buf;
-    AVCodecInternal *avci = s->internal;
-
-    if (pic->data[0] != NULL) {
-        av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
-        return -1;
-    }
-    if (avci->buffer_count >= INTERNAL_BUFFER_SIZE) {
-        av_log(s, AV_LOG_ERROR, "buffer_count overflow (missing release_buffer?)\n");
-        return -1;
-    }
+    FramePool *pool = avctx->internal->pool;
+    int i, ret;
 
-    if (av_image_check_size(w, h, 0, s))
-        return -1;
-
-    if (!avci->buffer) {
-        avci->buffer = av_mallocz((INTERNAL_BUFFER_SIZE + 1) *
-                                  sizeof(InternalBuffer));
-    }
-
-    buf = &avci->buffer[avci->buffer_count];
-
-    if (buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)) {
-        for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
-            av_freep(&buf->base[i]);
-            buf->data[i] = NULL;
-        }
-    }
-
-    if (!buf->base[0]) {
-        int h_chroma_shift, v_chroma_shift;
-        int size[4] = { 0 };
-        int tmpsize;
-        int unaligned;
+    switch (avctx->codec_type) {
+    case AVMEDIA_TYPE_VIDEO: {
         AVPicture picture;
-        int stride_align[AV_NUM_DATA_POINTERS];
-        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->pix_fmt);
-        const int pixel_size = desc->comp[0].step_minus1 + 1;
+        int size[4] = { 0 };
+        int w = frame->width;
+        int h = frame->height;
+        int tmpsize, unaligned;
 
-        av_pix_fmt_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift,
-                                         &v_chroma_shift);
+        if (pool->format == frame->format &&
+            pool->width == frame->width && pool->height == frame->height)
+            return 0;
 
-        avcodec_align_dimensions2(s, &w, &h, stride_align);
+        avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align);
 
-        if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
+        if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
             w += EDGE_WIDTH * 2;
             h += EDGE_WIDTH * 2;
         }
@@ -392,16 +330,17 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
         do {
             // NOTE: do not align linesizes individually, this breaks e.g. assumptions
             // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2
-            av_image_fill_linesizes(picture.linesize, s->pix_fmt, w);
+            av_image_fill_linesizes(picture.linesize, avctx->pix_fmt, w);
             // increase alignment of w for next try (rhs gives the lowest bit set in w)
             w += w & ~(w - 1);
 
             unaligned = 0;
             for (i = 0; i < 4; i++)
-                unaligned |= picture.linesize[i] % stride_align[i];
+                unaligned |= picture.linesize[i] % pool->stride_align[i];
         } while (unaligned);
 
-        tmpsize = av_image_fill_pointers(picture.data, s->pix_fmt, h, NULL, picture.linesize);
+        tmpsize = av_image_fill_pointers(picture.data, avctx->pix_fmt, h,
+                                         NULL, picture.linesize);
         if (tmpsize < 0)
             return -1;
 
@@ -409,54 +348,169 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
             size[i] = picture.data[i + 1] - picture.data[i];
         size[i] = tmpsize - (picture.data[i] - picture.data[0]);
 
-        memset(buf->base, 0, sizeof(buf->base));
-        memset(buf->data, 0, sizeof(buf->data));
+        for (i = 0; i < 4; i++) {
+            av_buffer_pool_uninit(&pool->pools[i]);
+            pool->linesize[i] = picture.linesize[i];
+            if (size[i]) {
+                pool->pools[i] = av_buffer_pool_init(size[i] + 16, NULL);
+                if (!pool->pools[i]) {
+                    ret = AVERROR(ENOMEM);
+                    goto fail;
+                }
+            }
+        }
+        pool->format = frame->format;
+        pool->width  = frame->width;
+        pool->height = frame->height;
 
-        for (i = 0; i < 4 && size[i]; i++) {
-            const int h_shift = i == 0 ? 0 : h_chroma_shift;
-            const int v_shift = i == 0 ? 0 : v_chroma_shift;
+        break;
+        }
+    case AVMEDIA_TYPE_AUDIO: {
+        int ch     = av_get_channel_layout_nb_channels(frame->channel_layout);
+        int planar = av_sample_fmt_is_planar(frame->format);
+        int planes = planar ? ch : 1;
+
+        if (pool->format == frame->format && pool->planes == planes &&
+            pool->channels == ch && frame->nb_samples == pool->samples)
+            return 0;
+
+        av_buffer_pool_uninit(&pool->pools[0]);
+        ret = av_samples_get_buffer_size(&pool->linesize[0], ch,
+                                         frame->nb_samples, frame->format, 0);
+        if (ret < 0)
+            goto fail;
+
+        pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL);
+        if (!pool->pools[0]) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
 
-            buf->linesize[i] = picture.linesize[i];
+        pool->format     = frame->format;
+        pool->planes     = planes;
+        pool->channels   = ch;
+        pool->samples = frame->nb_samples;
+        break;
+        }
+    default: av_assert0(0);
+    }
+    return 0;
+fail:
+    for (i = 0; i < 4; i++)
+        av_buffer_pool_uninit(&pool->pools[i]);
+    pool->format = -1;
+    pool->planes = pool->channels = pool->samples = 0;
+    pool->width  = pool->height = 0;
+    return ret;
+}
 
-            buf->base[i] = av_malloc(size[i] + 16); //FIXME 16
-            if (buf->base[i] == NULL)
-                return -1;
+static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    FramePool *pool = avctx->internal->pool;
+    int planes = pool->planes;
+    int i;
 
-            // no edge if EDGE EMU or not planar YUV
-            if ((s->flags & CODEC_FLAG_EMU_EDGE) || !size[2])
-                buf->data[i] = buf->base[i];
-            else
-                buf->data[i] = buf->base[i] + FFALIGN((buf->linesize[i] * EDGE_WIDTH >> v_shift) + (pixel_size * EDGE_WIDTH >> h_shift), stride_align[i]);
-        }
-        for (; i < AV_NUM_DATA_POINTERS; i++) {
-            buf->base[i]     = buf->data[i] = NULL;
-            buf->linesize[i] = 0;
+    frame->linesize[0] = pool->linesize[0];
+
+    if (planes > AV_NUM_DATA_POINTERS) {
+        frame->extended_data = av_mallocz(planes * sizeof(*frame->extended_data));
+        frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS;
+        frame->extended_buf  = av_mallocz(frame->nb_extended_buf *
+                                          sizeof(*frame->extended_buf));
+        if (!frame->extended_data || !frame->extended_buf) {
+            av_freep(&frame->extended_data);
+            av_freep(&frame->extended_buf);
+            return AVERROR(ENOMEM);
         }
-        if (size[1] && !size[2])
-            avpriv_set_systematic_pal2((uint32_t *)buf->data[1], s->pix_fmt);
-        buf->width   = s->width;
-        buf->height  = s->height;
-        buf->pix_fmt = s->pix_fmt;
+    } else
+        frame->extended_data = frame->data;
+
+    for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) {
+        frame->buf[i] = av_buffer_pool_get(pool->pools[0]);
+        if (!frame->buf[i])
+            goto fail;
+        frame->extended_data[i] = frame->data[i] = frame->buf[i]->data;
     }
+    for (i = 0; i < frame->nb_extended_buf; i++) {
+        frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]);
+        if (!frame->extended_buf[i])
+            goto fail;
+        frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data;
+    }
+
+    if (avctx->debug & FF_DEBUG_BUFFERS)
+        av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame);
+
+    return 0;
+fail:
+    av_frame_unref(frame);
+    return AVERROR(ENOMEM);
+}
 
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
-        pic->base[i]     = buf->base[i];
-        pic->data[i]     = buf->data[i];
-        pic->linesize[i] = buf->linesize[i];
+static int video_get_buffer(AVCodecContext *s, AVFrame *pic)
+{
+    FramePool *pool = s->internal->pool;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format);
+    int pixel_size = desc->comp[0].step_minus1 + 1;
+    int h_chroma_shift, v_chroma_shift;
+    int i;
+
+    if (pic->data[0] != NULL) {
+        av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
+        return -1;
     }
+
+    memset(pic->data, 0, sizeof(pic->data));
     pic->extended_data = pic->data;
-    avci->buffer_count++;
+
+    av_pix_fmt_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
+
+    for (i = 0; i < 4 && pool->pools[i]; i++) {
+        const int h_shift = i == 0 ? 0 : h_chroma_shift;
+        const int v_shift = i == 0 ? 0 : v_chroma_shift;
+
+        pic->linesize[i] = pool->linesize[i];
+
+        pic->buf[i] = av_buffer_pool_get(pool->pools[i]);
+        if (!pic->buf[i])
+            goto fail;
+
+        // no edge if EDGE EMU or not planar YUV
+        if ((s->flags & CODEC_FLAG_EMU_EDGE) || !pool->pools[2])
+            pic->data[i] = pic->buf[i]->data;
+        else {
+            pic->data[i] = pic->buf[i]->data +
+                FFALIGN((pic->linesize[i] * EDGE_WIDTH >> v_shift) +
+                        (pixel_size * EDGE_WIDTH >> h_shift), pool->stride_align[i]);
+        }
+    }
+    for (; i < AV_NUM_DATA_POINTERS; i++) {
+        pic->data[i] = NULL;
+        pic->linesize[i] = 0;
+    }
+    if (pic->data[1] && !pic->data[2])
+        avpriv_set_systematic_pal2((uint32_t *)pic->data[1], s->pix_fmt);
 
     if (s->debug & FF_DEBUG_BUFFERS)
-        av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d "
-                                "buffers used\n", pic, avci->buffer_count);
+        av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic);
 
     return 0;
+fail:
+    av_frame_unref(pic);
+    return AVERROR(ENOMEM);
 }
 
-int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags)
 {
+    int ret;
+
+    if ((ret = update_frame_pool(avctx, frame)) < 0)
+        return ret;
+
+#if FF_API_GET_BUFFER
     frame->type = FF_BUFFER_TYPE_INTERNAL;
+#endif
+
     switch (avctx->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
         return video_get_buffer(avctx, frame);
@@ -467,14 +521,44 @@ int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
     }
 }
 
-int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+#if FF_API_GET_BUFFER
+int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
 {
+    return avcodec_default_get_buffer2(avctx, frame, 0);
+}
+
+typedef struct CompatReleaseBufPriv {
+    AVCodecContext avctx;
+    AVFrame frame;
+} CompatReleaseBufPriv;
+
+static void compat_free_buffer(void *opaque, uint8_t *data)
+{
+    CompatReleaseBufPriv *priv = opaque;
+    priv->avctx.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);
+}
+#endif
+
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
+{
+    int ret;
+
     switch (avctx->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
         frame->width               = avctx->width;
         frame->height              = avctx->height;
         frame->format              = avctx->pix_fmt;
         frame->sample_aspect_ratio = avctx->sample_aspect_ratio;
+
+        if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
+            return ret;
         break;
     case AVMEDIA_TYPE_AUDIO:
         frame->sample_rate    = avctx->sample_rate;
@@ -487,87 +571,157 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
     frame->pkt_pts = avctx->pkt ? avctx->pkt->pts : AV_NOPTS_VALUE;
     frame->reordered_opaque = avctx->reordered_opaque;
 
-    return avctx->get_buffer(avctx, frame);
-}
+#if FF_API_GET_BUFFER
+    /*
+     * Wrap an old get_buffer()-allocated buffer in an 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().
+     */
+    if (avctx->get_buffer) {
+        CompatReleaseBufPriv *priv = NULL;
+        AVBufferRef *dummy_buf = NULL;
+        int planes, i, ret;
 
-void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)
-{
-    int i;
-    InternalBuffer *buf, *last;
-    AVCodecInternal *avci = s->internal;
+        if (flags & AV_GET_BUFFER_FLAG_REF)
+            frame->reference    = 1;
 
-    assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
+        ret = avctx->get_buffer(avctx, frame);
+        if (ret < 0)
+            return ret;
 
-    assert(pic->type == FF_BUFFER_TYPE_INTERNAL);
-    assert(avci->buffer_count);
+        /* 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])
+            return 0;
+
+        priv = av_mallocz(sizeof(*priv));
+        if (!priv) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        priv->avctx = *avctx;
+        priv->frame = *frame;
 
-    if (avci->buffer) {
-        buf = NULL; /* avoids warning */
-        for (i = 0; i < avci->buffer_count; i++) { //just 3-5 checks so is not worth to optimize
-            buf = &avci->buffer[i];
-            if (buf->data[0] == pic->data[0])
-                break;
+        dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, priv, 0);
+        if (!dummy_buf) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
         }
-        assert(i < avci->buffer_count);
-        avci->buffer_count--;
-        last = &avci->buffer[avci->buffer_count];
 
-        if (buf != last)
-            FFSWAP(InternalBuffer, *buf, *last);
-    }
+#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_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);
+
+            if (!desc) {
+                ret = AVERROR(EINVAL);
+                goto fail;
+            }
+            planes = (desc->flags & PIX_FMT_PLANAR) ? desc->nb_components : 1;
 
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
-        pic->data[i] = NULL;
-//        pic->base[i]=NULL;
+            for (i = 0; i < planes; i++) {
+                int h_shift    = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
+                int plane_size = (frame->width >> h_shift) * frame->linesize[i];
 
-    if (s->debug & FF_DEBUG_BUFFERS)
-        av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d "
-                                "buffers used\n", pic, avci->buffer_count);
-}
+                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(sizeof(*frame->extended_buf) *
+                                                frame->nb_extended_buf);
+                if (!frame->extended_buf) {
+                    ret = AVERROR(ENOMEM);
+                    goto fail;
+                }
+            }
 
-int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic)
-{
-    AVFrame temp_pic;
-    int i;
+            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 < planes - FF_ARRAY_ELEMS(frame->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);
 
-    assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
+        return 0;
 
-    /* If no picture return a new buffer */
-    if (pic->data[0] == NULL) {
-        /* We will copy from buffer, so must be readable */
-        pic->buffer_hints |= FF_BUFFER_HINTS_READABLE;
-        return ff_get_buffer(s, pic);
+fail:
+        avctx->release_buffer(avctx, frame);
+        av_freep(&priv);
+        av_buffer_unref(&dummy_buf);
+        return ret;
     }
+#endif
+
+    return avctx->get_buffer2(avctx, frame, flags);
+}
+
+int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    AVFrame tmp;
+    int ret;
 
-    assert(s->pix_fmt == pic->format);
+    av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO);
+
+    if (!frame->data[0])
+        return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
 
-    /* If internal buffer type return the same buffer */
-    if (pic->type == FF_BUFFER_TYPE_INTERNAL) {
-        if (s->pkt)
-            pic->pkt_pts = s->pkt->pts;
-        else
-            pic->pkt_pts = AV_NOPTS_VALUE;
-        pic->reordered_opaque = s->reordered_opaque;
+    if (av_frame_is_writable(frame))
         return 0;
+
+    av_frame_move_ref(&tmp, frame);
+
+    ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
+    if (ret < 0) {
+        av_frame_unref(&tmp);
+        return ret;
     }
 
-    /*
-     * Not internal type and reget_buffer not overridden, emulate cr buffer
-     */
-    temp_pic = *pic;
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
-        pic->data[i] = pic->base[i] = NULL;
-    pic->opaque = NULL;
-    /* Allocate new frame */
-    if (ff_get_buffer(s, pic))
-        return -1;
-    /* Copy image data from old buffer to new buffer */
-    av_picture_copy((AVPicture *)pic, (AVPicture *)&temp_pic, s->pix_fmt, s->width,
-                    s->height);
-    s->release_buffer(s, &temp_pic); // Release old frame
+    av_image_copy(frame->data, frame->linesize, tmp.data, tmp.linesize,
+                  frame->format, frame->width, frame->height);
+
+    av_frame_unref(&tmp);
+
     return 0;
 }
 
+#if FF_API_GET_BUFFER
+void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)
+{
+    av_frame_unref(pic);
+}
+
+int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic)
+{
+    av_assert0(0);
+}
+#endif
+
 int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size)
 {
     int i;
@@ -691,6 +845,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code
         goto end;
     }
 
+    avctx->internal->pool = av_mallocz(sizeof(*avctx->internal->pool));
+    if (!avctx->internal->pool) {
+        ret = AVERROR(ENOMEM);
+        goto free_and_end;
+    }
+
     if (codec->priv_data_size > 0) {
         if (!avctx->priv_data) {
             avctx->priv_data = av_mallocz(codec->priv_data_size);
@@ -876,6 +1036,8 @@ end:
 free_and_end:
     av_dict_free(&tmp);
     av_freep(&avctx->priv_data);
+    if (avctx->internal)
+        av_freep(&avctx->internal->pool);
     av_freep(&avctx->internal);
     avctx->codec = NULL;
     goto end;
@@ -1279,6 +1441,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
                                               int *got_picture_ptr,
                                               AVPacket *avpkt)
 {
+    AVCodecInternal *avci = avctx->internal;
     int ret;
 
     *got_picture_ptr = 0;
@@ -1290,6 +1453,9 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
 
     avcodec_get_frame_defaults(picture);
 
+    if (!avctx->refcounted_frames)
+        av_frame_unref(&avci->to_free);
+
     if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
         if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
             ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
@@ -1309,8 +1475,17 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
 
         emms_c(); //needed to avoid an emms_c() call before every return;
 
-        if (*got_picture_ptr)
+        if (ret < 0 && picture->data[0])
+            av_frame_unref(picture);
+
+        if (*got_picture_ptr) {
+            if (!avctx->refcounted_frames) {
+                avci->to_free = *picture;
+                avci->to_free.extended_data = avci->to_free.data;
+            }
+
             avctx->frame_number++;
+        }
     } else
         ret = 0;
 
@@ -1374,6 +1549,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
                                               int *got_frame_ptr,
                                               AVPacket *avpkt)
 {
+    AVCodecInternal *avci = avctx->internal;
     int planar, channels;
     int ret = 0;
 
@@ -1390,6 +1566,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
 
     avcodec_get_frame_defaults(frame);
 
+    if (!avctx->refcounted_frames)
+        av_frame_unref(&avci->to_free);
+
     if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
         ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt);
         if (ret >= 0 && *got_frame_ptr) {
@@ -1397,7 +1576,15 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
             frame->pkt_dts = avpkt->dts;
             if (frame->format == AV_SAMPLE_FMT_NONE)
                 frame->format = avctx->sample_fmt;
+
+            if (!avctx->refcounted_frames) {
+                avci->to_free = *frame;
+                avci->to_free.extended_data = avci->to_free.data;
+            }
         }
+
+        if (ret < 0 && frame->data[0])
+            av_frame_unref(frame);
     }
 
     /* many decoders assign whole AVFrames, thus overwriting extended_data;
@@ -1460,12 +1647,18 @@ av_cold int avcodec_close(AVCodecContext *avctx)
     }
 
     if (avcodec_is_open(avctx)) {
+        FramePool *pool = avctx->internal->pool;
+        int i;
         if (HAVE_THREADS && avctx->thread_opaque)
             ff_thread_free(avctx);
         if (avctx->codec && avctx->codec->close)
             avctx->codec->close(avctx);
-        avcodec_default_free_buffers(avctx);
         avctx->coded_frame = NULL;
+        if (!avctx->refcounted_frames)
+            av_frame_unref(&avctx->internal->to_free);
+        for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)
+            av_buffer_pool_uninit(&pool->pools[i]);
+        av_freep(&avctx->internal->pool);
         av_freep(&avctx->internal);
     }
 
@@ -1739,49 +1932,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
         avctx->codec->flush(avctx);
 }
 
-static void video_free_buffers(AVCodecContext *s)
-{
-    AVCodecInternal *avci = s->internal;
-    int i, j;
-
-    if (!avci->buffer)
-        return;
-
-    if (avci->buffer_count)
-        av_log(s, AV_LOG_WARNING, "Found %i unreleased buffers!\n",
-               avci->buffer_count);
-    for (i = 0; i < INTERNAL_BUFFER_SIZE; i++) {
-        InternalBuffer *buf = &avci->buffer[i];
-        for (j = 0; j < 4; j++) {
-            av_freep(&buf->base[j]);
-            buf->data[j] = NULL;
-        }
-    }
-    av_freep(&avci->buffer);
-
-    avci->buffer_count = 0;
-}
-
-static void audio_free_buffers(AVCodecContext *avctx)
-{
-    AVCodecInternal *avci = avctx->internal;
-    av_freep(&avci->audio_data);
-}
-
-void avcodec_default_free_buffers(AVCodecContext *avctx)
-{
-    switch (avctx->codec_type) {
-    case AVMEDIA_TYPE_VIDEO:
-        video_free_buffers(avctx);
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        audio_free_buffers(avctx);
-        break;
-    default:
-        break;
-    }
-}
-
 int av_get_exact_bits_per_sample(enum AVCodecID codec_id)
 {
     switch (codec_id) {
@@ -2117,17 +2267,36 @@ unsigned int avpriv_toupper4(unsigned int x)
           (av_toupper((x >> 24) & 0xFF) << 24);
 }
 
+int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src)
+{
+    int ret;
+
+    dst->owner = src->owner;
+
+    ret = av_frame_ref(dst->f, src->f);
+    if (ret < 0)
+        return ret;
+
+    if (src->progress &&
+        !(dst->progress = av_buffer_ref(src->progress))) {
+        ff_thread_release_buffer(dst->owner, dst);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
 #if !HAVE_THREADS
 
-int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
+int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
 {
     f->owner = avctx;
-    return ff_get_buffer(avctx, f);
+    return ff_get_buffer(avctx, f, flags);
 }
 
 void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
 {
-    f->owner->release_buffer(f->owner, f);
+    av_frame_unref(f);
 }
 
 void ff_thread_finish_setup(AVCodecContext *avctx)
index 0d7664c82278c911046490917920161dce183973..0a1317e8076ebcdbd822abe7137516cfb48ff963 100644 (file)
@@ -65,7 +65,6 @@ extern const int ff_ut_rgb_order[4];
 
 typedef struct UtvideoContext {
     AVCodecContext *avctx;
-    AVFrame        pic;
     DSPContext     dsp;
 
     uint32_t frame_info_size, flags, frame_info;
index 3f8f690ee04720a831ee7d2399ea3e7ad54413b3..06f3108eebb0a4460338d473601ba750d8fd4ccb 100644 (file)
@@ -331,13 +331,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size;
     int ret;
     GetByteContext gb;
+    ThreadFrame frame = { .f = data };
 
-    if (c->pic.data[0])
-        ff_thread_release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_thread_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -396,42 +392,42 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     case AV_PIX_FMT_RGB24:
     case AV_PIX_FMT_RGBA:
         for (i = 0; i < c->planes; i++) {
-            ret = decode_plane(c, i, c->pic.data[0] + ff_ut_rgb_order[i],
-                               c->planes, c->pic.linesize[0], avctx->width,
+            ret = decode_plane(c, i, frame.f->data[0] + ff_ut_rgb_order[i],
+                               c->planes, frame.f->linesize[0], avctx->width,
                                avctx->height, plane_start[i],
                                c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median(c->pic.data[0] + ff_ut_rgb_order[i],
-                                   c->planes, c->pic.linesize[0], avctx->width,
+                    restore_median(frame.f->data[0] + ff_ut_rgb_order[i],
+                                   c->planes, frame.f->linesize[0], avctx->width,
                                    avctx->height, c->slices, 0);
                 } else {
-                    restore_median_il(c->pic.data[0] + ff_ut_rgb_order[i],
-                                      c->planes, c->pic.linesize[0],
+                    restore_median_il(frame.f->data[0] + ff_ut_rgb_order[i],
+                                      c->planes, frame.f->linesize[0],
                                       avctx->width, avctx->height, c->slices,
                                       0);
                 }
             }
         }
-        restore_rgb_planes(c->pic.data[0], c->planes, c->pic.linesize[0],
+        restore_rgb_planes(frame.f->data[0], c->planes, frame.f->linesize[0],
                            avctx->width, avctx->height);
         break;
     case AV_PIX_FMT_YUV420P:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane(c, i, c->pic.data[i], 1, c->pic.linesize[i],
+            ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i],
                                avctx->width >> !!i, avctx->height >> !!i,
                                plane_start[i], c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median(frame.f->data[i], 1, frame.f->linesize[i],
                                    avctx->width >> !!i, avctx->height >> !!i,
                                    c->slices, !i);
                 } else {
-                    restore_median_il(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median_il(frame.f->data[i], 1, frame.f->linesize[i],
                                       avctx->width  >> !!i,
                                       avctx->height >> !!i,
                                       c->slices, !i);
@@ -441,18 +437,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     case AV_PIX_FMT_YUV422P:
         for (i = 0; i < 3; i++) {
-            ret = decode_plane(c, i, c->pic.data[i], 1, c->pic.linesize[i],
+            ret = decode_plane(c, i, frame.f->data[i], 1, frame.f->linesize[i],
                                avctx->width >> !!i, avctx->height,
                                plane_start[i], c->frame_pred == PRED_LEFT);
             if (ret)
                 return ret;
             if (c->frame_pred == PRED_MEDIAN) {
                 if (!c->interlaced) {
-                    restore_median(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median(frame.f->data[i], 1, frame.f->linesize[i],
                                    avctx->width >> !!i, avctx->height,
                                    c->slices, 0);
                 } else {
-                    restore_median_il(c->pic.data[i], 1, c->pic.linesize[i],
+                    restore_median_il(frame.f->data[i], 1, frame.f->linesize[i],
                                       avctx->width >> !!i, avctx->height,
                                       c->slices, 0);
                 }
@@ -461,12 +457,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         break;
     }
 
-    c->pic.key_frame = 1;
-    c->pic.pict_type = AV_PICTURE_TYPE_I;
-    c->pic.interlaced_frame = !!c->interlaced;
+    frame.f->key_frame = 1;
+    frame.f->pict_type = AV_PICTURE_TYPE_I;
+    frame.f->interlaced_frame = !!c->interlaced;
 
-    *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
+    *got_frame = 1;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -534,9 +529,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     UtvideoContext * const c = avctx->priv_data;
 
-    if (c->pic.data[0])
-        ff_thread_release_buffer(avctx, &c->pic);
-
     av_freep(&c->slice_bits);
 
     return 0;
index 2a6aa613763ead7ee9126b5e6df76954c31645a5..b8b647e6f6e9b7c32fb41a0d95f2753384e0c0e5 100644 (file)
@@ -36,10 +36,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     avctx->pix_fmt             = AV_PIX_FMT_YUV422P10;
     avctx->bits_per_raw_sample = 10;
 
-    avctx->coded_frame         = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
     return 0;
 }
 
@@ -47,22 +43,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     int h, w, ret;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *psrc = avpkt->data;
     uint16_t *y, *u, *v;
     int aligned_width = ((avctx->width + 47) / 48) * 48;
     int stride = aligned_width * 8 / 3;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < stride * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
         return AVERROR_INVALIDDATA;
     }
 
-    pic->reference = 0;
-    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     y = (uint16_t*)pic->data[0];
@@ -110,27 +102,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = *avctx->coded_frame;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_v210_decoder = {
     .name           = "v210",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_V210,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
index 97938b1090d1729a46a91a24c2560571ec3dfeee..758294c5bb73c9c6ed5ba764764258dda828b44f 100644 (file)
@@ -33,8 +33,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     avctx->pix_fmt             = AV_PIX_FMT_YUV422P16;
     avctx->bits_per_raw_sample = 10;
 
-    avctx->coded_frame= avcodec_alloc_frame();
-
     return 0;
 }
 
@@ -42,15 +40,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     const uint32_t *src = (const uint32_t *)avpkt->data;
-    AVFrame *pic        = avctx->coded_frame;
+    AVFrame *pic        = data;
     int width           = avctx->width;
     int y               = 0;
     uint16_t *ydst, *udst, *vdst, *yend;
     int ret;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < avctx->width * avctx->height * 8 / 3) {
         av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
         return AVERROR_INVALIDDATA;
@@ -60,8 +55,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         av_log_ask_for_sample(avctx, "Probably padded data\n");
     }
 
-    pic->reference = 0;
-    if ((ret = ff_get_buffer(avctx, pic)) < 0)
+    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
         return ret;
 
     ydst = (uint16_t *)pic->data[0];
@@ -122,27 +116,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data= *avctx->coded_frame;
 
     return avpkt->size;
 }
 
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    AVFrame *pic = avctx->coded_frame;
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_v210x_decoder = {
     .name           = "v210x",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_V210X,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
index efd20931346e195d1616d5a0e29dbeb8a816286c..e4b2a7ded3985d1a643281be92d352c0484961c4 100644 (file)
@@ -39,36 +39,24 @@ static av_cold int v410_decode_init(AVCodecContext *avctx)
         }
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
-
-    if (!avctx->coded_frame) {
-        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
-        return AVERROR(ENOMEM);
-    }
-
     return 0;
 }
 
 static int v410_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     uint8_t *src = avpkt->data;
     uint16_t *y, *u, *v;
     uint32_t val;
     int i, j;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < 4 * avctx->height * avctx->width) {
         av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
         return AVERROR(EINVAL);
     }
 
-    pic->reference = 0;
-
-    if (ff_get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -97,28 +85,16 @@ static int v410_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
 
-static av_cold int v410_decode_close(AVCodecContext *avctx)
-{
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_v410_decoder = {
     .name         = "v410",
     .type         = AVMEDIA_TYPE_VIDEO,
     .id           = AV_CODEC_ID_V410,
     .init         = v410_decode_init,
     .decode       = v410_decode_frame,
-    .close        = v410_decode_close,
     .capabilities = CODEC_CAP_DR1,
     .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed 4:4:4 10-bit"),
 };
index f34982cc73d21ac57b6cdeea0d98af47951ede4a..7cbe8c1826557439c3a317eb8ee4fd9154fa57fe 100644 (file)
@@ -55,7 +55,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic,
                            int            pic_structure)
 {
     if (pic_structure == 0)
-        pic_structure = pic->f.reference;
+        pic_structure = pic->reference;
     pic_structure &= PICT_FRAME; /* PICT_TOP_FIELD|PICT_BOTTOM_FIELD */
 
     va_pic->picture_id = ff_vaapi_get_surface_id(pic);
@@ -64,7 +64,7 @@ static void fill_vaapi_pic(VAPictureH264 *va_pic,
     va_pic->flags      = 0;
     if (pic_structure != PICT_FRAME)
         va_pic->flags |= (pic_structure & PICT_TOP_FIELD) ? VA_PICTURE_H264_TOP_FIELD : VA_PICTURE_H264_BOTTOM_FIELD;
-    if (pic->f.reference)
+    if (pic->reference)
         va_pic->flags |= pic->long_ref ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE;
 
     va_pic->TopFieldOrderCnt = 0;
@@ -134,13 +134,13 @@ static int fill_vaapi_ReferenceFrames(VAPictureParameterBufferH264 *pic_param,
 
     for (i = 0; i < h->short_ref_count; i++) {
         Picture * const pic = h->short_ref[i];
-        if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0)
+        if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
             return -1;
     }
 
     for (i = 0; i < 16; i++) {
         Picture * const pic = h->long_ref[i];
-        if (pic && pic->f.reference && dpb_add(&dpb, pic) < 0)
+        if (pic && pic->reference && dpb_add(&dpb, pic) < 0)
             return -1;
     }
     return 0;
@@ -160,7 +160,7 @@ static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32],
 {
     unsigned int i, n = 0;
     for (i = 0; i < ref_count; i++)
-        if (ref_list[i].f.reference)
+        if (ref_list[i].reference)
             fill_vaapi_pic(&RefPicList[n++], &ref_list[i], 0);
 
     for (; n < 32; n++)
index 8bb1a70cc19e98d9999ecbdacc6c36f22a66900e..df0fef98d285843c50e2cf69620636f82946a177 100644 (file)
@@ -41,7 +41,6 @@ enum VBFlags {
 
 typedef struct VBDecContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     uint8_t *frame, *prev_frame;
     uint32_t pal[AVPALETTE_COUNT];
@@ -189,6 +188,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     VBDecContext * const c = avctx->priv_data;
+    AVFrame *frame         = data;
     uint8_t *outptr, *srcptr;
     int i, j, ret;
     int flags;
@@ -197,10 +197,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     bytestream2_init(&c->stream, avpkt->data, avpkt->size);
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    c->pic.reference = 1;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -222,22 +219,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         vb_decode_palette(c, size);
     }
 
-    memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
-    c->pic.palette_has_changed = flags & VB_HAS_PALETTE;
+    memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
+    frame->palette_has_changed = flags & VB_HAS_PALETTE;
 
-    outptr = c->pic.data[0];
+    outptr = frame->data[0];
     srcptr = c->frame;
 
     for (i = 0; i < avctx->height; i++) {
         memcpy(outptr, srcptr, avctx->width);
         srcptr += avctx->width;
-        outptr += c->pic.linesize[0];
+        outptr += frame->linesize[0];
     }
 
     FFSWAP(uint8_t*, c->frame, c->prev_frame);
 
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return avpkt->size;
@@ -262,8 +258,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
     av_freep(&c->frame);
     av_freep(&c->prev_frame);
-    if(c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
 
     return 0;
 }
index 228b1bd61a963dfa8f49ab3d0e662790e0af3af9..6cd2dfc2e537868ebc12557991b0a4b0ad315b1c 100644 (file)
@@ -84,10 +84,10 @@ static int vble_unpack(VBLEContext *ctx, GetBitContext *gb)
     return 0;
 }
 
-static void vble_restore_plane(VBLEContext *ctx, int plane, int offset,
-                              int width, int height)
+static void vble_restore_plane(VBLEContext *ctx, AVFrame *pic,
+                               int plane, int offset,
+                               int width, int height)
 {
-    AVFrame *pic = ctx->avctx->coded_frame;
     uint8_t *dst = pic->data[plane];
     uint8_t *val = ctx->val + offset;
     int stride = pic->linesize[plane];
@@ -116,21 +116,15 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                              AVPacket *avpkt)
 {
     VBLEContext *ctx = avctx->priv_data;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic     = data;
     GetBitContext gb;
     const uint8_t *src = avpkt->data;
     int version;
     int offset = 0;
     int width_uv = avctx->width / 2, height_uv = avctx->height / 2;
 
-    pic->reference = 0;
-
-    /* Clear buffer if need be */
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     /* Allocate buffer */
-    if (ff_get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -154,19 +148,18 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     /* Restore planes. Should be almost identical to Huffyuv's. */
-    vble_restore_plane(ctx, 0, offset, avctx->width, avctx->height);
+    vble_restore_plane(ctx, pic, 0, offset, avctx->width, avctx->height);
 
     /* Chroma */
     if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
         offset += avctx->width * avctx->height;
-        vble_restore_plane(ctx, 1, offset, width_uv, height_uv);
+        vble_restore_plane(ctx, pic, 1, offset, width_uv, height_uv);
 
         offset += width_uv * height_uv;
-        vble_restore_plane(ctx, 2, offset, width_uv, height_uv);
+        vble_restore_plane(ctx, pic, 2, offset, width_uv, height_uv);
     }
 
     *got_frame       = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
@@ -174,12 +167,6 @@ static int vble_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 static av_cold int vble_decode_close(AVCodecContext *avctx)
 {
     VBLEContext *ctx = avctx->priv_data;
-    AVFrame *pic = avctx->coded_frame;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    av_freep(&avctx->coded_frame);
     av_freep(&ctx->val);
 
     return 0;
@@ -195,12 +182,6 @@ static av_cold int vble_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     avctx->bits_per_raw_sample = 8;
-    avctx->coded_frame = avcodec_alloc_frame();
-
-    if (!avctx->coded_frame) {
-        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
-        return AVERROR(ENOMEM);
-    }
 
     ctx->size = avpicture_get_size(avctx->pix_fmt,
                                    avctx->width, avctx->height);
index adfd699ac8942175720c67ef4dc7b1e7cbea514a..44dd65228368a8ca96a1d9c6de020187da924b86 100644 (file)
@@ -348,8 +348,8 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
 
     // store motion vectors for further use in B frames
     if (s->pict_type == AV_PICTURE_TYPE_P) {
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = my;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = mx;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = my;
     }
 
     uvmx = (mx + ((mx & 3) == 3)) >> 1;
@@ -604,8 +604,8 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
             ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;
             break;
         }
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
         for (k = 0; k < 4; k++)
             v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
     }
@@ -798,8 +798,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
         valid_count = get_chroma_mv(mvx, mvy, intra, 0, &tx, &ty);
         chroma_ref_type = v->reffield;
         if (!valid_count) {
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
             return; //no need to do MC for intra blocks
         }
@@ -813,8 +813,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir)
     }
     if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f.data[0])
         return;
-    s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
-    s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
+    s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
+    s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
     uvmx = (tx + ((tx & 3) == 3)) >> 1;
     uvmy = (ty + ((ty & 3) == 3)) >> 1;
 
@@ -1376,30 +1376,30 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
     xy   = s->block_index[n];
 
     if (s->mb_intra) {
-        s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = 0;
-        s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = 0;
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = 0;
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
+        s->mv[0][n][0] = s->current_picture.motion_val[0][xy + v->blocks_off][0] = 0;
+        s->mv[0][n][1] = s->current_picture.motion_val[0][xy + v->blocks_off][1] = 0;
+        s->current_picture.motion_val[1][xy + v->blocks_off][0] = 0;
+        s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
         if (mv1) { /* duplicate motion data for 1-MV block */
-            s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][0]        = 0;
-            s->current_picture.f.motion_val[0][xy + 1 + v->blocks_off][1]        = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][0]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + v->blocks_off][1]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
+            s->current_picture.motion_val[0][xy + 1 + v->blocks_off][0]        = 0;
+            s->current_picture.motion_val[0][xy + 1 + v->blocks_off][1]        = 0;
+            s->current_picture.motion_val[0][xy + wrap + v->blocks_off][0]     = 0;
+            s->current_picture.motion_val[0][xy + wrap + v->blocks_off][1]     = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1 + v->blocks_off][1] = 0;
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
-            s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][0]        = 0;
-            s->current_picture.f.motion_val[1][xy + 1 + v->blocks_off][1]        = 0;
-            s->current_picture.f.motion_val[1][xy + wrap][0]                     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + v->blocks_off][1]     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
+            s->current_picture.motion_val[1][xy + 1 + v->blocks_off][0]        = 0;
+            s->current_picture.motion_val[1][xy + 1 + v->blocks_off][1]        = 0;
+            s->current_picture.motion_val[1][xy + wrap][0]                     = 0;
+            s->current_picture.motion_val[1][xy + wrap + v->blocks_off][1]     = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1 + v->blocks_off][1] = 0;
         }
         return;
     }
 
-    C = s->current_picture.f.motion_val[dir][xy -    1 + v->blocks_off];
-    A = s->current_picture.f.motion_val[dir][xy - wrap + v->blocks_off];
+    C = s->current_picture.motion_val[dir][xy -    1 + v->blocks_off];
+    A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
     if (mv1) {
         if (v->field_mode && mixedmv_pic)
             off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
@@ -1421,7 +1421,7 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
             off = -1;
         }
     }
-    B = s->current_picture.f.motion_val[dir][xy - wrap + off + v->blocks_off];
+    B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
 
     a_valid = !s->first_slice_line || (n == 2 || n == 3);
     b_valid = a_valid && (s->mb_width > 1);
@@ -1584,15 +1584,15 @@ static inline void vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
     if (v->field_mode && v->cur_field_type && v->ref_field_type[dir] == 0)
         y_bias = 1;
     /* store MV using signed modulus of MV range defined in 4.11 */
-    s->mv[dir][n][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
-    s->mv[dir][n][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
+    s->mv[dir][n][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+    s->mv[dir][n][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1] = ((py + dmv_y + r_y - y_bias) & ((r_y << 1) - 1)) - r_y + y_bias;
     if (mv1) { /* duplicate motion data for 1-MV block */
-        s->current_picture.f.motion_val[dir][xy +    1 +     v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
-        s->current_picture.f.motion_val[dir][xy +    1 +     v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
-        s->current_picture.f.motion_val[dir][xy + wrap +     v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
-        s->current_picture.f.motion_val[dir][xy + wrap +     v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
-        s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][0];
-        s->current_picture.f.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.f.motion_val[dir][xy + v->blocks_off][1];
+        s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+        s->current_picture.motion_val[dir][xy +    1 +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+        s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+        s->current_picture.motion_val[dir][xy + wrap +     v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
+        s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][0] = s->current_picture.motion_val[dir][xy + v->blocks_off][0];
+        s->current_picture.motion_val[dir][xy + wrap + 1 + v->blocks_off][1] = s->current_picture.motion_val[dir][xy + v->blocks_off][1];
         v->mv_f[dir][xy +    1 + v->blocks_off] = v->mv_f[dir][xy +            v->blocks_off];
         v->mv_f[dir][xy + wrap + v->blocks_off] = v->mv_f[dir][xy + wrap + 1 + v->blocks_off] = v->mv_f[dir][xy + v->blocks_off];
     }
@@ -1616,24 +1616,24 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     xy = s->block_index[n];
 
     if (s->mb_intra) {
-        s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = 0;
-        s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = 0;
-        s->current_picture.f.motion_val[1][xy][0] = 0;
-        s->current_picture.f.motion_val[1][xy][1] = 0;
+        s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = 0;
+        s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = 0;
+        s->current_picture.motion_val[1][xy][0] = 0;
+        s->current_picture.motion_val[1][xy][1] = 0;
         if (mvn == 1) { /* duplicate motion data for 1-MV block */
-            s->current_picture.f.motion_val[0][xy + 1][0]        = 0;
-            s->current_picture.f.motion_val[0][xy + 1][1]        = 0;
-            s->current_picture.f.motion_val[0][xy + wrap][0]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap][1]     = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1][0] = 0;
-            s->current_picture.f.motion_val[0][xy + wrap + 1][1] = 0;
+            s->current_picture.motion_val[0][xy + 1][0]        = 0;
+            s->current_picture.motion_val[0][xy + 1][1]        = 0;
+            s->current_picture.motion_val[0][xy + wrap][0]     = 0;
+            s->current_picture.motion_val[0][xy + wrap][1]     = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1][0] = 0;
+            s->current_picture.motion_val[0][xy + wrap + 1][1] = 0;
             v->luma_mv[s->mb_x][0] = v->luma_mv[s->mb_x][1] = 0;
-            s->current_picture.f.motion_val[1][xy + 1][0]        = 0;
-            s->current_picture.f.motion_val[1][xy + 1][1]        = 0;
-            s->current_picture.f.motion_val[1][xy + wrap][0]     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap][1]     = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1][0] = 0;
-            s->current_picture.f.motion_val[1][xy + wrap + 1][1] = 0;
+            s->current_picture.motion_val[1][xy + 1][0]        = 0;
+            s->current_picture.motion_val[1][xy + 1][1]        = 0;
+            s->current_picture.motion_val[1][xy + wrap][0]     = 0;
+            s->current_picture.motion_val[1][xy + wrap][1]     = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1][0] = 0;
+            s->current_picture.motion_val[1][xy + wrap + 1][1] = 0;
         }
         return;
     }
@@ -1643,14 +1643,14 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     if (s->mb_x || (n == 1) || (n == 3)) {
         if ((v->blk_mv_type[xy]) // current block (MB) has a field MV
             || (!v->blk_mv_type[xy] && !v->blk_mv_type[xy - 1])) { // or both have frame MV
-            A[0] = s->current_picture.f.motion_val[0][xy - 1][0];
-            A[1] = s->current_picture.f.motion_val[0][xy - 1][1];
+            A[0] = s->current_picture.motion_val[0][xy - 1][0];
+            A[1] = s->current_picture.motion_val[0][xy - 1][1];
             a_valid = 1;
         } else { // current block has frame mv and cand. has field MV (so average)
-            A[0] = (s->current_picture.f.motion_val[0][xy - 1][0]
-                    + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][0] + 1) >> 1;
-            A[1] = (s->current_picture.f.motion_val[0][xy - 1][1]
-                    + s->current_picture.f.motion_val[0][xy - 1 + off * wrap][1] + 1) >> 1;
+            A[0] = (s->current_picture.motion_val[0][xy - 1][0]
+                    + s->current_picture.motion_val[0][xy - 1 + off * wrap][0] + 1) >> 1;
+            A[1] = (s->current_picture.motion_val[0][xy - 1][1]
+                    + s->current_picture.motion_val[0][xy - 1 + off * wrap][1] + 1) >> 1;
             a_valid = 1;
         }
         if (!(n & 1) && v->is_intra[s->mb_x - 1]) {
@@ -1670,11 +1670,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
                 if (v->blk_mv_type[pos_b] && v->blk_mv_type[xy]) {
                     n_adj = (n & 2) | (n & 1);
                 }
-                B[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][0];
-                B[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap][1];
+                B[0] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap][0];
+                B[1] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap][1];
                 if (v->blk_mv_type[pos_b] && !v->blk_mv_type[xy]) {
-                    B[0] = (B[0] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
-                    B[1] = (B[1] + s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
+                    B[0] = (B[0] + s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][0] + 1) >> 1;
+                    B[1] = (B[1] + s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap][1] + 1) >> 1;
                 }
             }
             if (s->mb_width > 1) {
@@ -1685,11 +1685,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
                     if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
                         n_adj = n & 2;
                     }
-                    C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][0];
-                    C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][1];
+                    C[0] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][0];
+                    C[1] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap + 2][1];
                     if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
-                        C[0] = (1 + C[0] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
-                        C[1] = (1 + C[1] + (s->current_picture.f.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
+                        C[0] = (1 + C[0] + (s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][0])) >> 1;
+                        C[1] = (1 + C[1] + (s->current_picture.motion_val[0][s->block_index[n_adj ^ 2] - 2 * wrap + 2][1])) >> 1;
                     }
                     if (s->mb_x == s->mb_width - 1) {
                         if (!v->is_intra[s->mb_x - s->mb_stride - 1]) {
@@ -1699,11 +1699,11 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
                             if (v->blk_mv_type[pos_c] && v->blk_mv_type[xy]) {
                                 n_adj = n | 1;
                             }
-                            C[0] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][0];
-                            C[1] = s->current_picture.f.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][1];
+                            C[0] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][0];
+                            C[1] = s->current_picture.motion_val[0][s->block_index[n_adj] - 2 * wrap - 2][1];
                             if (v->blk_mv_type[pos_c] && !v->blk_mv_type[xy]) {
-                                C[0] = (1 + C[0] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
-                                C[1] = (1 + C[1] + s->current_picture.f.motion_val[0][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
+                                C[0] = (1 + C[0] + s->current_picture.motion_val[0][s->block_index[1] - 2 * wrap - 2][0]) >> 1;
+                                C[1] = (1 + C[1] + s->current_picture.motion_val[0][s->block_index[1] - 2 * wrap - 2][1]) >> 1;
                             }
                         } else
                             c_valid = 0;
@@ -1714,12 +1714,12 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     } else {
         pos_b   = s->block_index[1];
         b_valid = 1;
-        B[0]    = s->current_picture.f.motion_val[0][pos_b][0];
-        B[1]    = s->current_picture.f.motion_val[0][pos_b][1];
+        B[0]    = s->current_picture.motion_val[0][pos_b][0];
+        B[1]    = s->current_picture.motion_val[0][pos_b][1];
         pos_c   = s->block_index[0];
         c_valid = 1;
-        C[0]    = s->current_picture.f.motion_val[0][pos_c][0];
-        C[1]    = s->current_picture.f.motion_val[0][pos_c][1];
+        C[0]    = s->current_picture.motion_val[0][pos_c][0];
+        C[1]    = s->current_picture.motion_val[0][pos_c][1];
     }
 
     total_valid = a_valid + b_valid + c_valid;
@@ -1807,18 +1807,18 @@ static inline void vc1_pred_mv_intfr(VC1Context *v, int n, int dmv_x, int dmv_y,
     }
 
     /* store MV using signed modulus of MV range defined in 4.11 */
-    s->mv[0][n][0] = s->current_picture.f.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
-    s->mv[0][n][1] = s->current_picture.f.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
+    s->mv[0][n][0] = s->current_picture.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+    s->mv[0][n][1] = s->current_picture.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
     if (mvn == 1) { /* duplicate motion data for 1-MV block */
-        s->current_picture.f.motion_val[0][xy +    1    ][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy +    1    ][1] = s->current_picture.f.motion_val[0][xy][1];
-        s->current_picture.f.motion_val[0][xy + wrap    ][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy + wrap    ][1] = s->current_picture.f.motion_val[0][xy][1];
-        s->current_picture.f.motion_val[0][xy + wrap + 1][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy + wrap + 1][1] = s->current_picture.f.motion_val[0][xy][1];
+        s->current_picture.motion_val[0][xy +    1    ][0] = s->current_picture.motion_val[0][xy][0];
+        s->current_picture.motion_val[0][xy +    1    ][1] = s->current_picture.motion_val[0][xy][1];
+        s->current_picture.motion_val[0][xy + wrap    ][0] = s->current_picture.motion_val[0][xy][0];
+        s->current_picture.motion_val[0][xy + wrap    ][1] = s->current_picture.motion_val[0][xy][1];
+        s->current_picture.motion_val[0][xy + wrap + 1][0] = s->current_picture.motion_val[0][xy][0];
+        s->current_picture.motion_val[0][xy + wrap + 1][1] = s->current_picture.motion_val[0][xy][1];
     } else if (mvn == 2) { /* duplicate motion data for 2-Field MV block */
-        s->current_picture.f.motion_val[0][xy + 1][0] = s->current_picture.f.motion_val[0][xy][0];
-        s->current_picture.f.motion_val[0][xy + 1][1] = s->current_picture.f.motion_val[0][xy][1];
+        s->current_picture.motion_val[0][xy + 1][0] = s->current_picture.motion_val[0][xy][0];
+        s->current_picture.motion_val[0][xy + 1][1] = s->current_picture.motion_val[0][xy][1];
         s->mv[0][n + 1][0] = s->mv[0][n][0];
         s->mv[0][n + 1][1] = s->mv[0][n][1];
     }
@@ -2041,17 +2041,17 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
     xy = s->block_index[0];
 
     if (s->mb_intra) {
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][0] =
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][1] =
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][0] =
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = 0;
+        s->current_picture.motion_val[0][xy + v->blocks_off][0] =
+        s->current_picture.motion_val[0][xy + v->blocks_off][1] =
+        s->current_picture.motion_val[1][xy + v->blocks_off][0] =
+        s->current_picture.motion_val[1][xy + v->blocks_off][1] = 0;
         return;
     }
     if (!v->field_mode) {
-        s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
-        s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
-        s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
-        s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
+        s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
+        s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 0, s->quarter_sample);
+        s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][xy][0], v->bfraction, 1, s->quarter_sample);
+        s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][xy][1], v->bfraction, 1, s->quarter_sample);
 
         /* Pullback predicted motion vectors as specified in 8.4.5.4 */
         s->mv[0][0][0] = av_clip(s->mv[0][0][0], -60 - (s->mb_x << 6), (s->mb_width  << 6) - 4 - (s->mb_x << 6));
@@ -2060,18 +2060,18 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
         s->mv[1][0][1] = av_clip(s->mv[1][0][1], -60 - (s->mb_y << 6), (s->mb_height << 6) - 4 - (s->mb_y << 6));
     }
     if (direct) {
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0];
-        s->current_picture.f.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1];
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0];
-        s->current_picture.f.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1];
+        s->current_picture.motion_val[0][xy + v->blocks_off][0] = s->mv[0][0][0];
+        s->current_picture.motion_val[0][xy + v->blocks_off][1] = s->mv[0][0][1];
+        s->current_picture.motion_val[1][xy + v->blocks_off][0] = s->mv[1][0][0];
+        s->current_picture.motion_val[1][xy + v->blocks_off][1] = s->mv[1][0][1];
         return;
     }
 
     if ((mvtype == BMV_TYPE_FORWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
-        C   = s->current_picture.f.motion_val[0][xy - 2];
-        A   = s->current_picture.f.motion_val[0][xy - wrap * 2];
+        C   = s->current_picture.motion_val[0][xy - 2];
+        A   = s->current_picture.motion_val[0][xy - wrap * 2];
         off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
-        B   = s->current_picture.f.motion_val[0][xy - wrap * 2 + off];
+        B   = s->current_picture.motion_val[0][xy - wrap * 2 + off];
 
         if (!s->mb_x) C[0] = C[1] = 0;
         if (!s->first_slice_line) { // predictor A is not out of bounds
@@ -2146,10 +2146,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
         s->mv[0][0][1] = ((py + dmv_y[0] + r_y) & ((r_y << 1) - 1)) - r_y;
     }
     if ((mvtype == BMV_TYPE_BACKWARD) || (mvtype == BMV_TYPE_INTERPOLATED)) {
-        C   = s->current_picture.f.motion_val[1][xy - 2];
-        A   = s->current_picture.f.motion_val[1][xy - wrap * 2];
+        C   = s->current_picture.motion_val[1][xy - 2];
+        A   = s->current_picture.motion_val[1][xy - wrap * 2];
         off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
-        B   = s->current_picture.f.motion_val[1][xy - wrap * 2 + off];
+        B   = s->current_picture.motion_val[1][xy - wrap * 2 + off];
 
         if (!s->mb_x)
             C[0] = C[1] = 0;
@@ -2225,10 +2225,10 @@ static inline void vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
         s->mv[1][0][0] = ((px + dmv_x[1] + r_x) & ((r_x << 1) - 1)) - r_x;
         s->mv[1][0][1] = ((py + dmv_y[1] + r_y) & ((r_y << 1) - 1)) - r_y;
     }
-    s->current_picture.f.motion_val[0][xy][0] = s->mv[0][0][0];
-    s->current_picture.f.motion_val[0][xy][1] = s->mv[0][0][1];
-    s->current_picture.f.motion_val[1][xy][0] = s->mv[1][0][0];
-    s->current_picture.f.motion_val[1][xy][1] = s->mv[1][0][1];
+    s->current_picture.motion_val[0][xy][0] = s->mv[0][0][0];
+    s->current_picture.motion_val[0][xy][1] = s->mv[0][0][1];
+    s->current_picture.motion_val[1][xy][0] = s->mv[1][0][0];
+    s->current_picture.motion_val[1][xy][1] = s->mv[1][0][1];
 }
 
 static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dmv_y, int mv1, int *pred_flag)
@@ -2239,14 +2239,14 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm
 
     if (v->bmvtype == BMV_TYPE_DIRECT) {
         int total_opp, k, f;
-        if (s->next_picture.f.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
-            s->mv[0][0][0] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0],
+        if (s->next_picture.mb_type[mb_pos + v->mb_off] != MB_TYPE_INTRA) {
+            s->mv[0][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
                                       v->bfraction, 0, s->quarter_sample);
-            s->mv[0][0][1] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1],
+            s->mv[0][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
                                       v->bfraction, 0, s->quarter_sample);
-            s->mv[1][0][0] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0],
+            s->mv[1][0][0] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][0],
                                       v->bfraction, 1, s->quarter_sample);
-            s->mv[1][0][1] = scale_mv(s->next_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1],
+            s->mv[1][0][1] = scale_mv(s->next_picture.motion_val[1][s->block_index[0] + v->blocks_off][1],
                                       v->bfraction, 1, s->quarter_sample);
 
             total_opp = v->mv_f_next[0][s->block_index[0] + v->blocks_off]
@@ -2261,10 +2261,10 @@ static inline void vc1_pred_b_mv_intfi(VC1Context *v, int n, int *dmv_x, int *dm
         }
         v->ref_field_type[0] = v->ref_field_type[1] = v->cur_field_type ^ f;
         for (k = 0; k < 4; k++) {
-            s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
-            s->current_picture.f.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
-            s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
-            s->current_picture.f.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
+            s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][0] = s->mv[0][0][0];
+            s->current_picture.motion_val[0][s->block_index[k] + v->blocks_off][1] = s->mv[0][0][1];
+            s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][0] = s->mv[1][0][0];
+            s->current_picture.motion_val[1][s->block_index[k] + v->blocks_off][1] = s->mv[1][0][1];
             v->mv_f[0][s->block_index[k] + v->blocks_off] = f;
             v->mv_f[1][s->block_index[k] + v->blocks_off] = f;
         }
@@ -2382,17 +2382,17 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
     b = dc_val[ - 1 - wrap];
     a = dc_val[ - wrap];
     /* scale predictors if needed */
-    q1 = s->current_picture.f.qscale_table[mb_pos];
+    q1 = s->current_picture.qscale_table[mb_pos];
     dqscale_index = s->y_dc_scale_table[q1] - 1;
     if (dqscale_index < 0)
         return 0;
     if (c_avail && (n != 1 && n != 3)) {
-        q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+        q2 = s->current_picture.qscale_table[mb_pos - 1];
         if (q2 && q2 != q1)
             c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
     if (a_avail && (n != 2 && n != 3)) {
-        q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+        q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
         if (q2 && q2 != q1)
             a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
@@ -2402,7 +2402,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
             off--;
         if (n != 2)
             off -= s->mb_stride;
-        q2 = s->current_picture.f.qscale_table[off];
+        q2 = s->current_picture.qscale_table[off];
         if (q2 && q2 != q1)
             b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18;
     }
@@ -2773,11 +2773,11 @@ static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,
     else // top
         ac_val -= 16 * s->block_wrap[n];
 
-    q1 = s->current_picture.f.qscale_table[mb_pos];
+    q1 = s->current_picture.qscale_table[mb_pos];
     if ( dc_pred_dir && c_avail && mb_pos)
-        q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+        q2 = s->current_picture.qscale_table[mb_pos - 1];
     if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
-        q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+        q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
     if ( dc_pred_dir && n == 1)
         q2 = q1;
     if (!dc_pred_dir && n == 2)
@@ -2996,11 +2996,11 @@ static int vc1_decode_intra_block(VC1Context *v, int16_t block[64], int n,
     else //top
         ac_val -= 16 * s->block_wrap[n];
 
-    q1 = s->current_picture.f.qscale_table[mb_pos];
+    q1 = s->current_picture.qscale_table[mb_pos];
     if (dc_pred_dir && c_avail && mb_pos)
-        q2 = s->current_picture.f.qscale_table[mb_pos - 1];
+        q2 = s->current_picture.qscale_table[mb_pos - 1];
     if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)
-        q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];
+        q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
     if ( dc_pred_dir && n == 1)
         q2 = q1;
     if (!dc_pred_dir && n == 2)
@@ -3318,7 +3318,7 @@ static av_always_inline void vc1_apply_p_v_loop_filter(VC1Context *v, int block_
             bottom_is_intra = (block_num < 2) ? (mb_is_intra          >> ((block_num + 2) * 4))
                                               : (v->is_intra[s->mb_x] >> ((block_num - 2) * 4));
             mv_stride       = s->b8_stride;
-            mv              = &s->current_picture.f.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
+            mv              = &s->current_picture.motion_val[0][s->block_index[block_num] - 2 * mv_stride];
         }
 
         if (bottom_is_intra & 1 || block_is_intra & 1 ||
@@ -3380,7 +3380,7 @@ static av_always_inline void vc1_apply_p_h_loop_filter(VC1Context *v, int block_
                                              : (mb_cbp                              >> ((block_num + 1) * 4));
             right_is_intra = (block_num & 1) ? (v->is_intra[s->mb_x - s->mb_stride] >> ((block_num - 1) * 4))
                                              : (mb_is_intra                         >> ((block_num + 1) * 4));
-            mv             = &s->current_picture.f.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
+            mv             = &s->current_picture.motion_val[0][s->block_index[block_num] - s->b8_stride * 2 - 2];
         }
         if (block_is_intra & 1 || right_is_intra & 1 || mv[0][0] != mv[1][0] || mv[0][1] != mv[1][1]) {
             v->vc1dsp.vc1_h_loop_filter8(dst, linesize, v->pq);
@@ -3474,10 +3474,10 @@ static int vc1_decode_p_mb(VC1Context *v)
             GET_MVDATA(dmv_x, dmv_y);
 
             if (s->mb_intra) {
-                s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-                s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
+                s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+                s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
             }
-            s->current_picture.f.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
+            s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
             vc1_pred_mv(v, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
 
             /* FIXME Set DC val for inter block ? */
@@ -3494,7 +3494,7 @@ static int vc1_decode_p_mb(VC1Context *v)
                 mquant = v->pq;
                 cbp    = 0;
             }
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
 
             if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table,
@@ -3548,8 +3548,8 @@ static int vc1_decode_p_mb(VC1Context *v)
                 v->mb_type[0][s->block_index[i]] = 0;
                 s->dc_val[0][s->block_index[i]]  = 0;
             }
-            s->current_picture.f.mb_type[mb_pos]      = MB_TYPE_SKIP;
-            s->current_picture.f.qscale_table[mb_pos] = 0;
+            s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
+            s->current_picture.qscale_table[mb_pos] = 0;
             vc1_pred_mv(v, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0], 0, 0);
             vc1_mc_1mv(v, 0);
         }
@@ -3592,7 +3592,7 @@ static int vc1_decode_p_mb(VC1Context *v)
             if (!intra_count && !coded_inter)
                 goto end;
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             /* test if block is intra and has pred */
             {
                 int intrapred = 0;
@@ -3655,7 +3655,7 @@ static int vc1_decode_p_mb(VC1Context *v)
             }
         } else { // skipped MB
             s->mb_intra                               = 0;
-            s->current_picture.f.qscale_table[mb_pos] = 0;
+            s->current_picture.qscale_table[mb_pos] = 0;
             for (i = 0; i < 6; i++) {
                 v->mb_type[0][s->block_index[i]] = 0;
                 s->dc_val[0][s->block_index[i]]  = 0;
@@ -3665,7 +3665,7 @@ static int vc1_decode_p_mb(VC1Context *v)
                 vc1_mc_4mv_luma(v, i, 0);
             }
             vc1_mc_4mv_chroma(v, 0);
-            s->current_picture.f.qscale_table[mb_pos] = 0;
+            s->current_picture.qscale_table[mb_pos] = 0;
         }
     }
 end:
@@ -3740,9 +3740,9 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             break;
         }
         if (ff_vc1_mbmode_intfrp[v->fourmvswitch][idx_mbmode][0] == MV_PMODE_INTFR_INTRA) { // intra MB
-            s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
-            s->current_picture.f.mb_type[mb_pos]                     = MB_TYPE_INTRA;
+            s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+            s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+            s->current_picture.mb_type[mb_pos]                     = MB_TYPE_INTRA;
             s->mb_intra = v->is_intra[s->mb_x] = 1;
             for (i = 0; i < 6; i++)
                 v->mb_type[0][s->block_index[i]] = 1;
@@ -3752,7 +3752,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
                 cbp = 1 + get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             v->s.ac_pred = v->acpred_plane[mb_pos] = get_bits1(gb);
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same (not sure if necessary here) */
             s->y_dc_scale = s->y_dc_scale_table[mquant];
             s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -3844,7 +3844,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             }
             if (cbp)
                 GET_MQUANT();  // p. 227
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             if (!v->ttmbf && cbp)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
             for (i = 0; i < 6; i++) {
@@ -3873,8 +3873,8 @@ static int vc1_decode_p_mb_intfr(VC1Context *v)
             v->mb_type[0][s->block_index[i]] = 0;
             s->dc_val[0][s->block_index[i]] = 0;
         }
-        s->current_picture.f.mb_type[mb_pos]      = MB_TYPE_SKIP;
-        s->current_picture.f.qscale_table[mb_pos] = 0;
+        s->current_picture.mb_type[mb_pos]      = MB_TYPE_SKIP;
+        s->current_picture.qscale_table[mb_pos] = 0;
         v->blk_mv_type[s->block_index[0]] = 0;
         v->blk_mv_type[s->block_index[1]] = 0;
         v->blk_mv_type[s->block_index[2]] = 0;
@@ -3911,11 +3911,11 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
     if (idx_mbmode <= 1) { // intra MB
         s->mb_intra = v->is_intra[s->mb_x] = 1;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
-        s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+        s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_INTRA;
         GET_MQUANT();
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same (not sure if necessary here) */
         s->y_dc_scale = s->y_dc_scale_table[mquant];
         s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -3947,7 +3947,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+        s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
         for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
         if (idx_mbmode <= 5) { // 1-MV
             dmv_x = dmv_y = pred_flag = 0;
@@ -3978,7 +3978,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v)
         if (cbp) {
             GET_MQUANT();
         }
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         if (!v->ttmbf && cbp) {
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
@@ -4044,7 +4044,7 @@ static void vc1_decode_b_mb(VC1Context *v)
         v->mb_type[0][s->block_index[i]] = 0;
         s->dc_val[0][s->block_index[i]]  = 0;
     }
-    s->current_picture.f.qscale_table[mb_pos] = 0;
+    s->current_picture.qscale_table[mb_pos] = 0;
 
     if (!direct) {
         if (!skipped) {
@@ -4081,7 +4081,7 @@ static void vc1_decode_b_mb(VC1Context *v)
         cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
         GET_MQUANT();
         s->mb_intra = 0;
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         if (!v->ttmbf)
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;
@@ -4096,7 +4096,7 @@ static void vc1_decode_b_mb(VC1Context *v)
         }
         if (s->mb_intra && !mb_has_coeffs) {
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             s->ac_pred = get_bits1(gb);
             cbp = 0;
             vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);
@@ -4118,7 +4118,7 @@ static void vc1_decode_b_mb(VC1Context *v)
                 s->ac_pred = get_bits1(gb);
             cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
             GET_MQUANT();
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
                 ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
@@ -4185,11 +4185,11 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
     if (idx_mbmode <= 1) { // intra MB
         s->mb_intra = v->is_intra[s->mb_x] = 1;
-        s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-        s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off]         = MB_TYPE_INTRA;
+        s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+        s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
+        s->current_picture.mb_type[mb_pos + v->mb_off]         = MB_TYPE_INTRA;
         GET_MQUANT();
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         /* Set DC scale - y and c use the same (not sure if necessary here) */
         s->y_dc_scale = s->y_dc_scale_table[mquant];
         s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -4224,7 +4224,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
         }
     } else {
         s->mb_intra = v->is_intra[s->mb_x] = 0;
-        s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
+        s->current_picture.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16;
         for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0;
         if (v->fmb_is_raw)
             fwd = v->forward_mb_plane[mb_pos] = get_bits1(gb);
@@ -4290,7 +4290,7 @@ static void vc1_decode_b_mb_intfi(VC1Context *v)
         if (cbp) {
             GET_MQUANT();
         }
-        s->current_picture.f.qscale_table[mb_pos] = mquant;
+        s->current_picture.qscale_table[mb_pos] = mquant;
         if (!v->ttmbf && cbp) {
             ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);
         }
@@ -4372,10 +4372,10 @@ static void vc1_decode_i_blocks(VC1Context *v)
             dst[5] = s->dest[2];
             s->dsp.clear_blocks(s->block[0]);
             mb_pos = s->mb_x + s->mb_y * s->mb_width;
-            s->current_picture.f.mb_type[mb_pos]                     = MB_TYPE_INTRA;
-            s->current_picture.f.qscale_table[mb_pos]                = v->pq;
-            s->current_picture.f.motion_val[1][s->block_index[0]][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0]][1] = 0;
+            s->current_picture.mb_type[mb_pos]                     = MB_TYPE_INTRA;
+            s->current_picture.qscale_table[mb_pos]                = v->pq;
+            s->current_picture.motion_val[1][s->block_index[0]][0] = 0;
+            s->current_picture.motion_val[1][s->block_index[0]][1] = 0;
 
             // do actual MB decoding and displaying
             cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
@@ -4512,9 +4512,9 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
             ff_update_block_index(s);
             s->dsp.clear_blocks(block[0]);
             mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-            s->current_picture.f.mb_type[mb_pos + v->mb_off]                         = MB_TYPE_INTRA;
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
-            s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
+            s->current_picture.mb_type[mb_pos + v->mb_off]                         = MB_TYPE_INTRA;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = 0;
+            s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = 0;
 
             // do actual MB decoding and displaying
             if (v->fieldtx_is_raw)
@@ -4530,7 +4530,7 @@ static void vc1_decode_i_blocks_adv(VC1Context *v)
 
             GET_MQUANT();
 
-            s->current_picture.f.qscale_table[mb_pos] = mquant;
+            s->current_picture.qscale_table[mb_pos] = mquant;
             /* Set DC scale - y and c use the same */
             s->y_dc_scale = s->y_dc_scale_table[mquant];
             s->c_dc_scale = s->c_dc_scale_table[mquant];
@@ -5024,12 +5024,8 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb)
         v->two_sprites = 0;
     }
 
-    if (v->sprite_output_frame.data[0])
-        avctx->release_buffer(avctx, &v->sprite_output_frame);
-
-    v->sprite_output_frame.buffer_hints = FF_BUFFER_HINTS_VALID;
-    v->sprite_output_frame.reference = 0;
-    if (ff_get_buffer(avctx, &v->sprite_output_frame) < 0) {
+    av_frame_unref(&v->sprite_output_frame);
+    if (ff_get_buffer(avctx, &v->sprite_output_frame, 0) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -5279,9 +5275,8 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx)
     VC1Context *v = avctx->priv_data;
     int i;
 
-    if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)
-        && v->sprite_output_frame.data[0])
-        avctx->release_buffer(avctx, &v->sprite_output_frame);
+    av_frame_unref(&v->sprite_output_frame);
+
     for (i = 0; i < 4; i++)
         av_freep(&v->sr_rows[i >> 1][i & 1]);
     av_freep(&v->hrd_rate);
@@ -5315,7 +5310,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size, n_slices = 0, i;
+    int buf_size = avpkt->size, n_slices = 0, i, ret;
     VC1Context *v = avctx->priv_data;
     MpegEncContext *s = &v->s;
     AVFrame *pict = data;
@@ -5332,7 +5327,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data,
     if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {
         /* special case for last picture */
         if (s->low_delay == 0 && s->next_picture_ptr) {
-            *pict = s->next_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->next_picture_ptr->f)) < 0)
+                return ret;
             s->next_picture_ptr = NULL;
 
             *got_frame = 1;
@@ -5650,17 +5646,21 @@ image:
         if (vc1_decode_sprites(v, &s->gb))
             goto err;
 #endif
-        *pict      = v->sprite_output_frame;
+        if ((ret = av_frame_ref(pict, &v->sprite_output_frame)) < 0)
+            goto err;
         *got_frame = 1;
     } else {
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            *pict = s->current_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->current_picture_ptr->f)) < 0)
+                goto err;
+            ff_print_debug_info(s, s->current_picture_ptr);
         } else if (s->last_picture_ptr != NULL) {
-            *pict = s->last_picture_ptr->f;
+            if ((ret = av_frame_ref(pict, &s->last_picture_ptr->f)) < 0)
+                goto err;
+            ff_print_debug_info(s, s->last_picture_ptr);
         }
         if (s->last_picture_ptr || s->low_delay) {
             *got_frame = 1;
-            ff_print_debug_info(s, pict);
         }
     }
 
index 499b1c75c6d94d063799e11c559e6c7e595f1a7b..c4b817ead8c22a5d6f6e42e3b95a0f3313c28f56 100644 (file)
 #include "libavutil/internal.h"
 
 typedef struct VCR1Context {
-    AVFrame picture;
     int delta[16];
     int offset[4];
 } VCR1Context;
 
-static av_cold int vcr1_common_init(AVCodecContext *avctx)
-{
-    VCR1Context *const a = avctx->priv_data;
-
-    avctx->coded_frame = &a->picture;
-
-    return 0;
-}
-
 static av_cold int vcr1_decode_init(AVCodecContext *avctx)
 {
-    vcr1_common_init(avctx);
-
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
 
     return 0;
 }
 
-static av_cold int vcr1_decode_end(AVCodecContext *avctx)
-{
-    VCR1Context *s = avctx->priv_data;
-
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
-    return 0;
-}
-
 static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
     const uint8_t *buf        = avpkt->data;
     int buf_size              = avpkt->size;
     VCR1Context *const a      = avctx->priv_data;
-    AVFrame *picture          = data;
-    AVFrame *const p          = &a->picture;
+    AVFrame *const p          = data;
     const uint8_t *bytestream = buf;
     int i, x, y, ret;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -91,11 +64,11 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
 
     for (y = 0; y < avctx->height; y++) {
         int offset;
-        uint8_t *luma = &a->picture.data[0][y * a->picture.linesize[0]];
+        uint8_t *luma = &p->data[0][y * p->linesize[0]];
 
         if ((y & 3) == 0) {
-            uint8_t *cb = &a->picture.data[1][(y >> 2) * a->picture.linesize[1]];
-            uint8_t *cr = &a->picture.data[2][(y >> 2) * a->picture.linesize[2]];
+            uint8_t *cb = &p->data[1][(y >> 2) * p->linesize[1]];
+            uint8_t *cr = &p->data[2][(y >> 2) * p->linesize[2]];
 
             for (i = 0; i < 4; i++)
                 a->offset[i] = *bytestream++;
@@ -131,7 +104,6 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -143,7 +115,6 @@ AVCodec ff_vcr1_decoder = {
     .id             = AV_CODEC_ID_VCR1,
     .priv_data_size = sizeof(VCR1Context),
     .init           = vcr1_decode_init,
-    .close          = vcr1_decode_end,
     .decode         = vcr1_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ATI VCR1"),
index e5c459b4147cdf5e1fbecd0bbfb259147fbb710d..66c7f59f27d958da7f106c44dd4d0495cd86f372 100644 (file)
@@ -104,7 +104,7 @@ void ff_vdpau_h264_set_reference_frames(H264Context *h)
 
         for (i = 0; i < ls; ++i) {
             pic = lp[i];
-            if (!pic || !pic->f.reference)
+            if (!pic || !pic->reference)
                 continue;
             pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
 
@@ -122,8 +122,8 @@ void ff_vdpau_h264_set_reference_frames(H264Context *h)
                 ++rf2;
             }
             if (rf2 != rf) {
-                rf2->top_is_reference    |= (pic->f.reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
-                rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+                rf2->top_is_reference    |= (pic->reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
+                rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
                 continue;
             }
 
@@ -132,8 +132,8 @@ void ff_vdpau_h264_set_reference_frames(H264Context *h)
 
             rf->surface             = render_ref->surface;
             rf->is_long_term        = pic->long_ref;
-            rf->top_is_reference    = (pic->f.reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
-            rf->bottom_is_reference = (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+            rf->top_is_reference    = (pic->reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
+            rf->bottom_is_reference = (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
             rf->field_order_cnt[0]  = pic->field_poc[0];
             rf->field_order_cnt[1]  = pic->field_poc[1];
             rf->frame_idx           = pic_frame_idx;
@@ -199,7 +199,7 @@ void ff_vdpau_h264_picture_complete(H264Context *h)
     if (render->info.h264.slice_count < 1)
         return;
 
-    render->info.h264.is_reference                           = (h->cur_pic_ptr->f.reference & 3) ? VDP_TRUE : VDP_FALSE;
+    render->info.h264.is_reference                           = (h->cur_pic_ptr->reference & 3) ? VDP_TRUE : VDP_FALSE;
     render->info.h264.field_pic_flag                         = h->picture_structure != PICT_FRAME;
     render->info.h264.bottom_field_flag                      = h->picture_structure == PICT_BOTTOM_FIELD;
     render->info.h264.num_ref_frames                         = h->sps.ref_frame_count;
index 91f8008366d8d42a91925947e1636809f959b542..e787762e348b6bedd871b519d49e0467784472dd 100644 (file)
@@ -52,10 +52,10 @@ static void vdpau_h264_set_rf(VdpReferenceFrameH264 *rf, Picture *pic,
     VdpVideoSurface surface = ff_vdpau_get_surface_id(pic);
 
     if (pic_structure == 0)
-        pic_structure = pic->f.reference;
+        pic_structure = pic->reference;
 
     rf->surface             = surface;
-    rf->is_long_term        = pic->f.reference && pic->long_ref;
+    rf->is_long_term        = pic->reference && pic->long_ref;
     rf->top_is_reference    = (pic_structure & PICT_TOP_FIELD)    != 0;
     rf->bottom_is_reference = (pic_structure & PICT_BOTTOM_FIELD) != 0;
     rf->field_order_cnt[0]  = h264_foc(pic->field_poc[0]);
@@ -83,7 +83,7 @@ static void vdpau_h264_set_reference_frames(AVCodecContext *avctx)
             VdpVideoSurface surface_ref;
             int pic_frame_idx;
 
-            if (!pic || !pic->f.reference)
+            if (!pic || !pic->reference)
                 continue;
             pic_frame_idx = pic->long_ref ? pic->pic_id : pic->frame_num;
             surface_ref = ff_vdpau_get_surface_id(pic);
@@ -97,15 +97,15 @@ static void vdpau_h264_set_reference_frames(AVCodecContext *avctx)
                 ++rf2;
             }
             if (rf2 != rf) {
-                rf2->top_is_reference    |= (pic->f.reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
-                rf2->bottom_is_reference |= (pic->f.reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
+                rf2->top_is_reference    |= (pic->reference & PICT_TOP_FIELD)    ? VDP_TRUE : VDP_FALSE;
+                rf2->bottom_is_reference |= (pic->reference & PICT_BOTTOM_FIELD) ? VDP_TRUE : VDP_FALSE;
                 continue;
             }
 
             if (rf >= &info->referenceFrames[H264_RF_COUNT])
                 continue;
 
-            vdpau_h264_set_rf(rf, pic, pic->f.reference);
+            vdpau_h264_set_rf(rf, pic, pic->reference);
             ++rf;
         }
     }
index 78fcdbfaaef08fd5f640680ead263d27391f249f..aaf873568656015bf5eda6115ab300b48c303e7a 100644 (file)
 #ifndef FF_API_DESTRUCT_PACKET
 #define FF_API_DESTRUCT_PACKET   (LIBAVCODEC_VERSION_MAJOR < 56)
 #endif
+#ifndef FF_API_GET_BUFFER
+#define FF_API_GET_BUFFER        (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
 
 #endif /* AVCODEC_VERSION_H */
index 88cd167659285a0e82c08259ca75d31de25edd81..b5b5524919c4fde5ee4882bfd7e70557cc686e52 100644 (file)
@@ -59,7 +59,6 @@
 typedef struct VmdVideoContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
     AVFrame prev_frame;
 
     const unsigned char *buf;
@@ -207,7 +206,7 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest,
     return ps - src;
 }
 
-static void vmd_decode(VmdVideoContext *s)
+static void vmd_decode(VmdVideoContext *s, AVFrame *frame)
 {
     int i;
     unsigned int *palette32;
@@ -257,8 +256,8 @@ static void vmd_decode(VmdVideoContext *s)
         (frame_x || frame_y || (frame_width != s->avctx->width) ||
         (frame_height != s->avctx->height))) {
 
-        memcpy(s->frame.data[0], s->prev_frame.data[0],
-            s->avctx->height * s->frame.linesize[0]);
+        memcpy(frame->data[0], s->prev_frame.data[0],
+            s->avctx->height * frame->linesize[0]);
     }
 
     /* check if there is a new palette */
@@ -288,7 +287,7 @@ static void vmd_decode(VmdVideoContext *s)
             pb_size = s->unpack_buffer_size;
         }
 
-        dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
+        dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
         pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
         switch (meth) {
         case 1:
@@ -320,7 +319,7 @@ static void vmd_decode(VmdVideoContext *s)
                         ofs, frame_width);
                     break;
                 }
-                dp += s->frame.linesize[0];
+                dp += frame->linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
             break;
@@ -332,7 +331,7 @@ static void vmd_decode(VmdVideoContext *s)
                 memcpy(dp, pb, frame_width);
                 pb += frame_width;
                 pb_size -= frame_width;
-                dp += s->frame.linesize[0];
+                dp += frame->linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
             break;
@@ -371,7 +370,7 @@ static void vmd_decode(VmdVideoContext *s)
                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
                         ofs, frame_width);
                 }
-                dp += s->frame.linesize[0];
+                dp += frame->linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
             break;
@@ -425,6 +424,8 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     VmdVideoContext *s = avctx->priv_data;
+    AVFrame *frame = data;
+    int ret;
 
     s->buf = buf;
     s->size = buf_size;
@@ -432,24 +433,22 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     if (buf_size < 16)
         return buf_size;
 
-    s->frame.reference = 1;
-    if (ff_get_buffer(avctx, &s->frame)) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
-    vmd_decode(s);
+    vmd_decode(s, frame);
 
     /* make the palette available on the way out */
-    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
+    memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
 
     /* shuffle frames */
-    FFSWAP(AVFrame, s->frame, s->prev_frame);
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->prev_frame);
+    if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0)
+        return ret;
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->prev_frame;
 
     /* report that the buffer was completely consumed */
     return buf_size;
@@ -459,8 +458,7 @@ static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
 {
     VmdVideoContext *s = avctx->priv_data;
 
-    if (s->prev_frame.data[0])
-        avctx->release_buffer(avctx, &s->prev_frame);
+    av_frame_unref(&s->prev_frame);
     av_free(s->unpack_buffer);
 
     return 0;
@@ -607,7 +605,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
     /* get output buffer */
     frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
                         avctx->channels;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 4071cdf51a833a182524aec4b2647a6a4f168cc4..41e4730b4483d8d19c5920ab52d1784f56acaa9c 100644 (file)
@@ -31,6 +31,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 enum EncTypes {
     MAGIC_WMVd = 0x574D5664,
@@ -293,13 +294,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     VmncContext * const c = avctx->priv_data;
     uint8_t *outptr;
     const uint8_t *src = buf;
-    int dx, dy, w, h, depth, enc, chunks, res, size_left;
+    int dx, dy, w, h, depth, enc, chunks, res, size_left, ret;
 
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if(avctx->reget_buffer(avctx, &c->pic) < 0){
+    if ((ret = ff_reget_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
 
     c->pic.key_frame = 0;
@@ -448,7 +447,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         }
     }
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
+    if ((ret = av_frame_ref(data, &c->pic)) < 0)
+        return ret;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -502,8 +502,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     VmncContext * const c = avctx->priv_data;
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
+    av_frame_unref(&c->pic);
 
     av_free(c->curbits);
     av_free(c->curmask);
index c31dd17b8bb056bbb440d3d005908666a3ed35c9..ebe7aa79dc9870676ed193fdc83afc6c1254c602 100644 (file)
@@ -1684,7 +1684,7 @@ static int vorbis_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = vc->blocksize[1] / 2;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index f46ac32a9aa092cafc0dbe767b0cb074885e59b2..3d55c784aad753f7df80443c8e310ebbd0b50e68 100644 (file)
@@ -131,9 +131,9 @@ typedef struct Vp3DecodeContext {
     int version;
     int width, height;
     int chroma_x_shift, chroma_y_shift;
-    AVFrame golden_frame;
-    AVFrame last_frame;
-    AVFrame current_frame;
+    ThreadFrame golden_frame;
+    ThreadFrame last_frame;
+    ThreadFrame current_frame;
     int keyframe;
     DSPContext dsp;
     VideoDSPContext vdsp;
@@ -261,19 +261,11 @@ static void vp3_decode_flush(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
 
-    if (s->golden_frame.data[0]) {
-        if (s->golden_frame.data[0] == s->last_frame.data[0])
-            memset(&s->last_frame, 0, sizeof(AVFrame));
-        if (s->current_frame.data[0] == s->golden_frame.data[0])
-            memset(&s->current_frame, 0, sizeof(AVFrame));
+    if (s->golden_frame.f)
         ff_thread_release_buffer(avctx, &s->golden_frame);
-    }
-    if (s->last_frame.data[0]) {
-        if (s->current_frame.data[0] == s->last_frame.data[0])
-            memset(&s->current_frame, 0, sizeof(AVFrame));
+    if (s->last_frame.f)
         ff_thread_release_buffer(avctx, &s->last_frame);
-    }
-    if (s->current_frame.data[0])
+    if (s->current_frame.f)
         ff_thread_release_buffer(avctx, &s->current_frame);
 }
 
@@ -292,6 +284,12 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
     av_freep(&s->motion_val[1]);
     av_freep(&s->edge_emu_buffer);
 
+    /* release all frames */
+    vp3_decode_flush(avctx);
+    av_frame_free(&s->current_frame.f);
+    av_frame_free(&s->last_frame.f);
+    av_frame_free(&s->golden_frame.f);
+
     if (avctx->internal->is_copy)
         return 0;
 
@@ -308,8 +306,6 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
     ff_free_vlc(&s->mode_code_vlc);
     ff_free_vlc(&s->motion_vector_vlc);
 
-    /* release all frames */
-    vp3_decode_flush(avctx);
 
     return 0;
 }
@@ -1290,8 +1286,8 @@ static void apply_loop_filter(Vp3DecodeContext *s, int plane, int ystart, int ye
     int width           = s->fragment_width[!!plane];
     int height          = s->fragment_height[!!plane];
     int fragment        = s->fragment_start        [plane] + ystart * width;
-    int stride          = s->current_frame.linesize[plane];
-    uint8_t *plane_data = s->current_frame.data    [plane];
+    int stride          = s->current_frame.f->linesize[plane];
+    uint8_t *plane_data = s->current_frame.f->data    [plane];
     if (!s->flipped_image) stride = -stride;
     plane_data += s->data_offset[plane] + 8*ystart*stride;
 
@@ -1420,14 +1416,14 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
     }
 
     cy = y >> s->chroma_y_shift;
-    offset[0] = s->current_frame.linesize[0]*y;
-    offset[1] = s->current_frame.linesize[1]*cy;
-    offset[2] = s->current_frame.linesize[2]*cy;
+    offset[0] = s->current_frame.f->linesize[0]*y;
+    offset[1] = s->current_frame.f->linesize[1]*cy;
+    offset[2] = s->current_frame.f->linesize[2]*cy;
     for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
         offset[i] = 0;
 
     emms_c();
-    s->avctx->draw_horiz_band(s->avctx, &s->current_frame, offset, y, 3, h);
+    s->avctx->draw_horiz_band(s->avctx, s->current_frame.f, offset, y, 3, h);
 }
 
 /**
@@ -1436,7 +1432,7 @@ static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
  */
 static void await_reference_row(Vp3DecodeContext *s, Vp3Fragment *fragment, int motion_y, int y)
 {
-    AVFrame *ref_frame;
+    ThreadFrame *ref_frame;
     int ref_row;
     int border = motion_y&1;
 
@@ -1469,10 +1465,10 @@ static void render_slice(Vp3DecodeContext *s, int slice)
         return;
 
     for (plane = 0; plane < 3; plane++) {
-        uint8_t *output_plane = s->current_frame.data    [plane] + s->data_offset[plane];
-        uint8_t *  last_plane = s->   last_frame.data    [plane] + s->data_offset[plane];
-        uint8_t *golden_plane = s-> golden_frame.data    [plane] + s->data_offset[plane];
-        int stride            = s->current_frame.linesize[plane];
+        uint8_t *output_plane = s->current_frame.f->data    [plane] + s->data_offset[plane];
+        uint8_t *  last_plane = s->   last_frame.f->data    [plane] + s->data_offset[plane];
+        uint8_t *golden_plane = s-> golden_frame.f->data    [plane] + s->data_offset[plane];
+        int stride            = s->current_frame.f->linesize[plane];
         int plane_width       = s->width  >> (plane && s->chroma_x_shift);
         int plane_height      = s->height >> (plane && s->chroma_y_shift);
         int8_t (*motion_val)[2] = s->motion_val[!!plane];
@@ -1657,14 +1653,36 @@ static av_cold int allocate_tables(AVCodecContext *avctx)
     return 0;
 }
 
+static av_cold int init_frames(Vp3DecodeContext *s)
+{
+    s->current_frame.f = av_frame_alloc();
+    s->last_frame.f    = av_frame_alloc();
+    s->golden_frame.f  = av_frame_alloc();
+
+    if (!s->current_frame.f || !s->last_frame.f || !s->golden_frame.f) {
+        av_frame_free(&s->current_frame.f);
+        av_frame_free(&s->last_frame.f);
+        av_frame_free(&s->golden_frame.f);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
 static av_cold int vp3_decode_init(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
-    int i, inter, plane;
+    int i, inter, plane, ret;
     int c_width;
     int c_height;
     int y_fragment_count, c_fragment_count;
 
+    ret = init_frames(s);
+    if (ret < 0)
+        return ret;
+
+    avctx->internal->allocate_progress = 1;
+
     if (avctx->codec_tag == MKTAG('V','P','3','0'))
         s->version = 0;
     else
@@ -1821,12 +1839,6 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx)
         &motion_vector_vlc_table[0][1], 2, 1,
         &motion_vector_vlc_table[0][0], 2, 1, 0);
 
-    for (i = 0; i < 3; i++) {
-        s->current_frame.data[i] = NULL;
-        s->last_frame.data[i] = NULL;
-        s->golden_frame.data[i] = NULL;
-    }
-
     return allocate_tables(avctx);
 
 vlc_fail:
@@ -1835,26 +1847,44 @@ vlc_fail:
 }
 
 /// Release and shuffle frames after decode finishes
-static void update_frames(AVCodecContext *avctx)
+static int update_frames(AVCodecContext *avctx)
 {
     Vp3DecodeContext *s = avctx->priv_data;
+    int ret = 0;
 
-    /* release the last frame, if it is allocated and if it is not the
-     * golden frame */
-    if (s->last_frame.data[0] && s->last_frame.type != FF_BUFFER_TYPE_COPY)
-        ff_thread_release_buffer(avctx, &s->last_frame);
 
     /* shuffle frames (last = current) */
-    s->last_frame= s->current_frame;
+    ff_thread_release_buffer(avctx, &s->last_frame);
+    ret = ff_thread_ref_frame(&s->last_frame, &s->current_frame);
+    if (ret < 0)
+        goto fail;
 
     if (s->keyframe) {
-        if (s->golden_frame.data[0])
-            ff_thread_release_buffer(avctx, &s->golden_frame);
-        s->golden_frame = s->current_frame;
-        s->last_frame.type = FF_BUFFER_TYPE_COPY;
+        ff_thread_release_buffer(avctx, &s->golden_frame);
+        ret = ff_thread_ref_frame(&s->golden_frame, &s->current_frame);
     }
 
-    s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */
+fail:
+    ff_thread_release_buffer(avctx, &s->current_frame);
+    return ret;
+}
+
+static int ref_frame(Vp3DecodeContext *s, ThreadFrame *dst, ThreadFrame *src)
+{
+    ff_thread_release_buffer(s->avctx, dst);
+    if (src->f->data[0])
+        return ff_thread_ref_frame(dst, src);
+    return 0;
+}
+
+static int ref_frames(Vp3DecodeContext *dst, Vp3DecodeContext *src)
+{
+    int ret;
+    if ((ret = ref_frame(dst, &dst->current_frame, &src->current_frame)) < 0 ||
+        (ret = ref_frame(dst, &dst->golden_frame,  &src->golden_frame)) < 0  ||
+        (ret = ref_frame(dst, &dst->last_frame,    &src->last_frame)) < 0)
+        return ret;
+    return 0;
 }
 
 static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
@@ -1864,17 +1894,17 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
 
 #define copy_fields(to, from, start_field, end_field) memcpy(&to->start_field, &from->start_field, (char*)&to->end_field - (char*)&to->start_field)
 
-    if (!s1->current_frame.data[0]
+    if (!s1->current_frame.f->data[0]
         ||s->width != s1->width
         ||s->height!= s1->height) {
         if (s != s1)
-            copy_fields(s, s1, golden_frame, current_frame);
+            ref_frames(s, s1);
         return -1;
     }
 
     if (s != s1) {
         // init tables if the first frame hasn't been decoded
-        if (!s->current_frame.data[0]) {
+        if (!s->current_frame.f->data[0]) {
             int y_fragment_count, c_fragment_count;
             s->avctx = dst;
             err = allocate_tables(dst);
@@ -1887,7 +1917,10 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
         }
 
         // copy previous frame data
-        copy_fields(s, s1, golden_frame, dsp);
+        if ((err = ref_frames(s, s1)) < 0)
+            return err;
+
+        s->keyframe = s1->keyframe;
 
         // copy qscale data if necessary
         for (i = 0; i < 3; i++) {
@@ -1905,9 +1938,7 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *
 #undef copy_fields
     }
 
-    update_frames(dst);
-
-    return 0;
+    return update_frames(dst);
 }
 
 static int vp3_decode_frame(AVCodecContext *avctx,
@@ -1918,7 +1949,7 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     Vp3DecodeContext *s = avctx->priv_data;
     GetBitContext gb;
-    int i;
+    int i, ret;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -1960,15 +1991,14 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)
         return buf_size;
 
-    s->current_frame.reference = 3;
-    s->current_frame.pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-    if (ff_thread_get_buffer(avctx, &s->current_frame) < 0) {
+    s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         goto error;
     }
 
     if (!s->edge_emu_buffer)
-        s->edge_emu_buffer = av_malloc(9*FFABS(s->current_frame.linesize[0]));
+        s->edge_emu_buffer = av_malloc(9*FFABS(s->current_frame.f->linesize[0]));
 
     if (s->keyframe) {
         if (!s->theora)
@@ -1989,17 +2019,17 @@ static int vp3_decode_frame(AVCodecContext *avctx,
             skip_bits(&gb, 2); /* reserved? */
         }
     } else {
-        if (!s->golden_frame.data[0]) {
+        if (!s->golden_frame.f->data[0]) {
             av_log(s->avctx, AV_LOG_WARNING, "vp3: first frame not a keyframe\n");
 
-            s->golden_frame.reference = 3;
-            s->golden_frame.pict_type = AV_PICTURE_TYPE_I;
-            if (ff_thread_get_buffer(avctx, &s->golden_frame) < 0) {
+            s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;
+            if (ff_thread_get_buffer(avctx, &s->golden_frame, AV_GET_BUFFER_FLAG_REF) < 0) {
                 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 goto error;
             }
-            s->last_frame = s->golden_frame;
-            s->last_frame.type = FF_BUFFER_TYPE_COPY;
+            ff_thread_release_buffer(avctx, &s->last_frame);
+            if ((ret = ff_thread_ref_frame(&s->last_frame, &s->golden_frame)) < 0)
+                goto error;
             ff_thread_report_progress(&s->last_frame, INT_MAX, 0);
         }
     }
@@ -2033,7 +2063,7 @@ static int vp3_decode_frame(AVCodecContext *avctx,
         if (s->flipped_image)
             s->data_offset[i] = 0;
         else
-            s->data_offset[i] = (height-1) * s->current_frame.linesize[i];
+            s->data_offset[i] = (height-1) * s->current_frame.f->linesize[i];
     }
 
     s->last_slice_end = 0;
@@ -2047,11 +2077,15 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     }
     vp3_draw_horiz_band(s, s->avctx->height);
 
+    if ((ret = av_frame_ref(data, s->current_frame.f)) < 0)
+        return ret;
     *got_frame = 1;
-    *(AVFrame*)data= s->current_frame;
 
-    if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
-        update_frames(avctx);
+    if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME)) {
+        ret = update_frames(avctx);
+        if (ret < 0)
+            return ret;
+    }
 
     return buf_size;
 
@@ -2059,7 +2093,7 @@ error:
     ff_thread_report_progress(&s->current_frame, INT_MAX, 0);
 
     if (!HAVE_THREADS || !(s->avctx->active_thread_type&FF_THREAD_FRAME))
-        avctx->release_buffer(avctx, &s->current_frame);
+        av_frame_unref(s->current_frame.f);
 
     return -1;
 }
@@ -2113,7 +2147,7 @@ static int vp3_init_thread_copy(AVCodecContext *avctx)
     s->motion_val[1]          = NULL;
     s->edge_emu_buffer        = NULL;
 
-    return 0;
+    return init_frames(s);
 }
 
 #if CONFIG_THEORA_DECODER
index 89333f3d927b98f03239b4a57ade70dada148e7b..742262be054e48e19f98836e3ba02622744be8e6 100644 (file)
@@ -41,10 +41,10 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
     int rows, cols;
 
     ff_vp56_init_range_decoder(&s->c, buf, buf_size);
-    s->framep[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
+    s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
     vp56_rac_get(c);
     ff_vp56_init_dequant(s, vp56_rac_gets(c, 6));
-    if (s->framep[VP56_FRAME_CURRENT]->key_frame)
+    if (s->frames[VP56_FRAME_CURRENT]->key_frame)
     {
         vp56_rac_gets(c, 8);
         if(vp56_rac_gets(c, 5) > 5)
@@ -138,7 +138,7 @@ static int vp5_parse_coeff_models(VP56Context *s)
             if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) {
                 def_prob[node] = vp56_rac_gets_nn(c, 7);
                 model->coeff_dccv[pt][node] = def_prob[node];
-            } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+            } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                 model->coeff_dccv[pt][node] = def_prob[node];
             }
 
@@ -149,7 +149,7 @@ static int vp5_parse_coeff_models(VP56Context *s)
                     if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) {
                         def_prob[node] = vp56_rac_gets_nn(c, 7);
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
-                    } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+                    } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
                     }
 
@@ -264,8 +264,10 @@ static void vp5_default_models_init(VP56Context *s)
 static av_cold int vp5_decode_init(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    int ret;
 
-    ff_vp56_init(avctx, 1, 0);
+    if ((ret = ff_vp56_init(avctx, 1, 0)) < 0)
+        return ret;
     s->vp56_coord_div = vp5_coord_div;
     s->parse_vector_adjustment = vp5_parse_vector_adjustment;
     s->parse_coeff = vp5_parse_coeff;
index 64f33c6dbeb5954a1772abcf7114cab476f14461..b93f75da7e84bebaf7ab9b3bc164db20fdc37020 100644 (file)
@@ -36,7 +36,6 @@ void ff_vp56_init_dequant(VP56Context *s, int quantizer)
     s->quantizer = quantizer;
     s->dequant_dc = vp56_dc_dequant[quantizer] << 2;
     s->dequant_ac = vp56_ac_dequant[quantizer] << 2;
-    memset(s->qscale_table, quantizer, s->mb_width);
 }
 
 static int vp56_get_vectors_predictors(VP56Context *s, int row, int col,
@@ -314,7 +313,7 @@ static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv,
 static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
                     int stride, int x, int y)
 {
-    uint8_t *dst=s->framep[VP56_FRAME_CURRENT]->data[plane]+s->block_offset[b];
+    uint8_t *dst = s->frames[VP56_FRAME_CURRENT]->data[plane] + s->block_offset[b];
     uint8_t *src_block;
     int src_offset;
     int overlap_offset = 0;
@@ -325,7 +324,7 @@ static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
 
     if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
         (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY
-         && !s->framep[VP56_FRAME_CURRENT]->key_frame))
+         && !s->frames[VP56_FRAME_CURRENT]->key_frame))
         deblock_filtering = 0;
 
     dx = s->mv[b].x / s->vp56_coord_div[b];
@@ -388,7 +387,7 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
     VP56Frame ref_frame;
     int b, ab, b_max, plane, off;
 
-    if (s->framep[VP56_FRAME_CURRENT]->key_frame)
+    if (s->frames[VP56_FRAME_CURRENT]->key_frame)
         mb_type = VP56_MB_INTRA;
     else
         mb_type = vp56_decode_mv(s, row, col);
@@ -398,8 +397,8 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
 
     vp56_add_predictors_dc(s, ref_frame);
 
-    frame_current = s->framep[VP56_FRAME_CURRENT];
-    frame_ref = s->framep[ref_frame];
+    frame_current = s->frames[VP56_FRAME_CURRENT];
+    frame_ref = s->frames[ref_frame];
     if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
         return;
 
@@ -456,7 +455,7 @@ static void vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
 static int vp56_size_changed(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
-    int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0];
+    int stride = s->frames[VP56_FRAME_CURRENT]->linesize[0];
     int i;
 
     s->plane_width[0]  = s->plane_width[3]  = avctx->coded_width;
@@ -465,7 +464,7 @@ static int vp56_size_changed(AVCodecContext *avctx)
     s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2;
 
     for (i=0; i<4; i++)
-        s->stride[i] = s->flip * s->framep[VP56_FRAME_CURRENT]->linesize[i];
+        s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT]->linesize[i];
 
     s->mb_width  = (avctx->coded_width +15) / 16;
     s->mb_height = (avctx->coded_height+15) / 16;
@@ -476,7 +475,6 @@ static int vp56_size_changed(AVCodecContext *avctx)
         return -1;
     }
 
-    s->qscale_table = av_realloc(s->qscale_table, s->mb_width);
     s->above_blocks = av_realloc(s->above_blocks,
                                  (4*s->mb_width+6) * sizeof(*s->above_blocks));
     s->macroblocks = av_realloc(s->macroblocks,
@@ -495,9 +493,10 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 {
     const uint8_t *buf = avpkt->data;
     VP56Context *s = avctx->priv_data;
-    AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
+    AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
     int remaining_buf_size = avpkt->size;
     int is_alpha, av_uninit(alpha_offset);
+    int res;
 
     if (s->has_alpha) {
         if (remaining_buf_size < 3)
@@ -512,26 +511,21 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         int mb_row, mb_col, mb_row_flip, mb_offset = 0;
         int block, y, uv, stride_y, stride_uv;
         int golden_frame = 0;
-        int res;
 
         s->modelp = &s->models[is_alpha];
 
         res = s->parse_header(s, buf, remaining_buf_size, &golden_frame);
         if (res < 0) {
             int i;
-            for (i = 0; i < 4; i++) {
-                if (s->frames[i].data[0])
-                    avctx->release_buffer(avctx, &s->frames[i]);
-            }
+            for (i = 0; i < 4; i++)
+                av_frame_unref(s->frames[i]);
             return res;
         }
 
         if (res == VP56_SIZE_CHANGE) {
             int i;
-            for (i = 0; i < 4; i++) {
-                if (s->frames[i].data[0])
-                    avctx->release_buffer(avctx, &s->frames[i]);
-            }
+            for (i = 0; i < 4; i++)
+                av_frame_unref(s->frames[i]);
             if (is_alpha) {
                 avcodec_set_dimensions(avctx, 0, 0);
                 return -1;
@@ -539,15 +533,14 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         }
 
         if (!is_alpha) {
-            p->reference = 1;
-            if (ff_get_buffer(avctx, p) < 0) {
+            if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return -1;
             }
 
             if (res == VP56_SIZE_CHANGE)
                 if (vp56_size_changed(avctx)) {
-                    avctx->release_buffer(avctx, p);
+                    av_frame_unref(p);
                     return -1;
                 }
         }
@@ -631,44 +624,31 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     next:
         if (p->key_frame || golden_frame) {
-            if (s->framep[VP56_FRAME_GOLDEN]->data[0] &&
-                s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2])
-                avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
-            s->framep[VP56_FRAME_GOLDEN] = p;
+            av_frame_unref(s->frames[VP56_FRAME_GOLDEN]);
+            if ((res = av_frame_ref(s->frames[VP56_FRAME_GOLDEN], p)) < 0)
+                return res;
         }
 
         if (s->has_alpha) {
-            FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN],
-                              s->framep[VP56_FRAME_GOLDEN2]);
+            FFSWAP(AVFrame *, s->frames[VP56_FRAME_GOLDEN],
+                              s->frames[VP56_FRAME_GOLDEN2]);
             buf += alpha_offset;
             remaining_buf_size -= alpha_offset;
         }
     }
 
-    if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] ||
-        s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) {
-        if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] &&
-            s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2])
-            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
-                              s->framep[VP56_FRAME_UNUSED]);
-        else
-            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
-                              s->framep[VP56_FRAME_UNUSED2]);
-    } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
-    FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],
-                      s->framep[VP56_FRAME_PREVIOUS]);
-
-    p->qstride = 0;
-    p->qscale_table = s->qscale_table;
-    p->qscale_type = FF_QSCALE_TYPE_VP56;
-    *(AVFrame*)data = *p;
+    av_frame_unref(s->frames[VP56_FRAME_PREVIOUS]);
+    FFSWAP(AVFrame *, s->frames[VP56_FRAME_CURRENT],
+                      s->frames[VP56_FRAME_PREVIOUS]);
+
+    if ((res = av_frame_ref(data, p)) < 0)
+        return res;
     *got_frame = 1;
 
     return avpkt->size;
 }
 
-av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
+av_cold int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
 {
     VP56Context *s = avctx->priv_data;
     int i;
@@ -684,10 +664,13 @@ av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
     ff_init_scantable_permutation(s->dsp.idct_permutation, s->vp3dsp.idct_perm);
     ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct);
 
-    for (i=0; i<4; i++)
-        s->framep[i] = &s->frames[i];
-    s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN];
-    s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2];
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
+        s->frames[i] = av_frame_alloc();
+        if (!s->frames[i]) {
+            ff_vp56_free(avctx);
+            return AVERROR(ENOMEM);
+        }
+    }
     s->edge_emu_buffer_alloc = NULL;
 
     s->above_blocks = NULL;
@@ -707,21 +690,21 @@ av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
         s->frbi = 0;
         s->srbi = 2;
     }
+
+    return 0;
 }
 
 av_cold int ff_vp56_free(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    int i;
 
-    av_freep(&s->qscale_table);
     av_freep(&s->above_blocks);
     av_freep(&s->macroblocks);
     av_freep(&s->edge_emu_buffer_alloc);
-    if (s->framep[VP56_FRAME_GOLDEN]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
-    if (s->framep[VP56_FRAME_GOLDEN2]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]);
-    if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+        av_frame_free(&s->frames[i]);
+
     return 0;
 }
index 8c6ba14ada27c0e9d2de29b3c9896b3032c90aee..80ede6a0aa478583e0df9230128c8960cd4deb06 100644 (file)
@@ -101,8 +101,7 @@ struct vp56_context {
     VP3DSPContext vp3dsp;
     VP56DSPContext vp56dsp;
     ScanTable scantable;
-    AVFrame frames[4];
-    AVFrame *framep[6];
+    AVFrame *frames[4];
     uint8_t *edge_emu_buffer_alloc;
     uint8_t *edge_emu_buffer;
     VP56RangeCoder c;
@@ -120,7 +119,6 @@ struct vp56_context {
     int quantizer;
     uint16_t dequant_dc;
     uint16_t dequant_ac;
-    int8_t *qscale_table;
 
     /* DC predictors management */
     VP56RefDc *above_blocks;
@@ -179,7 +177,7 @@ struct vp56_context {
 };
 
 
-void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
+int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
 int ff_vp56_free(AVCodecContext *avctx);
 void ff_vp56_init_dequant(VP56Context *s, int quantizer);
 int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
index 0535425d3d9b65c64dd601a5705e7c4d57c4ec3b..ee3832293da2e94d5a3fc34f2968b86b81eb923a 100644 (file)
@@ -34,8 +34,6 @@ typedef enum {
     VP56_FRAME_PREVIOUS = 1,
     VP56_FRAME_GOLDEN   = 2,
     VP56_FRAME_GOLDEN2  = 3,
-    VP56_FRAME_UNUSED   = 4,
-    VP56_FRAME_UNUSED2  = 5,
 } VP56Frame;
 
 typedef enum {
index b824e3b1cd26841c87aea4b4b6542cfea74012e2..30b489dfca73e9bdfb191f90093e43a618f0504b 100644 (file)
@@ -54,10 +54,10 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
     int res = 0;
     int separated_coeff = buf[0] & 1;
 
-    s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
+    s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
     ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
 
-    if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+    if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
         sub_version = buf[1] >> 3;
         if (sub_version > 8)
             return AVERROR_INVALIDDATA;
@@ -143,7 +143,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
         buf      += coeff_offset;
         buf_size -= coeff_offset;
         if (buf_size < 0) {
-            if (s->framep[VP56_FRAME_CURRENT]->key_frame)
+            if (s->frames[VP56_FRAME_CURRENT]->key_frame)
                 avcodec_set_dimensions(s->avctx, 0, 0);
             return AVERROR_INVALIDDATA;
         }
@@ -258,7 +258,7 @@ static int vp6_parse_coeff_models(VP56Context *s)
             if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) {
                 def_prob[node] = vp56_rac_gets_nn(c, 7);
                 model->coeff_dccv[pt][node] = def_prob[node];
-            } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+            } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                 model->coeff_dccv[pt][node] = def_prob[node];
             }
 
@@ -281,7 +281,7 @@ static int vp6_parse_coeff_models(VP56Context *s)
                     if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) {
                         def_prob[node] = vp56_rac_gets_nn(c, 7);
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
-                    } else if (s->framep[VP56_FRAME_CURRENT]->key_frame) {
+                    } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
                         model->coeff_ract[pt][ct][cg][node] = def_prob[node];
                     }
 
@@ -592,9 +592,12 @@ static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
 static av_cold int vp6_decode_init(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    int ret;
+
+    if ((ret = ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6,
+                            avctx->codec->id == AV_CODEC_ID_VP6A)) < 0)
+        return ret;
 
-    ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6,
-                        avctx->codec->id == AV_CODEC_ID_VP6A);
     s->vp56_coord_div = vp6_coord_div;
     s->parse_vector_adjustment = vp6_parse_vector_adjustment;
     s->filter = vp6_filter;
index e6b0071ce6695e892b603477b41e7f24d639a00a..4d4ff6ca2d659329e998c5eab41d9b43f96f178e 100644 (file)
@@ -52,64 +52,59 @@ static void free_buffers(VP8Context *s)
     s->macroblocks = NULL;
 }
 
-static int vp8_alloc_frame(VP8Context *s, AVFrame *f)
+static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
 {
     int ret;
-    if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0)
+    if ((ret = ff_thread_get_buffer(s->avctx, &f->tf,
+                                    ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
         return ret;
-    if (s->num_maps_to_be_freed && !s->maps_are_invalid) {
-        f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed];
-    } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) {
-        ff_thread_release_buffer(s->avctx, f);
+    if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) {
+        ff_thread_release_buffer(s->avctx, &f->tf);
         return AVERROR(ENOMEM);
     }
     return 0;
 }
 
-static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_free, int can_direct_free)
+static void vp8_release_frame(VP8Context *s, VP8Frame *f)
 {
-    if (f->ref_index[0]) {
-        if (prefer_delayed_free) {
-            /* Upon a size change, we want to free the maps but other threads may still
-             * be using them, so queue them. Upon a seek, all threads are inactive so
-             * we want to cache one to prevent re-allocation in the next decoding
-             * iteration, but the rest we can free directly. */
-            int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segmentation_maps);
-            if (s->num_maps_to_be_freed < max_queued_maps) {
-                s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0];
-            } else if (can_direct_free) /* vp8_decode_flush(), but our queue is full */ {
-                av_free(f->ref_index[0]);
-            } /* else: MEMLEAK (should never happen, but better that than crash) */
-            f->ref_index[0] = NULL;
-        } else /* vp8_decode_free() */ {
-            av_free(f->ref_index[0]);
-        }
+    av_buffer_unref(&f->seg_map);
+    ff_thread_release_buffer(s->avctx, &f->tf);
+}
+
+static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src)
+{
+    int ret;
+
+    vp8_release_frame(s, dst);
+
+    if ((ret = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0)
+        return ret;
+    if (src->seg_map &&
+        !(dst->seg_map = av_buffer_ref(src->seg_map))) {
+        vp8_release_frame(s, dst);
+        return AVERROR(ENOMEM);
     }
-    ff_thread_release_buffer(s->avctx, f);
+
+    return 0;
 }
 
-static void vp8_decode_flush_impl(AVCodecContext *avctx,
-                                  int prefer_delayed_free, int can_direct_free, int free_mem)
+
+static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
 {
     VP8Context *s = avctx->priv_data;
     int i;
 
-    if (!avctx->internal->is_copy) {
-        for (i = 0; i < 5; i++)
-            if (s->frames[i].data[0])
-                vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free);
-    }
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+        vp8_release_frame(s, &s->frames[i]);
     memset(s->framep, 0, sizeof(s->framep));
 
-    if (free_mem) {
+    if (free_mem)
         free_buffers(s);
-        s->maps_are_invalid = 1;
-    }
 }
 
 static void vp8_decode_flush(AVCodecContext *avctx)
 {
-    vp8_decode_flush_impl(avctx, 1, 1, 0);
+    vp8_decode_flush_impl(avctx, 0);
 }
 
 static int update_dimensions(VP8Context *s, int width, int height)
@@ -122,7 +117,7 @@ static int update_dimensions(VP8Context *s, int width, int height)
         if (av_image_check_size(width, height, 0, s->avctx))
             return AVERROR_INVALIDDATA;
 
-        vp8_decode_flush_impl(s->avctx, 1, 0, 1);
+        vp8_decode_flush_impl(s->avctx, 1);
 
         avcodec_set_dimensions(s->avctx, width, height);
     }
@@ -1178,12 +1173,12 @@ static const uint8_t subpel_idx[3][8] = {
  */
 static av_always_inline
 void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
-                 AVFrame *ref, const VP56mv *mv,
+                 ThreadFrame *ref, const VP56mv *mv,
                  int x_off, int y_off, int block_w, int block_h,
                  int width, int height, int linesize,
                  vp8_mc_func mc_func[3][3])
 {
-    uint8_t *src = ref->data[0];
+    uint8_t *src = ref->f->data[0];
 
     if (AV_RN32A(mv)) {
 
@@ -1229,11 +1224,11 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
  */
 static av_always_inline
 void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2,
-                   AVFrame *ref, const VP56mv *mv, int x_off, int y_off,
+                   ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off,
                    int block_w, int block_h, int width, int height, int linesize,
                    vp8_mc_func mc_func[3][3])
 {
-    uint8_t *src1 = ref->data[1], *src2 = ref->data[2];
+    uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2];
 
     if (AV_RN32A(mv)) {
         int mx = mv->x&7, mx_idx = subpel_idx[0][mx];
@@ -1272,7 +1267,7 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst
 
 static av_always_inline
 void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
-                 AVFrame *ref_frame, int x_off, int y_off,
+                 ThreadFrame *ref_frame, int x_off, int y_off,
                  int bx_off, int by_off,
                  int block_w, int block_h,
                  int width, int height, VP56mv *mv)
@@ -1310,7 +1305,7 @@ static av_always_inline void prefetch_motion(VP8Context *s, VP8Macroblock *mb, i
         int x_off = mb_x << 4, y_off = mb_y << 4;
         int mx = (mb->mv.x>>2) + x_off + 8;
         int my = (mb->mv.y>>2) + y_off;
-        uint8_t **src= s->framep[ref]->data;
+        uint8_t **src= s->framep[ref]->tf.f->data;
         int off= mx + (my + (mb_x&3)*4)*s->linesize + 64;
         /* For threading, a ff_thread_await_progress here might be useful, but
          * it actually slows down the decoder. Since a bad prefetch doesn't
@@ -1330,7 +1325,7 @@ void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
 {
     int x_off = mb_x << 4, y_off = mb_y << 4;
     int width = 16*s->mb_width, height = 16*s->mb_height;
-    AVFrame *ref = s->framep[mb->ref_frame];
+    ThreadFrame *ref = &s->framep[mb->ref_frame]->tf;
     VP56mv *bmv = mb->bmv;
 
     switch (mb->partitioning) {
@@ -1589,17 +1584,9 @@ static av_always_inline void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Fi
     }
 }
 
-static void release_queued_segmaps(VP8Context *s, int is_close)
-{
-    int leave_behind = is_close ? 0 : !s->maps_are_invalid;
-    while (s->num_maps_to_be_freed > leave_behind)
-        av_freep(&s->segmentation_maps[--s->num_maps_to_be_freed]);
-    s->maps_are_invalid = 0;
-}
-
 #define MARGIN (16 << 2)
-static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe,
-                                   AVFrame *prev_frame)
+static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
+                                   VP8Frame *prev_frame)
 {
     VP8Context *s = avctx->priv_data;
     int mb_x, mb_y;
@@ -1617,8 +1604,9 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe,
         for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
             if (mb_y == 0)
                 AV_WN32A((mb-s->mb_width-1)->intra4x4_pred_mode_top, DC_PRED*0x01010101);
-            decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
-                           prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 1);
+            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+                           prev_frame && prev_frame->seg_map ?
+                           prev_frame->seg_map->data + mb_xy : NULL, 1);
             s->mv_min.x -= 64;
             s->mv_max.x -= 64;
         }
@@ -1672,13 +1660,13 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
     int mb_y = td->thread_mb_pos>>16;
     int i, y, mb_x, mb_xy = mb_y*s->mb_width;
     int num_jobs = s->num_jobs;
-    AVFrame *curframe = s->curframe, *prev_frame = s->prev_frame;
+    VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;
     VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions-1)];
     VP8Macroblock *mb;
     uint8_t *dst[3] = {
-        curframe->data[0] + 16*mb_y*s->linesize,
-        curframe->data[1] +  8*mb_y*s->uvlinesize,
-        curframe->data[2] +  8*mb_y*s->uvlinesize
+        curframe->tf.f->data[0] + 16*mb_y*s->linesize,
+        curframe->tf.f->data[1] +  8*mb_y*s->uvlinesize,
+        curframe->tf.f->data[2] +  8*mb_y*s->uvlinesize
     };
     if (mb_y == 0) prev_td = td;
     else           prev_td = &s->thread_data[(jobnr + num_jobs - 1)%num_jobs];
@@ -1697,7 +1685,7 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
     if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) {
         for (i = 0; i < 3; i++)
             for (y = 0; y < 16>>!!i; y++)
-                dst[i][y*curframe->linesize[i]-1] = 129;
+                dst[i][y*curframe->tf.f->linesize[i]-1] = 129;
         if (mb_y == 1) {
             s->top_border[0][15] = s->top_border[0][23] = s->top_border[0][31] = 129;
         }
@@ -1720,8 +1708,9 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
         s->vdsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2);
 
         if (!s->mb_layout)
-            decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy,
-                           prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 0);
+            decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+                           prev_frame && prev_frame->seg_map ?
+                           prev_frame->seg_map->data + mb_xy : NULL, 0);
 
         prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);
 
@@ -1780,7 +1769,7 @@ static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata,
     VP8Context *s = avctx->priv_data;
     VP8ThreadData *td = &s->thread_data[threadnr];
     int mb_x, mb_y = td->thread_mb_pos>>16, num_jobs = s->num_jobs;
-    AVFrame *curframe = s->curframe;
+    AVFrame *curframe = s->curframe->tf.f;
     VP8Macroblock *mb;
     VP8ThreadData *prev_td, *next_td;
     uint8_t *dst[3] = {
@@ -1834,7 +1823,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
     VP8Context *s = avctx->priv_data;
     VP8ThreadData *td = &s->thread_data[jobnr];
     VP8ThreadData *next_td = NULL, *prev_td = NULL;
-    AVFrame *curframe = s->curframe;
+    VP8Frame *curframe = s->curframe;
     int mb_y, num_jobs = s->num_jobs;
     td->thread_nr = threadnr;
     for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
@@ -1849,7 +1838,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
         s->mv_max.y -= 64;
 
         if (avctx->active_thread_type == FF_THREAD_FRAME)
-            ff_thread_report_progress(curframe, mb_y, 0);
+            ff_thread_report_progress(&curframe->tf, mb_y, 0);
     }
 
     return 0;
@@ -1861,9 +1850,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     VP8Context *s = avctx->priv_data;
     int ret, i, referenced, num_jobs;
     enum AVDiscard skip_thresh;
-    AVFrame *av_uninit(curframe), *prev_frame;
-
-    release_queued_segmaps(s, 0);
+    VP8Frame *av_uninit(curframe), *prev_frame;
 
     if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0)
         goto err;
@@ -1885,12 +1872,12 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     // release no longer referenced frames
     for (i = 0; i < 5; i++)
-        if (s->frames[i].data[0] &&
+        if (s->frames[i].tf.f->data[0] &&
             &s->frames[i] != prev_frame &&
             &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
             &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
-            vp8_release_frame(s, &s->frames[i], 1, 0);
+            vp8_release_frame(s, &s->frames[i]);
 
     // find a free buffer
     for (i = 0; i < 5; i++)
@@ -1905,8 +1892,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
         abort();
     }
-    if (curframe->data[0])
-        vp8_release_frame(s, curframe, 1, 0);
+    if (curframe->tf.f->data[0])
+        vp8_release_frame(s, curframe);
 
     // Given that arithmetic probabilities are updated every frame, it's quite likely
     // that the values we have on a random interframe are complete junk if we didn't
@@ -1919,10 +1906,9 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         goto err;
     }
 
-    curframe->key_frame = s->keyframe;
-    curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-    curframe->reference = referenced ? 3 : 0;
-    if ((ret = vp8_alloc_frame(s, curframe))) {
+    curframe->tf.f->key_frame = s->keyframe;
+    curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    if ((ret = vp8_alloc_frame(s, curframe, referenced))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
         goto err;
     }
@@ -1947,8 +1933,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     ff_thread_finish_setup(avctx);
 
-    s->linesize   = curframe->linesize[0];
-    s->uvlinesize = curframe->linesize[1];
+    s->linesize   = curframe->tf.f->linesize[0];
+    s->uvlinesize = curframe->tf.f->linesize[1];
 
     if (!s->thread_data[0].edge_emu_buffer)
         for (i = 0; i < MAX_THREADS; i++)
@@ -1973,7 +1959,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     // Make sure the previous frame has read its segmentation map,
     // if we re-use the same map.
     if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map)
-        ff_thread_await_progress(prev_frame, 1, 0);
+        ff_thread_await_progress(&prev_frame->tf, 1, 0);
 
     if (s->mb_layout == 1)
         vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
@@ -1993,7 +1979,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
     avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, num_jobs);
 
-    ff_thread_report_progress(curframe, INT_MAX, 0);
+    ff_thread_report_progress(&curframe->tf, INT_MAX, 0);
     memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
 
 skip_decode:
@@ -2003,7 +1989,8 @@ skip_decode:
         s->prob[0] = s->prob[1];
 
     if (!s->invisible) {
-        *(AVFrame*)data = *curframe;
+        if ((ret = av_frame_ref(data, curframe->tf.f)) < 0)
+            return ret;
         *got_frame      = 1;
     }
 
@@ -2013,33 +2000,62 @@ err:
     return ret;
 }
 
+static av_cold int vp8_decode_free(AVCodecContext *avctx)
+{
+    VP8Context *s = avctx->priv_data;
+    int i;
+
+    vp8_decode_flush_impl(avctx, 1);
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+        av_frame_free(&s->frames[i].tf.f);
+
+    return 0;
+}
+
+static av_cold int vp8_init_frames(VP8Context *s)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
+        s->frames[i].tf.f = av_frame_alloc();
+        if (!s->frames[i].tf.f)
+            return AVERROR(ENOMEM);
+    }
+    return 0;
+}
+
 static av_cold int vp8_decode_init(AVCodecContext *avctx)
 {
     VP8Context *s = avctx->priv_data;
+    int ret;
 
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    avctx->internal->allocate_progress = 1;
 
     ff_videodsp_init(&s->vdsp, 8);
     ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1);
     ff_vp8dsp_init(&s->vp8dsp);
 
-    return 0;
-}
+    if ((ret = vp8_init_frames(s)) < 0) {
+        vp8_decode_free(avctx);
+        return ret;
+    }
 
-static av_cold int vp8_decode_free(AVCodecContext *avctx)
-{
-    vp8_decode_flush_impl(avctx, 0, 1, 1);
-    release_queued_segmaps(avctx->priv_data, 1);
     return 0;
 }
 
 static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
 {
     VP8Context *s = avctx->priv_data;
+    int ret;
 
     s->avctx = avctx;
 
+    if ((ret = vp8_init_frames(s)) < 0) {
+        vp8_decode_free(avctx);
+        return ret;
+    }
+
     return 0;
 }
 
@@ -2049,11 +2065,11 @@ static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
 static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
 {
     VP8Context *s = dst->priv_data, *s_src = src->priv_data;
+    int i;
 
     if (s->macroblocks_base &&
         (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) {
         free_buffers(s);
-        s->maps_are_invalid = 1;
         s->mb_width  = s_src->mb_width;
         s->mb_height = s_src->mb_height;
     }
@@ -2063,7 +2079,14 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
     s->lf_delta = s_src->lf_delta;
     memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias));
 
-    memcpy(&s->frames, &s_src->frames, sizeof(s->frames));
+    for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) {
+        if (s_src->frames[i].tf.f->data[0]) {
+            int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]);
+            if (ret < 0)
+                return ret;
+        }
+    }
+
     s->framep[0] = REBASE(s_src->next_framep[0]);
     s->framep[1] = REBASE(s_src->next_framep[1]);
     s->framep[2] = REBASE(s_src->next_framep[2]);
index 392d0b44c99481347fc6a752250d69dc2f69a67e..8631c8f5dbbbd84e3c6766879553b95560cdd6f0 100644 (file)
 #ifndef AVCODEC_VP8_H
 #define AVCODEC_VP8_H
 
+#include "libavutil/buffer.h"
+
 #include "vp56.h"
 #include "vp56data.h"
 #include "vp8dsp.h"
 #include "h264pred.h"
+#include "thread.h"
 #if HAVE_PTHREADS
 #include <pthread.h>
 #elif HAVE_W32THREADS
@@ -122,14 +125,19 @@ typedef struct VP8ThreadData {
     VP8FilterStrength *filter_strength;
 } VP8ThreadData;
 
+typedef struct VP8Frame {
+    ThreadFrame tf;
+    AVBufferRef *seg_map;
+} VP8Frame;
+
 #define MAX_THREADS 8
 typedef struct VP8Context {
     VP8ThreadData *thread_data;
     AVCodecContext *avctx;
-    AVFrame *framep[4];
-    AVFrame *next_framep[4];
-    AVFrame *curframe;
-    AVFrame *prev_frame;
+    VP8Frame *framep[4];
+    VP8Frame *next_framep[4];
+    VP8Frame *curframe;
+    VP8Frame *prev_frame;
 
     uint16_t mb_width;   /* number of horizontal MB */
     uint16_t mb_height;  /* number of vertical MB */
@@ -251,17 +259,8 @@ typedef struct VP8Context {
     VP8DSPContext vp8dsp;
     H264PredContext hpc;
     vp8_mc_func put_pixels_tab[3][3][3];
-    AVFrame frames[5];
+    VP8Frame frames[5];
 
-    /**
-     * A list of segmentation_map buffers that are to be free()'ed in
-     * the next decoding iteration. We can't free() them right away
-     * because the map may still be used by subsequent decoding threads.
-     * Unused if frame threading is off.
-     */
-    uint8_t *segmentation_maps[5];
-    int num_maps_to_be_freed;
-    int maps_are_invalid;
     int num_jobs;
     /**
      * This describes the macroblock memory layout.
index ae854cda56cf41e7cac895a6c0f38d058df703f0..ed4d8147cbfe1aa479f750b4cca41f8613fd05b1 100644 (file)
@@ -94,7 +94,6 @@
 typedef struct VqaContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
     GetByteContext gb;
 
     uint32_t palette[PALETTE_COUNT];
@@ -188,8 +187,6 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
     }
     s->next_codebook_buffer_index = 0;
 
-    s->frame.data[0] = NULL;
-
     return 0;
 fail:
     av_freep(&s->codebook);
@@ -303,7 +300,7 @@ static int decode_format80(GetByteContext *gb, int src_size,
     return 0; // let's display what we decoded anyway
 }
 
-static int vqa_decode_chunk(VqaContext *s)
+static int vqa_decode_chunk(VqaContext *s, AVFrame *frame)
 {
     unsigned int chunk_type;
     unsigned int chunk_size;
@@ -471,7 +468,7 @@ static int vqa_decode_chunk(VqaContext *s)
         index_shift = 3;
     for (y = 0; y < s->height; y += s->vector_height) {
         for (x = 0; x < s->width; x += 4, lobytes++, hibytes++) {
-            pixel_ptr = y * s->frame.linesize[0] + x;
+            pixel_ptr = y * frame->linesize[0] + x;
 
             /* get the vector index, the method for which varies according to
              * VQA file version */
@@ -486,11 +483,11 @@ static int vqa_decode_chunk(VqaContext *s)
                 /* uniform color fill - a quick hack */
                 if (hibyte == 0xFF) {
                     while (lines--) {
-                        s->frame.data[0][pixel_ptr + 0] = 255 - lobyte;
-                        s->frame.data[0][pixel_ptr + 1] = 255 - lobyte;
-                        s->frame.data[0][pixel_ptr + 2] = 255 - lobyte;
-                        s->frame.data[0][pixel_ptr + 3] = 255 - lobyte;
-                        pixel_ptr += s->frame.linesize[0];
+                        frame->data[0][pixel_ptr + 0] = 255 - lobyte;
+                        frame->data[0][pixel_ptr + 1] = 255 - lobyte;
+                        frame->data[0][pixel_ptr + 2] = 255 - lobyte;
+                        frame->data[0][pixel_ptr + 3] = 255 - lobyte;
+                        pixel_ptr += frame->linesize[0];
                     }
                     lines=0;
                 }
@@ -511,11 +508,11 @@ static int vqa_decode_chunk(VqaContext *s)
             }
 
             while (lines--) {
-                s->frame.data[0][pixel_ptr + 0] = s->codebook[vector_index++];
-                s->frame.data[0][pixel_ptr + 1] = s->codebook[vector_index++];
-                s->frame.data[0][pixel_ptr + 2] = s->codebook[vector_index++];
-                s->frame.data[0][pixel_ptr + 3] = s->codebook[vector_index++];
-                pixel_ptr += s->frame.linesize[0];
+                frame->data[0][pixel_ptr + 0] = s->codebook[vector_index++];
+                frame->data[0][pixel_ptr + 1] = s->codebook[vector_index++];
+                frame->data[0][pixel_ptr + 2] = s->codebook[vector_index++];
+                frame->data[0][pixel_ptr + 3] = s->codebook[vector_index++];
+                pixel_ptr += frame->linesize[0];
             }
         }
     }
@@ -596,26 +593,23 @@ static int vqa_decode_frame(AVCodecContext *avctx,
                             AVPacket *avpkt)
 {
     VqaContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int res;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "  VQA Video: get_buffer() failed\n");
         return res;
     }
 
     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
-    if ((res = vqa_decode_chunk(s)) < 0)
+    if ((res = vqa_decode_chunk(s, frame)) < 0)
         return res;
 
     /* make the palette available on the way out */
-    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
-    s->frame.palette_has_changed = 1;
+    memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
+    frame->palette_has_changed = 1;
 
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
 
     /* report that the buffer was completely consumed */
     return avpkt->size;
@@ -629,9 +623,6 @@ static av_cold int vqa_decode_end(AVCodecContext *avctx)
     av_freep(&s->next_codebook_buffer);
     av_freep(&s->decode_buffer);
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
     return 0;
 }
 
index ca639ee54bf2de03688297b84dece8dd3799493f..37e87686ca14c51e06fa2e4ffd1254754cc03c54 100644 (file)
@@ -1205,7 +1205,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = s->samples;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 6fbef08920724fcfd60bfbfd0bcb50249f20dd11..14a1521b1f8ffe8250a19912dda7371231aa132e 100644 (file)
@@ -820,7 +820,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = nb_frames * s->frame_len;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index 747ac37dc00e6f19cb57d9d05b73873be4aff493..f9361baa7b657070bdc8bbf1ecf3ac75aa6aeb38 100644 (file)
@@ -1015,7 +1015,7 @@ static int decode_frame(WmallDecodeCtx *s)
     int more_frames = 0, len = 0, i, ret;
 
     s->frame.nb_samples = s->samples_per_frame;
-    if ((ret = ff_get_buffer(s->avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(s->avctx, &s->frame, 0)) < 0) {
         /* return an error if no frame could be decoded at all */
         av_log(s->avctx, AV_LOG_ERROR,
                "not enough space for the output samples\n");
index 0954795f31bd317350d26be4bff067050d76ed5f..66f27c86f3e37e72ef7064bcb6cf77ae56fc93d7 100644 (file)
@@ -1362,7 +1362,7 @@ static int decode_frame(WMAProDecodeCtx *s, AVFrame *frame, int *got_frame_ptr)
 
     /* get output buffer */
     frame->nb_samples = s->samples_per_frame;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         s->packet_loss = 1;
         return 0;
index f81e8e9403bbfdbd5ac3231a3c9f508afecc6002..f33def3b87f1476b8817a8ed6a1e73fea9669141 100644 (file)
@@ -1801,7 +1801,7 @@ static int synth_superframe(AVCodecContext *ctx, AVFrame *frame,
 
     /* get output buffer */
     frame->nb_samples = 480;
-    if ((res = ff_get_buffer(ctx, frame)) < 0) {
+    if ((res = ff_get_buffer(ctx, frame, 0)) < 0) {
         av_log(ctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return res;
     }
index acce8c7c0ff3d4728a3f6ac411a71644e816a2b4..f16b6de67efdb9fbaf6c4ad73cd9b7e6c60d376a 100644 (file)
@@ -31,7 +31,7 @@
 static void parse_mb_skip(Wmv2Context * w){
     int mb_x, mb_y;
     MpegEncContext * const s= &w->s;
-    uint32_t * const mb_type = s->current_picture_ptr->f.mb_type;
+    uint32_t * const mb_type = s->current_picture_ptr->mb_type;
 
     w->skip_type= get_bits(&s->gb, 2);
     switch(w->skip_type){
@@ -254,11 +254,11 @@ static int16_t *wmv2_pred_motion(Wmv2Context *w, int *px, int *py){
     wrap = s->b8_stride;
     xy = s->block_index[0];
 
-    mot_val = s->current_picture.f.motion_val[0][xy];
+    mot_val = s->current_picture.motion_val[0][xy];
 
-    A = s->current_picture.f.motion_val[0][xy - 1];
-    B = s->current_picture.f.motion_val[0][xy - wrap];
-    C = s->current_picture.f.motion_val[0][xy + 2 - wrap];
+    A = s->current_picture.motion_val[0][xy - 1];
+    B = s->current_picture.motion_val[0][xy - wrap];
+    C = s->current_picture.motion_val[0][xy + 2 - wrap];
 
     if(s->mb_x && !s->first_slice_line && !s->mspel && w->top_left_mv_flag)
         diff= FFMAX(FFABS(A[0] - B[0]), FFABS(A[1] - B[1]));
@@ -339,7 +339,7 @@ int ff_wmv2_decode_mb(MpegEncContext *s, int16_t block[6][64])
     if(w->j_type) return 0;
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
-        if (IS_SKIP(s->current_picture.f.mb_type[s->mb_y * s->mb_stride + s->mb_x])) {
+        if (IS_SKIP(s->current_picture.mb_type[s->mb_y * s->mb_stride + s->mb_x])) {
             /* skip mb */
             s->mb_intra = 0;
             for(i=0;i<6;i++)
index 0e727db4182769bd63c700c91eb7118991fea94b..2f9fc413b0b74578e3c293d4b8a20af51b9174f3 100644 (file)
@@ -32,7 +32,6 @@
 
 typedef struct WNV1Context {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int shift;
     GetBitContext gb;
@@ -65,7 +64,7 @@ static int decode_frame(AVCodecContext *avctx,
     WNV1Context * const l = avctx->priv_data;
     const uint8_t *buf    = avpkt->data;
     int buf_size          = avpkt->size;
-    AVFrame * const p     = &l->pic;
+    AVFrame * const p     = data;
     unsigned char *Y,*U,*V;
     int i, j, ret;
     int prev_y = 0, prev_u = 0, prev_v = 0;
@@ -77,11 +76,7 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR(ENOMEM);
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         av_free(rbuf);
         return ret;
@@ -125,7 +120,6 @@ static int decode_frame(AVCodecContext *avctx,
 
 
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
     av_free(rbuf);
 
     return buf_size;
@@ -148,24 +142,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx)
-{
-    WNV1Context * const l = avctx->priv_data;
-    AVFrame *pic = &l->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    return 0;
-}
-
 AVCodec ff_wnv1_decoder = {
     .name           = "wnv1",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_WNV1,
     .priv_data_size = sizeof(WNV1Context),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Winnov WNV1"),
index 62340c3bc58882628c7ed4315534ca62f9547dd3..14a93354efe22a8c6778d0da868ad4cf52f9adbf 100644 (file)
@@ -81,7 +81,7 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = out_size;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
index a1671e1cc59bbdf7227edf1de877acd56ca74253..ca2e8e0e2c266c09fa1a78aca4b79c7e5a47bbf9 100644 (file)
@@ -53,7 +53,6 @@ typedef struct XanContext {
 
     AVCodecContext *avctx;
     AVFrame last_frame;
-    AVFrame current_frame;
 
     const unsigned char *buf;
     int size;
@@ -187,7 +186,7 @@ static void xan_unpack(unsigned char *dest, int dest_len,
     }
 }
 
-static inline void xan_wc3_output_pixel_run(XanContext *s,
+static inline void xan_wc3_output_pixel_run(XanContext *s, AVFrame *frame,
     const unsigned char *pixel_buffer, int x, int y, int pixel_count)
 {
     int stride;
@@ -197,8 +196,8 @@ static inline void xan_wc3_output_pixel_run(XanContext *s,
     int width = s->avctx->width;
     unsigned char *palette_plane;
 
-    palette_plane = s->current_frame.data[0];
-    stride = s->current_frame.linesize[0];
+    palette_plane = frame->data[0];
+    stride = frame->linesize[0];
     line_inc = stride - width;
     index = y * stride + x;
     current_x = x;
@@ -217,7 +216,8 @@ static inline void xan_wc3_output_pixel_run(XanContext *s,
     }
 }
 
-static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
+static inline void xan_wc3_copy_pixel_run(XanContext *s, AVFrame *frame,
+                                          int x, int y,
                                           int pixel_count, int motion_x,
                                           int motion_y)
 {
@@ -232,11 +232,11 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
         x + motion_x < 0 || x + motion_x >= s->avctx->width)
         return;
 
-    palette_plane = s->current_frame.data[0];
+    palette_plane = frame->data[0];
     prev_palette_plane = s->last_frame.data[0];
     if (!prev_palette_plane)
         prev_palette_plane = palette_plane;
-    stride = s->current_frame.linesize[0];
+    stride = frame->linesize[0];
     line_inc = stride - width;
     curframe_index = y * stride + x;
     curframe_x = x;
@@ -268,7 +268,8 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int x, int y,
     }
 }
 
-static int xan_wc3_decode_frame(XanContext *s) {
+static int xan_wc3_decode_frame(XanContext *s, AVFrame *frame)
+{
 
     int width  = s->avctx->width;
     int height = s->avctx->height;
@@ -383,12 +384,12 @@ static int xan_wc3_decode_frame(XanContext *s) {
             flag ^= 1;
             if (flag) {
                 /* run of (size) pixels is unchanged from last frame */
-                xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
+                xan_wc3_copy_pixel_run(s, frame, x, y, size, 0, 0);
             } else {
                 /* output a run of pixels from imagedata_buffer */
                 if (imagedata_size < size)
                     break;
-                xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
+                xan_wc3_output_pixel_run(s, frame, imagedata_buffer, x, y, size);
                 imagedata_buffer += size;
                 imagedata_size -= size;
             }
@@ -399,7 +400,7 @@ static int xan_wc3_decode_frame(XanContext *s) {
             vector_segment++;
 
             /* copy a run of pixels from the previous frame */
-            xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
+            xan_wc3_copy_pixel_run(s, frame, x, y, size, motion_x, motion_y);
 
             flag = 0;
         }
@@ -499,6 +500,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int ret, buf_size = avpkt->size;
     XanContext *s = avctx->priv_data;
@@ -563,33 +565,28 @@ static int xan_decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    if ((ret = ff_get_buffer(avctx, &s->current_frame))) {
+    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF))) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
-    s->current_frame.reference = 3;
 
     if (!s->frame_size)
-        s->frame_size = s->current_frame.linesize[0] * s->avctx->height;
+        s->frame_size = frame->linesize[0] * s->avctx->height;
 
-    memcpy(s->current_frame.data[1],
+    memcpy(frame->data[1],
            s->palettes + s->cur_palette * AVPALETTE_COUNT, AVPALETTE_SIZE);
 
     s->buf = ctx.buffer;
     s->size = buf_size;
 
-    if (xan_wc3_decode_frame(s) < 0)
+    if (xan_wc3_decode_frame(s, frame) < 0)
         return AVERROR_INVALIDDATA;
 
-    /* release the last frame if it is allocated */
-    if (s->last_frame.data[0])
-        avctx->release_buffer(avctx, &s->last_frame);
+    av_frame_unref(&s->last_frame);
+    if ((ret = av_frame_ref(&s->last_frame, frame)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame*)data = s->current_frame;
-
-    /* shuffle frames */
-    FFSWAP(AVFrame, s->current_frame, s->last_frame);
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -599,11 +596,7 @@ static av_cold int xan_decode_end(AVCodecContext *avctx)
 {
     XanContext *s = avctx->priv_data;
 
-    /* release the frames */
-    if (s->last_frame.data[0])
-        avctx->release_buffer(avctx, &s->last_frame);
-    if (s->current_frame.data[0])
-        avctx->release_buffer(avctx, &s->current_frame);
+    av_frame_unref(&s->last_frame);
 
     av_freep(&s->buffer1);
     av_freep(&s->buffer2);
index ab45a5e35a0a5e27c32942fc7099c0d9410a72f3..e7948a0057e1af10aab512075ea99a5f98f96400 100644 (file)
 #include "avcodec.h"
 #include "internal.h"
 
-typedef struct VideoXLContext{
-    AVCodecContext *avctx;
-    AVFrame pic;
-} VideoXLContext;
-
 static const int xl_table[32] = {
    0,   1,   2,   3,   4,   5,   6,   7,
    8,   9,  12,  15,  20,  25,  34,  46,
@@ -46,28 +41,23 @@ static int decode_frame(AVCodecContext *avctx,
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
-    VideoXLContext * const a = avctx->priv_data;
-    AVFrame * const p = &a->pic;
+    AVFrame * const p = data;
     uint8_t *Y, *U, *V;
     int i, j, ret;
     int stride;
     uint32_t val;
     int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0){
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
     p->pict_type= AV_PICTURE_TYPE_I;
     p->key_frame= 1;
 
-    Y = a->pic.data[0];
-    U = a->pic.data[1];
-    V = a->pic.data[2];
+    Y = p->data[0];
+    U = p->data[1];
+    V = p->data[2];
 
     stride = avctx->width - 4;
 
@@ -117,42 +107,27 @@ static int decode_frame(AVCodecContext *avctx,
         }
 
         buf += avctx->width + 4;
-        Y += a->pic.linesize[0];
-        U += a->pic.linesize[1];
-        V += a->pic.linesize[2];
+        Y += p->linesize[0];
+        U += p->linesize[1];
+        V += p->linesize[2];
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = a->pic;
 
     return buf_size;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx){
-//    VideoXLContext * const a = avctx->priv_data;
-
     avctx->pix_fmt= AV_PIX_FMT_YUV411P;
 
     return 0;
 }
 
-static av_cold int decode_end(AVCodecContext *avctx){
-    VideoXLContext * const a = avctx->priv_data;
-    AVFrame *pic = &a->pic;
-
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    return 0;
-}
-
 AVCodec ff_xl_decoder = {
     .name           = "xl",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_VIXL,
-    .priv_data_size = sizeof(VideoXLContext),
     .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Miro VideoXL"),
index 274e4fa1039e9e3e1c5fb05bbd9cbe36e513f297..23f9c01d6000781cd92c390e60d7588e73bf5247 100644 (file)
 #include "internal.h"
 #include "xwd.h"
 
-static av_cold int xwd_decode_init(AVCodecContext *avctx)
-{
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
-    return 0;
-}
-
 static int xwd_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *p = avctx->coded_frame;
+    AVFrame *p = data;
     const uint8_t *buf = avpkt->data;
     int i, ret, buf_size = avpkt->size;
     uint32_t version, header_size, vclass, ncolors;
@@ -205,11 +196,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_PATCHWELCOME;
     }
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 0;
-    if ((ret = ff_get_buffer(avctx, p)) < 0) {
+    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -243,27 +230,14 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame       = 1;
-    *(AVFrame *)data = *p;
 
     return buf_size;
 }
 
-static av_cold int xwd_decode_close(AVCodecContext *avctx)
-{
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
-
-    return 0;
-}
-
 AVCodec ff_xwd_decoder = {
     .name           = "xwd",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_XWD,
-    .init           = xwd_decode_init,
-    .close          = xwd_decode_close,
     .decode         = xwd_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
index 31f475512a8bf36d650ff96d2c766b826a05edf9..47ab54a7f90ed56cb6e2ac410913dd094f339e62 100644 (file)
@@ -26,6 +26,7 @@
 #include "bytestream.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct XanContext {
     AVCodecContext *avctx;
@@ -379,11 +380,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
     int ftype;
     int ret;
 
-    s->pic.reference = 1;
-    s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &s->pic))) {
+    if ((ret = ff_reget_buffer(avctx, &s->pic))) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -404,8 +401,10 @@ static int xan_decode_frame(AVCodecContext *avctx,
     if (ret)
         return ret;
 
+    if ((ret = av_frame_ref(data, &s->pic)) < 0)
+        return ret;
+
     *got_frame = 1;
-    *(AVFrame*)data = s->pic;
 
     return avpkt->size;
 }
@@ -414,8 +413,7 @@ static av_cold int xan_decode_end(AVCodecContext *avctx)
 {
     XanContext *s = avctx->priv_data;
 
-    if (s->pic.data[0])
-        avctx->release_buffer(avctx, &s->pic);
+    av_frame_unref(&s->pic);
 
     av_freep(&s->y_buffer);
     av_freep(&s->scratch_buffer);
index fd7f090839dc72fca8a507b985fb9125afff1c35..3a760c5345289c45738de09cba163c4ac7fd7120 100644 (file)
@@ -30,7 +30,6 @@
 #include "internal.h"
 
 typedef struct YopDecContext {
-    AVFrame frame;
     AVCodecContext *avctx;
 
     int num_pal_colors;
@@ -111,30 +110,22 @@ static av_cold int yop_decode_init(AVCodecContext *avctx)
     return 0;
 }
 
-static av_cold int yop_decode_close(AVCodecContext *avctx)
-{
-    YopDecContext *s = avctx->priv_data;
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-    return 0;
-}
-
 /**
  * Paint a macroblock using the pattern in paint_lut.
  * @param s codec context
  * @param tag the tag that was in the nibble
  */
-static int yop_paint_block(YopDecContext *s, int tag)
+static int yop_paint_block(YopDecContext *s, int linesize, int tag)
 {
     if (s->src_end - s->srcptr < paint_lut[tag][3]) {
         av_log(s->avctx, AV_LOG_ERROR, "Packet too small.\n");
         return AVERROR_INVALIDDATA;
     }
 
-    s->dstptr[0]                        = s->srcptr[0];
-    s->dstptr[1]                        = s->srcptr[paint_lut[tag][0]];
-    s->dstptr[s->frame.linesize[0]]     = s->srcptr[paint_lut[tag][1]];
-    s->dstptr[s->frame.linesize[0] + 1] = s->srcptr[paint_lut[tag][2]];
+    s->dstptr[0]            = s->srcptr[0];
+    s->dstptr[1]            = s->srcptr[paint_lut[tag][0]];
+    s->dstptr[linesize]     = s->srcptr[paint_lut[tag][1]];
+    s->dstptr[linesize + 1] = s->srcptr[paint_lut[tag][2]];
 
     // The number of src bytes consumed is in the last part of the lut entry.
     s->srcptr += paint_lut[tag][3];
@@ -145,23 +136,23 @@ static int yop_paint_block(YopDecContext *s, int tag)
  * Copy a previously painted macroblock to the current_block.
  * @param copy_tag the tag that was in the nibble
  */
-static int yop_copy_previous_block(YopDecContext *s, int copy_tag)
+static int yop_copy_previous_block(YopDecContext *s, int linesize, int copy_tag)
 {
     uint8_t *bufptr;
 
     // Calculate position for the copy source
     bufptr = s->dstptr + motion_vector[copy_tag][0] +
-             s->frame.linesize[0] * motion_vector[copy_tag][1];
+             linesize * motion_vector[copy_tag][1];
     if (bufptr < s->dstbuf) {
         av_log(s->avctx, AV_LOG_ERROR,
                "YOP: cannot decode, file probably corrupt\n");
         return AVERROR_INVALIDDATA;
     }
 
-    s->dstptr[0]                        = bufptr[0];
-    s->dstptr[1]                        = bufptr[1];
-    s->dstptr[s->frame.linesize[0]]     = bufptr[s->frame.linesize[0]];
-    s->dstptr[s->frame.linesize[0] + 1] = bufptr[s->frame.linesize[0] + 1];
+    s->dstptr[0]            = bufptr[0];
+    s->dstptr[1]            = bufptr[1];
+    s->dstptr[linesize]     = bufptr[linesize];
+    s->dstptr[linesize + 1] = bufptr[linesize + 1];
 
     return 0;
 }
@@ -188,6 +179,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                             AVPacket *avpkt)
 {
     YopDecContext *s = avctx->priv_data;
+    AVFrame *frame = data;
     int tag, firstcolor, is_odd_frame;
     int ret, i, x, y;
     uint32_t *palette;
@@ -197,34 +189,31 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    ret = ff_get_buffer(avctx, &s->frame);
+    ret = ff_get_buffer(avctx, frame, 0);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
     if (!avctx->frame_number)
-        memset(s->frame.data[1], 0, AVPALETTE_SIZE);
+        memset(frame->data[1], 0, AVPALETTE_SIZE);
 
-    s->dstbuf     = s->frame.data[0];
-    s->dstptr     = s->frame.data[0];
+    s->dstbuf     = frame->data[0];
+    s->dstptr     = frame->data[0];
     s->srcptr     = avpkt->data + 4;
     s->src_end    = avpkt->data + avpkt->size;
     s->low_nibble = NULL;
 
     is_odd_frame = avpkt->data[0];
     firstcolor   = s->first_color[is_odd_frame];
-    palette      = (uint32_t *)s->frame.data[1];
+    palette      = (uint32_t *)frame->data[1];
 
     for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3)
         palette[i + firstcolor] = (s->srcptr[0] << 18) |
                                   (s->srcptr[1] << 10) |
                                   (s->srcptr[2] << 2);
 
-    s->frame.palette_has_changed = 1;
+    frame->palette_has_changed = 1;
 
     for (y = 0; y < avctx->height; y += 2) {
         for (x = 0; x < avctx->width; x += 2) {
@@ -236,24 +225,21 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             tag = yop_get_next_nibble(s);
 
             if (tag != 0xf) {
-                ret = yop_paint_block(s, tag);
+                ret = yop_paint_block(s, frame->linesize[0], tag);
                 if (ret < 0)
                     return ret;
             } else {
                 tag = yop_get_next_nibble(s);
-                ret = yop_copy_previous_block(s, tag);
-                if (ret < 0) {
-                    avctx->release_buffer(avctx, &s->frame);
+                ret = yop_copy_previous_block(s, frame->linesize[0], tag);
+                if (ret < 0)
                     return ret;
-                }
             }
             s->dstptr += 2;
         }
-        s->dstptr += 2*s->frame.linesize[0] - x;
+        s->dstptr += 2*frame->linesize[0] - x;
     }
 
     *got_frame = 1;
-    *(AVFrame *) data = s->frame;
     return avpkt->size;
 }
 
@@ -263,7 +249,6 @@ AVCodec ff_yop_decoder = {
     .id             = AV_CODEC_ID_YOP,
     .priv_data_size = sizeof(YopDecContext),
     .init           = yop_decode_init,
-    .close          = yop_decode_close,
     .decode         = yop_decode_frame,
     .long_name      = NULL_IF_CONFIG_SMALL("Psygnosis YOP Video"),
     .capabilities   = CODEC_CAP_DR1,
index 8122cca3b2745bd53b76cd69e7eade93a6045b63..e503aa768912c116d1c7778ee86bbd2d24191bbc 100644 (file)
@@ -31,14 +31,12 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
                                   int *got_frame, AVPacket *avpkt)
 {
     ZeroCodecContext *zc = avctx->priv_data;
-    AVFrame *pic         = avctx->coded_frame;
+    AVFrame *pic         = data;
     AVFrame *prev_pic    = &zc->previous_frame;
     z_stream *zstream    = &zc->zstream;
     uint8_t *prev        = prev_pic->data[0];
     uint8_t *dst;
-    int i, j, zret;
-
-    pic->reference = 3;
+    int i, j, zret, ret;
 
     if (avpkt->flags & AV_PKT_FLAG_KEY) {
         pic->key_frame = 1;
@@ -61,7 +59,7 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    if (ff_get_buffer(avctx, pic) < 0) {
+    if (ff_get_buffer(avctx, pic, AV_GET_BUFFER_FLAG_REF) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
         return AVERROR(ENOMEM);
     }
@@ -82,7 +80,6 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
 
         zret = inflate(zstream, Z_SYNC_FLUSH);
         if (zret != Z_OK && zret != Z_STREAM_END) {
-            avctx->release_buffer(avctx, pic);
             av_log(avctx, AV_LOG_ERROR,
                    "Inflate failed with return code: %d.\n", zret);
             return AVERROR_INVALIDDATA;
@@ -96,16 +93,11 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
         dst  -= pic->linesize[0];
     }
 
-    /* Release the previous buffer if need be */
-    if (prev_pic->data[0])
-        avctx->release_buffer(avctx, prev_pic);
+    av_frame_unref(&zc->previous_frame);
+    if ((ret = av_frame_ref(&zc->previous_frame, pic)) < 0)
+        return ret;
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
-
-    /* Store the previous frame for use later.
-     * FFSWAP ensures that e.g. pic->data is NULLed. */
-    FFSWAP(AVFrame, *pic, *prev_pic);
 
     return avpkt->size;
 }
@@ -113,15 +105,10 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,
 static av_cold int zerocodec_decode_close(AVCodecContext *avctx)
 {
     ZeroCodecContext *zc = avctx->priv_data;
-    AVFrame *prev_pic    = &zc->previous_frame;
-
-    inflateEnd(&zc->zstream);
 
-    /* Release last frame */
-    if (prev_pic->data[0])
-        avctx->release_buffer(avctx, prev_pic);
+    av_frame_unref(&zc->previous_frame);
 
-    av_freep(&avctx->coded_frame);
+    inflateEnd(&zc->zstream);
 
     return 0;
 }
@@ -145,13 +132,6 @@ static av_cold int zerocodec_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame buffer.\n");
-        zerocodec_decode_close(avctx);
-        return AVERROR(ENOMEM);
-    }
-
     return 0;
 }
 
index 5d4254aec0d4ee4bfad1b4ee3d931d36c637cdb8..8cf6a0cb5bfedbc34e5eafe0b08ad6ad7d6cdc3d 100644 (file)
@@ -54,7 +54,6 @@ enum ZmbvFormat {
  */
 typedef struct ZmbvContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int bpp;
     unsigned int decomp_size;
@@ -400,6 +399,7 @@ static int zmbv_decode_intra(ZmbvContext *c)
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     ZmbvContext * const c = avctx->priv_data;
@@ -408,12 +408,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     int hi_ver, lo_ver, ret;
     uint8_t *tmp;
 
-    if (c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 1;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = ff_get_buffer(avctx, &c->pic)) < 0) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -524,12 +519,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         c->decomp_len = c->zstream.total_out;
     }
     if (c->flags & ZMBV_KEYFRAME) {
-        c->pic.key_frame = 1;
-        c->pic.pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
+        frame->pict_type = AV_PICTURE_TYPE_I;
         c->decode_intra(c);
     } else {
-        c->pic.key_frame = 0;
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
         if (c->decomp_len)
             c->decode_xor(c);
     }
@@ -539,7 +534,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         uint8_t *out, *src;
         int i, j;
 
-        out = c->pic.data[0];
+        out = frame->data[0];
         src = c->cur;
         switch (c->fmt) {
         case ZMBV_FMT_8BPP:
@@ -550,7 +545,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     out[i * 3 + 2] = c->pal[(*src) * 3 + 2];
                     src++;
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
         case ZMBV_FMT_15BPP:
@@ -562,7 +557,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     out[i * 3 + 1] = (tmp & 0x03E0) >> 2;
                     out[i * 3 + 2] = (tmp & 0x001F) << 3;
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
         case ZMBV_FMT_16BPP:
@@ -574,7 +569,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     out[i * 3 + 1] = (tmp & 0x07E0) >> 3;
                     out[i * 3 + 2] = (tmp & 0x001F) << 3;
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
 #ifdef ZMBV_ENABLE_24BPP
@@ -582,7 +577,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
             for (j = 0; j < c->height; j++) {
                 memcpy(out, src, c->width * 3);
                 src += c->width * 3;
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
 #endif //ZMBV_ENABLE_24BPP
@@ -593,7 +588,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                     src += 4;
                     AV_WB24(out+(i*3), tmp);
                 }
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
         default:
@@ -602,7 +597,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         FFSWAP(uint8_t *, c->cur, c->prev);
     }
     *got_frame = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -653,8 +647,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
     av_freep(&c->decomp_buf);
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
     inflateEnd(&c->zstream);
     av_freep(&c->cur);
     av_freep(&c->prev);