diff --git a/doc/multithreading.txt b/doc/multithreading.txt
index a1068425cd84cbfe01fa96dbf7c8cd61cc360f09..2b992fcbc53325577ad838dcf62519ff38493121 100644
--- a/doc/multithreading.txt
+++ b/doc/multithreading.txt
@@ -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
diff --git a/libavcodec/012v.c b/libavcodec/012v.c
index 6f4533b14c7d52ec6190dab9031dc8ce50bd0e45..51c0d0ca0f613bce577cca4798807e4fd9cb6e24 100644
--- a/libavcodec/012v.c
+++ b/libavcodec/012v.c
@@ -29,15 +29,9 @@ static av_cold int zero12v_decode_init(AVCodecContext *avctx)
     avctx->pix_fmt             = PIX_FMT_YUV422P16;
     avctx->bits_per_raw_sample = 10;
 
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
     if (avctx->codec_tag == MKTAG('a', '1', '2', 'v'))
         av_log_ask_for_sample(avctx, "Samples with actual transparency needed\n");
 
-    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
-    avctx->coded_frame->key_frame = 1;
     return 0;
 }
 
@@ -46,14 +40,11 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
 {
     int line = 0, ret;
     const int width = avctx->width;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     uint16_t *y, *u, *v;
     const uint8_t *line_end, *src = avpkt->data;
     int stride = avctx->width * 8 / 3;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (width == 1) {
         av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n");
         return AVERROR_INVALIDDATA;
@@ -64,10 +55,12 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
         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;
+    pic->key_frame = 1;
+
     y = (uint16_t *)pic->data[0];
     u = (uint16_t *)pic->data[1];
     v = (uint16_t *)pic->data[2];
@@ -145,27 +138,15 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame = 1;
-    *(AVFrame*)data= *avctx->coded_frame;
 
     return avpkt->size;
 }
 
-static av_cold int zero12v_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_zero12v_decoder = {
     .name           = "012v",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_012V,
     .init           = zero12v_decode_init,
-    .close          = zero12v_decode_close,
     .decode         = zero12v_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index e3d8486941af2e138ff6adfdaeff0f4105487937..6a6349115bcf222baf72223d695375da65bd8b8f 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -24,6 +24,7 @@
  * 4XM codec.
  */
 
+#include "libavutil/frame.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
@@ -255,15 +256,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;
     }
 }
 
@@ -404,14 +405,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;
 
@@ -455,7 +457,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)
@@ -519,12 +521,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;
@@ -682,14 +684,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;
     const uint8_t *buf_end = buf + length;
     GetByteContext g3;
 
@@ -731,7 +733,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;
@@ -785,7 +787,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);
         }
     }
 
@@ -802,7 +804,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;
 
     if (buf_size < 12)
@@ -880,34 +881,30 @@ static int decode_frame(AVCodecContext *avctx, void *data,
 
     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;
 
-    p->reference= 3;
-    if ((ret = avctx->reget_buffer(avctx, p)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, f->current_picture)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_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) {
+        f->current_picture->pict_type = AV_PICTURE_TYPE_I;
+        if ((ret = decode_i2_frame(f, f->current_picture, buf - 4, frame_size + 4)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n");
             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) {
+        f->current_picture->pict_type = AV_PICTURE_TYPE_I;
+        if ((ret = decode_i_frame(f, f->current_picture, buf, frame_size)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n");
             return ret;
         }
     } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
         if (!f->last_picture->data[0]) {
-            f->last_picture->reference = 3;
-            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;
             }
@@ -915,8 +912,8 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                 memset(f->last_picture->data[0] + i*f->last_picture->linesize[0], 0, 2*avctx->width);
         }
 
-        p->pict_type = AV_PICTURE_TYPE_P;
-        if ((ret = decode_p_frame(f, buf, frame_size)) < 0) {
+        f->current_picture->pict_type = AV_PICTURE_TYPE_P;
+        if ((ret = decode_p_frame(f, f->current_picture, buf, frame_size)) < 0) {
             av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
             return ret;
         }
@@ -928,9 +925,10 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                buf_size);
     }
 
-    p->key_frame = p->pict_type == AV_PICTURE_TYPE_I;
+    f->current_picture->key_frame = f->current_picture->pict_type == AV_PICTURE_TYPE_I;
 
-    *picture   = *p;
+    if ((ret = av_frame_ref(picture, f->current_picture)) < 0)
+        return ret;
     *got_frame = 1;
 
     emms_c();
@@ -961,13 +959,10 @@ 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->current_picture = av_frame_alloc();
+    f->last_picture    = av_frame_alloc();
+    if (!f->current_picture  || !f->last_picture)
         return AVERROR(ENOMEM);
-    }
 
     return 0;
 }
@@ -985,12 +980,8 @@ 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->current_picture);
+    av_frame_free(&f->last_picture);
 
     return 0;
 }
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index 158e29faeafd8dcd58c63807349584efb32b1a37..5f5dde62ff7206134137bd9a54b75010c4dac740 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -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;
@@ -70,12 +70,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;
     }
@@ -89,8 +84,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];
             if(lp - encoded + row*2 + 1 >= buf_size)
                 return -1;
             dlen = av_be2ne16(*(const unsigned short *)(lp + row * 2));
@@ -129,15 +124,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;
@@ -148,9 +142,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
     EightBpsContext * const c = avctx->priv_data;
 
     c->avctx       = avctx;
-    c->pic.data[0] = NULL;
 
-    avcodec_get_frame_defaults(&c->pic);
     switch (avctx->bits_per_coded_sample) {
     case 8:
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
@@ -188,23 +180,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"),
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index d33f73e0395f501d1eafb4790adfe141c8c35971..8f0fbade42374bd84dc1e89f0fb907773ddc6a74 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -136,7 +136,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = buf_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;
     }
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 7a871c40227fb6e34f4142b767c6cf3148618058..c69ec15bab6bee20b83dd2f08384adc67183e65f 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -190,8 +190,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;
     }
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index 308edd064773d9e21add426d11ce1de61f8da8ff..b47019601d55bef0862e9de3c9a15d0a578995af 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -29,12 +29,13 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "msrledec.h"
 
 typedef struct AascContext {
     AVCodecContext *avctx;
     GetByteContext gb;
-    AVFrame frame;
+    AVFrame *frame;
 
     uint32_t palette[AVPALETTE_COUNT];
     int palette_size;
@@ -68,7 +69,10 @@ static av_cold int aasc_decode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", avctx->bits_per_coded_sample);
         return -1;
     }
-    avcodec_get_frame_defaults(&s->frame);
+
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -87,9 +91,7 @@ static int aasc_decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    s->frame.reference = 3;
-    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;
     }
@@ -112,14 +114,14 @@ static int aasc_decode_frame(AVCodecContext *avctx,
                 av_log(avctx, AV_LOG_ERROR, "Next line is beyond buffer bounds\n");
                 break;
             }
-            memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width * psize);
+            memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize);
             buf += stride;
             buf_size -= 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);
@@ -132,10 +134,11 @@ static int aasc_decode_frame(AVCodecContext *avctx,
     }
 
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
-        memcpy(s->frame.data[1], s->palette, s->palette_size);
+        memcpy(s->frame->data[1], s->palette, s->palette_size);
 
     *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;
@@ -145,9 +148,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;
 }
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 51ef187cdb4403e81241c61b0c94c0a1bd5fec28..87f1067b916134e89e3f412c41ff1e467b10ec5e 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -1375,7 +1375,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;
     }
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 02de22cee734aa96ce33f62799fe25b3c72dcd81..a995b554a4d5564e714e7c5fc1bef3721682ffbb 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -637,7 +637,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;
     }
diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index aebf6910c9ed1b27f55beac731404010547b9ce3..b5868a09c5feaa6ac2ed3a0476e4d83ce3bc19d8 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -142,7 +142,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;
     }
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index f8ac560cb8dd3058257cc8dd99933bf405e09037..532b7ab6fb684be28ec97d7d336b7b1cf50dac55 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -289,7 +289,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;
         }
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index a6d70d44e2e8160bcdc2983d1fb9c9a834b20a23..d7cad19e300364d22ef6f83afd562c8f4cc7aeb4 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -1480,7 +1480,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;
     }
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index 6e14a60843213609397e62c358b65975876ec9c7..d186dccc4db32c030a7bdbaa48b8dfbe4b023dab 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -963,7 +963,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;
     }
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index c0481325e7343dace2dbaf1f5bce195d6f0b7b9d..0e9446f1be80f2d1684cc7139100264a60876585 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -1112,7 +1112,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;
     }
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index 08f5170e9bbe4fc1680c946357e72d30dcd0de69..4e9737f6a1768783197b232478dc2292d76b12e9 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -26,9 +26,10 @@
 
 #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,8 +42,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    avcodec_get_frame_defaults(&s->frame);
-    s->frame.reference = 3;
+    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;
@@ -114,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);
 
@@ -137,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;
@@ -169,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;
 }
 
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index 51339d24f9e0c0f660f81990095a186c6c4542dc..621f095f06ed182391045f7fb177e617079ba732 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -25,6 +25,7 @@
  */
 
 #include "libavutil/common.h"
+#include "libavutil/frame.h"
 #include "libavutil/lfg.h"
 #include "libavutil/xga_font_data.h"
 #include "avcodec.h"
@@ -50,7 +51,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) */
@@ -79,13 +80,16 @@ 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        = avpriv_vga16_font;
     s->font_height = 16;
     s->fg          = DEFAULT_FG_COLOR;
     s->bg          = DEFAULT_BG_COLOR;
 
-    avcodec_get_frame_defaults(&s->frame);
     if (!avctx->width || !avctx->height)
         avcodec_set_dimensions(avctx, 80<<3, 25<<4);
 
@@ -119,11 +123,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);
 }
 
@@ -132,7 +136,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);
 }
 
@@ -141,7 +145,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;
 }
 
@@ -162,8 +166,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;
@@ -240,17 +244,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;
-            set_palette((uint32_t *)s->frame.data[1]);
+            s->frame->pict_type           = AV_PICTURE_TYPE_I;
+            s->frame->palette_has_changed = 1;
+            set_palette((uint32_t *)s->frame->data[1]);
             erase_screen(avctx);
         } else if (c == 'l') {
             erase_screen(avctx);
@@ -261,13 +264,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);
@@ -348,20 +351,20 @@ 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) {
         for (i=0; i<avctx->height; i++)
-            memset(s->frame.data[0]+ i*s->frame.linesize[0], 0, avctx->width);
-        memset(s->frame.data[1], 0, AVPALETTE_SIZE);
+            memset(s->frame->data[0]+ i*s->frame->linesize[0], 0, avctx->width);
+        memset(s->frame->data[1], 0, AVPALETTE_SIZE);
     }
 
-    s->frame.pict_type           = AV_PICTURE_TYPE_I;
-    s->frame.palette_has_changed = 1;
-    set_palette((uint32_t *)s->frame.data[1]);
+    s->frame->pict_type           = AV_PICTURE_TYPE_I;
+    s->frame->palette_has_changed = 1;
+    set_palette((uint32_t *)s->frame->data[1]);
     if (!s->first_frame) {
         erase_screen(avctx);
         s->first_frame = 1;
@@ -449,15 +452,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;
 }
 
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index e0af6aad5f0964c19ceabd38ef399c4049d633ad..875234138199267eba55a83bdd6521cb5114fc30 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -904,7 +904,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;
     }
diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index e7a04cdd9372ad6be9287e1ebacc250651248c29..532c9e59a6f8cae954e2e45f10c81bf12db9762b 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -180,14 +180,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]);
@@ -195,8 +195,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]);
     }
 }
 
@@ -207,15 +207,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;
     }
@@ -242,7 +237,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);
         }
     }
 
@@ -252,7 +247,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);
         }
     }
 
@@ -262,11 +257,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();
@@ -277,7 +271,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;
 
@@ -300,11 +293,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;
 }
 
@@ -313,12 +301,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;
 }
 
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index 72c1b508e78b5dee3b64d640071b2058d3669d54..5db608592ffb8b5b45e1c71049188799a9f456b7 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -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;
     }
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index 62165363639d9696c63dc32c94cefa7844700488..0c42a6d4fdccbcbabe34e07ce1417d8032c1ed75 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -813,7 +813,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;
     }
diff --git a/libavcodec/aura.c b/libavcodec/aura.c
index c591f2f6db55abf95b50502a014f0a7fd63a8b78..bb2be7ee9fd23b6feb64655a0601c0b492c76d1e 100644
--- a/libavcodec/aura.c
+++ b/libavcodec/aura.c
@@ -27,21 +27,12 @@
 #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);
     avctx->pix_fmt = AV_PIX_FMT_YUV422P;
-    avcodec_get_frame_defaults(&s->frame);
 
     return 0;
 }
@@ -50,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;
@@ -68,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++) {
@@ -103,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"),
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 36c110607dfc1ba4af2d2828eb892738811d7faa..cc9adf753b88f8efbad90bfa32d42971ea877e8f 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -894,6 +894,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.
@@ -903,6 +904,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
@@ -1982,6 +1989,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.
      *
@@ -2041,7 +2049,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);
 
     /**
@@ -2052,7 +2063,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);
 
     /**
@@ -2067,8 +2081,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)
@@ -3488,9 +3594,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
@@ -4465,8 +4580,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.
  *
diff --git a/libavcodec/avrndec.c b/libavcodec/avrndec.c
index 0fc431d4da92ac3d5b60f11c7d800481da1af91e..882ee507691ba1cb018a90bde10100479af68443 100644
--- a/libavcodec/avrndec.c
+++ b/libavcodec/avrndec.c
@@ -27,7 +27,6 @@
 
 typedef struct {
     MJpegDecodeContext mjpeg_ctx;
-    AVFrame frame;
     int is_mjpeg;
     int interlace; //FIXME use frame.interlaced_frame
     int tff;
@@ -52,7 +51,6 @@ static av_cold int init(AVCodecContext *avctx)
     if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
         return ret;
 
-    avcodec_get_frame_defaults(&a->frame);
     avctx->pix_fmt = AV_PIX_FMT_UYVY422;
 
     if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
@@ -69,10 +67,6 @@ static av_cold int init(AVCodecContext *avctx)
 static av_cold int end(AVCodecContext *avctx)
 {
     AVRnContext *a = avctx->priv_data;
-    AVFrame *p = &a->frame;
-
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
 
     if(a->is_mjpeg)
         ff_mjpeg_decode_end(avctx);
@@ -84,7 +78,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
                         int *got_frame, AVPacket *avpkt)
 {
     AVRnContext *a = avctx->priv_data;
-    AVFrame *p = &a->frame;
+    AVFrame *p = data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
     int y, ret, true_height;
@@ -93,15 +87,13 @@ static int decode_frame(AVCodecContext *avctx, void *data,
         return ff_mjpeg_decode_frame(avctx, data, got_frame, avpkt);
 
     true_height    = buf_size / (2*avctx->width);
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
 
     if(buf_size < 2*avctx->width * avctx->height) {
         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
         return AVERROR_INVALIDDATA;
     }
 
-    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;
     }
@@ -123,7 +115,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *(AVFrame*)data = a->frame;
     *got_frame      = 1;
     return buf_size;
 }
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index e3d2070bb797938bcb9c018406b007b080071bc9..d5b21670c326e8745bf0dcc01405fc5253c772d6 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -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 = {0}; //init to silence warning
 
-    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 = 3;
     p->pict_type = AV_PICTURE_TYPE_P;
     p->key_frame = 0;
 
@@ -151,7 +151,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;
@@ -169,8 +170,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;
 }
 
diff --git a/libavcodec/avuidec.c b/libavcodec/avuidec.c
index 22af7190903fa23d229e582ead70ae0b82418ac6..689191d2e65272c1e9259117d5d7a7aeb122b6ba 100644
--- a/libavcodec/avuidec.c
+++ b/libavcodec/avuidec.c
@@ -27,30 +27,19 @@
 static av_cold int avui_decode_init(AVCodecContext *avctx)
 {
     avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
-
-    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 avui_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *src = avpkt->data, *extradata = avctx->extradata;
     const uint8_t *srca;
     uint8_t *y, *u, *v, *a;
     int transparent, interlaced = 1, skip, opaque_length, i, j, k;
     uint32_t extradata_size = avctx->extradata_size;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     while (extradata_size >= 24) {
         uint32_t atom_size = AV_RB32(extradata);
         if (!memcmp(&extradata[4], "APRGAPRG0001", 12)) {
@@ -78,9 +67,7 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data,
                   avpkt->size >= opaque_length * 2 + 4;
     srca = src + opaque_length + 5;
 
-    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);
     }
@@ -129,28 +116,16 @@ static int avui_decode_frame(AVCodecContext *avctx, void *data,
         srca += 4;
     }
     *got_frame       = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
 
-static av_cold int avui_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_avui_decoder = {
     .name         = "avui",
     .type         = AVMEDIA_TYPE_VIDEO,
     .id           = AV_CODEC_ID_AVUI,
     .init         = avui_decode_init,
     .decode       = avui_decode_frame,
-    .close        = avui_decode_close,
     .capabilities = CODEC_CAP_DR1,
     .long_name    = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"),
 };
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index 2a03f1adbe0c50b3d21f37146a7b90dfd49c2718..ed9525a41a578655e2ee9b2480d0aa0a86d312af 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -31,6 +31,7 @@
 #include "avcodec.h"
 #include "bethsoftvideo.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct BethsoftvidContext {
     AVFrame frame;
@@ -41,9 +42,6 @@ static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
 {
     BethsoftvidContext *vid = avctx->priv_data;
     avcodec_get_frame_defaults(&vid->frame);
-    vid->frame.reference = 3;
-    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;
 }
@@ -77,7 +75,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;
     }
@@ -138,8 +136,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;
 }
@@ -147,8 +147,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;
 }
 
diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c
index 231ee6220467347e860fe74bbe6f763fb8c806b7..da22cc00a87268431e17008e43ba5e1ac3927aef 100644
--- a/libavcodec/bfi.c
+++ b/libavcodec/bfi.c
@@ -33,7 +33,6 @@
 
 typedef struct BFIContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     uint8_t *dst;
     uint32_t pal[256];
 } BFIContext;
@@ -42,7 +41,6 @@ static av_cold int bfi_decode_init(AVCodecContext *avctx)
 {
     BFIContext *bfi = avctx->priv_data;
     avctx->pix_fmt  = AV_PIX_FMT_PAL8;
-    avcodec_get_frame_defaults(&bfi->frame);
     bfi->dst        = av_mallocz(avctx->width * avctx->height);
     return 0;
 }
@@ -50,6 +48,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;
@@ -59,12 +58,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 = 3;
-
-    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;
     }
@@ -73,14 +67,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 = 0xFFU << 24;
@@ -89,13 +83,13 @@ static int bfi_decode_frame(AVCodecContext *avctx, void *data,
                          (avctx->extradata[i * 3 + j] >> 4)) << shift;
             pal++;
         }
-        memcpy(bfi->pal, bfi->frame.data[1], sizeof(bfi->pal));
-        bfi->frame.palette_has_changed = 1;
+        memcpy(bfi->pal, frame->data[1], sizeof(bfi->pal));
+        frame->palette_has_changed = 1;
     } else {
-        bfi->frame.pict_type = AV_PICTURE_TYPE_P;
-        bfi->frame.key_frame = 0;
-        bfi->frame.palette_has_changed = 0;
-        memcpy(bfi->frame.data[1], bfi->pal, sizeof(bfi->pal));
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+        frame->palette_has_changed = 0;
+        memcpy(frame->data[1], bfi->pal, sizeof(bfi->pal));
     }
 
     bytestream2_skip(&g, 4); // Unpacked size, not required.
@@ -163,22 +157,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;
 }
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index 5d000a86b4d10430ee438dbeecc5ee78287b1b1f..5aeef2cf7b36ac62d32424e06c4bc16d2283887d 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -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;
@@ -800,8 +800,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;
@@ -815,13 +815,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;
@@ -832,7 +832,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) {
@@ -946,8 +946,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;
@@ -960,7 +960,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;
@@ -970,7 +970,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;
 
@@ -999,9 +999,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
@@ -1178,30 +1178,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')
@@ -1211,10 +1211,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;
         }
@@ -1223,11 +1223,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;
@@ -1328,12 +1326,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;
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index 5ba77a68f098a1ca0aa92f9f9760d88780d5aed9..7de2c245e06189e69465bfb55212d50c1a3d1ce0 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -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;
     }
diff --git a/libavcodec/bintext.c b/libavcodec/bintext.c
index 1c9bc3e6a1af8773c86f60e9efcbe73d36913245..b6d7d0f84cb06b789aa5791e080a1e70bbe5730f 100644
--- a/libavcodec/bintext.c
+++ b/libavcodec/bintext.c
@@ -33,9 +33,10 @@
 #include "avcodec.h"
 #include "cga_data.h"
 #include "bintext.h"
+#include "internal.h"
 
 typedef struct XbinContext {
-    AVFrame frame;
+    AVFrame *frame;
     int palette[16];
     int flags;
     int font_height;
@@ -91,6 +92,10 @@ static av_cold int decode_init(AVCodecContext *avctx)
         }
     }
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
@@ -101,10 +106,10 @@ av_unused static void hscroll(AVCodecContext *avctx)
     if (s->y < avctx->height - s->font_height) {
         s->y += s->font_height;
     } else {
-        memmove(s->frame.data[0], s->frame.data[0] + s->font_height*s->frame.linesize[0],
-            (avctx->height - s->font_height)*s->frame.linesize[0]);
-        memset(s->frame.data[0] + (avctx->height - s->font_height)*s->frame.linesize[0],
-            DEFAULT_BG_COLOR, s->font_height * s->frame.linesize[0]);
+        memmove(s->frame->data[0], s->frame->data[0] + s->font_height*s->frame->linesize[0],
+            (avctx->height - s->font_height)*s->frame->linesize[0]);
+        memset(s->frame->data[0] + (avctx->height - s->font_height)*s->frame->linesize[0],
+            DEFAULT_BG_COLOR, s->font_height * s->frame->linesize[0]);
     }
 }
 
@@ -118,8 +123,8 @@ static void draw_char(AVCodecContext *avctx, int c, int a)
     XbinContext *s = avctx->priv_data;
     if (s->y > avctx->height - s->font_height)
         return;
-    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,
+    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,
                     a & 0x0F, a >> 4);
     s->x += FONT_WIDTH;
     if (s->x > avctx->width - FONT_WIDTH) {
@@ -136,18 +141,16 @@ static int decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     const uint8_t *buf_end = buf+buf_size;
+    int ret;
 
     s->x = s->y = 0;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
-                            FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE;
-    if (avctx->reget_buffer(avctx, &s->frame)) {
+    if (ff_reget_buffer(avctx, s->frame) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
-    s->frame.pict_type           = AV_PICTURE_TYPE_I;
-    s->frame.palette_has_changed = 1;
-    memcpy(s->frame.data[1], s->palette, 16 * 4);
+    s->frame->pict_type           = AV_PICTURE_TYPE_I;
+    s->frame->palette_has_changed = 1;
+    memcpy(s->frame->data[1], s->palette, 16 * 4);
 
     if (avctx->codec_id == AV_CODEC_ID_XBIN) {
         while (buf + 2 < buf_end) {
@@ -201,8 +204,9 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
     *got_frame      = 1;
-    *(AVFrame*)data = s->frame;
     return buf_size;
 }
 
@@ -210,8 +214,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     XbinContext *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_free(&s->frame);
 
     return 0;
 }
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index fb69396ab49b66574caa9a5b2c3815d4f67164fa..fef2f2372d7d6c83ea347c64e23b96839b7f1682 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -25,25 +25,13 @@
 #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;
@@ -208,11 +196,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;
     }
@@ -341,29 +325,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)"),
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index c480815333b6f1f95f1c39a266e29b20bcfff476..78176f837f3385139c2b812c49a3a5b5cf8b71bb 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -44,7 +44,6 @@ enum BMVFlags{
 
 typedef struct BMVDecContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     uint8_t *frame, frame_base[SCREEN_WIDE * (SCREEN_HIGH + 1)];
     uint32_t pal[256];
@@ -200,6 +199,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;
@@ -242,11 +242,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;
     }
@@ -256,20 +252,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;
@@ -292,16 +287,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
 };
@@ -335,7 +320,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;
     }
@@ -363,7 +348,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"),
diff --git a/libavcodec/brender_pix.c b/libavcodec/brender_pix.c
index 6c63244ac9a6aef80bae346457e030f8b7d607ec..67bec05413da96d6f077d11978e7c57eb1a3a4d6 100644
--- a/libavcodec/brender_pix.c
+++ b/libavcodec/brender_pix.c
@@ -30,25 +30,11 @@
 #include "bytestream.h"
 #include "internal.h"
 
-typedef struct BRPixContext {
-    AVFrame frame;
-} BRPixContext;
-
 typedef struct BRPixHeader {
     int format;
     unsigned int width, height;
 } BRPixHeader;
 
-static av_cold int brpix_init(AVCodecContext *avctx)
-{
-    BRPixContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
-    return 0;
-}
-
 static int brpix_decode_header(BRPixHeader *out, GetByteContext *pgb)
 {
     unsigned int header_len = bytestream2_get_be32(pgb);
@@ -73,8 +59,7 @@ static int brpix_decode_frame(AVCodecContext *avctx,
                               void *data, int *got_frame,
                               AVPacket *avpkt)
 {
-    BRPixContext *s = avctx->priv_data;
-    AVFrame *frame_out = data;
+    AVFrame *frame = data;
 
     int ret;
     GetByteContext gb;
@@ -143,16 +128,13 @@ static int brpix_decode_frame(AVCodecContext *avctx,
         return AVERROR_PATCHWELCOME;
     }
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
     if (av_image_check_size(hdr.width, hdr.height, 0, avctx) < 0)
         return AVERROR_INVALIDDATA;
 
     if (hdr.width != avctx->width || hdr.height != avctx->height)
         avcodec_set_dimensions(avctx, hdr.width, hdr.height);
 
-    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;
     }
@@ -162,7 +144,7 @@ static int brpix_decode_frame(AVCodecContext *avctx,
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
         (chunk_type == 0x3 || chunk_type == 0x3d)) {
         BRPixHeader palhdr;
-        uint32_t *pal_out = (uint32_t *)s->frame.data[1];
+        uint32_t *pal_out = (uint32_t *)frame->data[1];
         int i;
 
         ret = brpix_decode_header(&palhdr, &gb);
@@ -190,17 +172,17 @@ static int brpix_decode_frame(AVCodecContext *avctx,
         }
         bytestream2_skip(&gb, 8);
 
-        s->frame.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
 
         chunk_type = bytestream2_get_be32(&gb);
     } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-        uint32_t *pal_out = (uint32_t *)s->frame.data[1];
+        uint32_t *pal_out = (uint32_t *)frame->data[1];
         int i;
 
         for (i = 0; i < 256; ++i) {
             *pal_out++ = (0xFFU << 24) | (i * 0x010101);
         }
-        s->frame.palette_has_changed = 1;
+        frame->palette_has_changed = 1;
     }
 
     data_len = bytestream2_get_be32(&gb);
@@ -218,35 +200,21 @@ static int brpix_decode_frame(AVCodecContext *avctx,
             return AVERROR_INVALIDDATA;
         }
 
-        av_image_copy_plane(s->frame.data[0], s->frame.linesize[0],
+        av_image_copy_plane(frame->data[0], frame->linesize[0],
                             avpkt->data + bytestream2_tell(&gb),
                             bytes_per_scanline,
                             bytes_per_scanline, hdr.height);
     }
 
-    *frame_out = s->frame;
     *got_frame = 1;
 
     return avpkt->size;
 }
 
-static av_cold int brpix_end(AVCodecContext *avctx)
-{
-    BRPixContext *s = avctx->priv_data;
-
-    if(s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
-
-    return 0;
-}
-
 AVCodec ff_brender_pix_decoder = {
     .name           = "brender_pix",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_BRENDER_PIX,
-    .priv_data_size = sizeof(BRPixContext),
-    .init           = brpix_init,
-    .close          = brpix_end,
     .decode         = brpix_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("BRender PIX image"),
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index e5f371b081445eebf14b102f164a27e4a670a92c..d587d3d5611aa7e6747e8fa5deadb2a4607ddecd 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -21,6 +21,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct {
     AVFrame pictures[2];
@@ -59,10 +60,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;
 }
 
@@ -124,17 +124,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 = 3;
-    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;
     }
@@ -243,7 +239,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;
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index adf0ecaa563b2cc6d96200d9eb618f62f8f1d607..dffd6cc8199ae2aa53e5771909e30b8ac9d935a7 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -738,9 +738,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);
@@ -771,15 +771,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]);
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index fa60d6c0eb8450e537eae5beac7b8fb527e98d6e..4d0bf90581a661f53cf38262929dedad3dd29e7a 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -948,6 +948,8 @@ static int decode_pic(AVSContext *h)
     int ret;
     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;
@@ -973,11 +975,10 @@ 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);
 
-    if ((ret = ff_get_buffer(h->avctx, h->cur.f)) < 0)
+    if ((ret = ff_get_buffer(h->avctx, h->cur.f,
+                             h->cur.f->pict_type == AV_PICTURE_TYPE_B ?
+                             0 : AV_GET_BUFFER_FLAG_REF)) < 0)
         return ret;
 
     if (!h->edge_emu_buffer) {
@@ -1075,8 +1076,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]);
     }
@@ -1142,19 +1142,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;
     }
@@ -1173,10 +1169,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:
@@ -1192,12 +1186,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);
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index 202211d124d8d5500044b9fdd067b3868d2fc084..f380dcdc9fcc0b789e6741d67c7d762af226f32f 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -64,26 +64,18 @@
 #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] = 0xFFU << 24 | 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) {
@@ -286,14 +278,14 @@ 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[1], 0, AVPALETTE_SIZE);
+        memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);
+        memset(cc->frame->data[1], 0, AVPALETTE_SIZE);
     }
 
     command = bytestream_get_byte(&buf);
@@ -306,8 +298,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:
@@ -341,28 +333,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;
 }
 
@@ -370,8 +367,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;
 }
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index 1af69b75b4611b883ce98c1cc7f60290ac6edc2a..8546e0bdb6da897dbbec1b9148bc0630aae0fbe5 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -35,7 +35,6 @@
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame        frame;
     int            bpp;
     int            format;
     int            padded_bits;
@@ -51,7 +50,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;
 
@@ -115,16 +113,16 @@ 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];
 
-    memset(c->frame.data[1], 0, AVPALETTE_SIZE);
+    memset(frame->data[1], 0, AVPALETTE_SIZE);
     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;
@@ -132,7 +130,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);
@@ -163,11 +161,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;
@@ -175,7 +173,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);
@@ -206,7 +204,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];
     }
 }
 
@@ -214,7 +212,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;
 
@@ -262,11 +260,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;
     }
@@ -278,14 +272,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;
 }
@@ -295,8 +288,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;
 }
diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index 5bd3f1349b950bbeb99ce796d4ddddab02807403..02f16ec09df498676d7802784b9c4093786c3613 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -40,6 +40,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 
 typedef uint8_t cvid_codebook[12];
@@ -57,7 +58,7 @@ typedef struct {
 typedef struct CinepakContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
+    AVFrame *frame;
 
     const unsigned char *data;
     int size;
@@ -143,14 +144,14 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
     for (y=strip->y1; y < strip->y2; y+=4) {
 
 /* take care of y dimension not being multiple of 4, such streams exist */
-        ip0 = ip1 = ip2 = ip3 = s->frame.data[0] +
-          (s->palette_video?strip->x1:strip->x1*3) + (y * s->frame.linesize[0]);
+        ip0 = ip1 = ip2 = ip3 = s->frame->data[0] +
+          (s->palette_video?strip->x1:strip->x1*3) + (y * s->frame->linesize[0]);
         if(s->avctx->height - y > 1) {
-            ip1 = ip0 + s->frame.linesize[0];
+            ip1 = ip0 + s->frame->linesize[0];
             if(s->avctx->height - y > 2) {
-                ip2 = ip1 + s->frame.linesize[0];
+                ip2 = ip1 + s->frame->linesize[0];
                 if(s->avctx->height - y > 3) {
-                    ip3 = ip2 + s->frame.linesize[0];
+                    ip3 = ip2 + s->frame->linesize[0];
                 }
             }
         }
@@ -359,7 +360,7 @@ static int cinepak_decode (CinepakContext *s)
 
     num_strips = FFMIN(num_strips, MAX_STRIPS);
 
-    s->frame.key_frame = 0;
+    s->frame->key_frame = 0;
 
     for (i=0; i < num_strips; i++) {
         if ((s->data + 12) > eod)
@@ -375,7 +376,7 @@ static int cinepak_decode (CinepakContext *s)
         s->strips[i].x2 = AV_RB16 (&s->data[10]);
 
         if (s->strips[i].id == 0x10)
-            s->frame.key_frame = 1;
+            s->frame->key_frame = 1;
 
         strip_size = AV_RB24 (&s->data[1]) - 12;
         if (strip_size < 0)
@@ -420,8 +421,9 @@ static av_cold int cinepak_decode_init(AVCodecContext *avctx)
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
     }
 
-    avcodec_get_frame_defaults(&s->frame);
-    s->frame.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -437,10 +439,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     s->data = buf;
     s->size = buf_size;
 
-    s->frame.reference = 3;
-    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)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -448,7 +447,7 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     if (s->palette_video) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
         if (pal) {
-            s->frame.palette_has_changed = 1;
+            s->frame->palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
     }
@@ -458,10 +457,12 @@ static int cinepak_decode_frame(AVCodecContext *avctx,
     }
 
     if (s->palette_video)
-        memcpy (s->frame.data[1], s->pal, AVPALETTE_SIZE);
+        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;
@@ -471,8 +472,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_free(&s->frame);
 
     return 0;
 }
diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c
index b93997f13d199b380186880f3335bcb66bbab7e1..7d4fd6897e08e4472bbc8b16ac2d28e76a05be3a 100644
--- a/libavcodec/cljr.c
+++ b/libavcodec/cljr.c
@@ -30,22 +30,6 @@
 #include "internal.h"
 #include "put_bits.h"
 
-typedef struct CLJRContext {
-    AVClass        *avclass;
-    AVFrame         picture;
-    int             dither_type;
-} CLJRContext;
-
-static av_cold int common_init(AVCodecContext *avctx)
-{
-    CLJRContext * const a = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&a->picture);
-    avctx->coded_frame = &a->picture;
-
-    return 0;
-}
-
 #if CONFIG_CLJR_DECODER
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
@@ -53,15 +37,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;
@@ -73,8 +52,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;
     }
@@ -84,9 +62,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)*33) >> 2;
             luma[2] = (get_bits(&gb, 5)*33) >> 2;
@@ -98,7 +76,6 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -107,15 +84,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;
 }
 
@@ -123,9 +91,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"),
@@ -133,6 +99,21 @@ AVCodec ff_cljr_decoder = {
 #endif
 
 #if CONFIG_CLJR_ENCODER
+typedef struct CLJRContext {
+    AVClass        *avclass;
+    AVFrame         picture;
+    int             dither_type;
+} 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)
 {
@@ -201,7 +182,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 },
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index d14de6080cd01e6c3f2cc1dfeb9e14137a538ecb..685ad593007a6d5984c5700a310d186f83a5556e 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -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;
 }
 
diff --git a/libavcodec/cngdec.c b/libavcodec/cngdec.c
index edfdd3e44cefc47d9e4e2533afb17fa03628b060..b22ee6885c1ecb97e4c4fdb5aac8d9a84e7017f4 100644
--- a/libavcodec/cngdec.c
+++ b/libavcodec/cngdec.c
@@ -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;
     }
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index 7dcf6558ec5bd03f6cc68c19a20cf2af3b2626a3..d9c443701bc9838442a765fe427ec2f97eaf5d96 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -970,7 +970,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;
         }
diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c
index a5ebc2f1ffd36ca1a47674b8cf58546c32629293..a29b651867643e016ab9a04899f98e93fd6f5f1f 100644
--- a/libavcodec/cpia.c
+++ b/libavcodec/cpia.c
@@ -24,6 +24,7 @@
 
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 
 
 #define FRAME_HEADER_SIZE 64
@@ -42,7 +43,7 @@
 
 
 typedef struct {
-    AVFrame frame;
+    AVFrame *frame;
 } CpiaContext;
 
 
@@ -58,7 +59,7 @@ static int cpia_decode_frame(AVCodecContext *avctx,
     uint16_t linelength;
     uint8_t skip;
 
-    AVFrame* const frame = &cpia->frame;
+    AVFrame *frame = cpia->frame;
     uint8_t *y, *u, *v, *y_end, *u_end, *v_end;
 
     // Check header
@@ -99,7 +100,7 @@ static int cpia_decode_frame(AVCodecContext *avctx,
     }
 
     // Get buffer filled with previous frame
-    if ((ret = avctx->reget_buffer(avctx, frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed!\n");
         return ret;
     }
@@ -184,13 +185,16 @@ static int cpia_decode_frame(AVCodecContext *avctx,
     }
 
     *got_frame = 1;
-    *(AVFrame*) data = *frame;
+    if ((ret = av_frame_ref(data, cpia->frame)) < 0)
+        return ret;
 
     return avpkt->size;
 }
 
 static av_cold int cpia_decode_init(AVCodecContext *avctx)
 {
+    CpiaContext *s = avctx->priv_data;
+
     // output pixel format
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
@@ -202,9 +206,21 @@ static av_cold int cpia_decode_init(AVCodecContext *avctx)
         avctx->time_base.den = 60;
     }
 
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
+
     return 0;
 }
 
+static av_cold int cpia_decode_end(AVCodecContext *avctx)
+{
+    CpiaContext *s = avctx->priv_data;
+
+    av_frame_free(&s->frame);
+
+    return 0;
+}
 
 AVCodec ff_cpia_decoder = {
     .name           = "cpia",
@@ -212,6 +228,7 @@ AVCodec ff_cpia_decoder = {
     .id             = AV_CODEC_ID_CPIA,
     .priv_data_size = sizeof(CpiaContext),
     .init           = cpia_decode_init,
+    .close          = cpia_decode_end,
     .decode         = cpia_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("CPiA video format"),
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index e2596a29e1e65bf0e49cf87127b69c276d051073..3e9b62bf81c4db66d836170973ad0f2b2ec6fedb 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -643,7 +643,7 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
     priv->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
                              FF_BUFFER_HINTS_REUSABLE;
     if (!priv->pic.data[0]) {
-        if (ff_get_buffer(avctx, &priv->pic) < 0) {
+        if (ff_get_buffer(avctx, &priv->pic, 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return RET_ERROR;
         }
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index 110b06fa2ba962f21509bd5c3231f0d91b75dd73..cc7fe950a80b9fc4db767b60dbfad7dc7559cd7a 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -31,7 +31,7 @@
 #include "libavutil/lzo.h"
 
 typedef struct {
-    AVFrame pic;
+    AVFrame *pic;
     int linelen, height, bpp;
     unsigned int decomp_size;
     unsigned char* decomp_buf;
@@ -67,7 +67,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     CamStudioContext *c = avctx->priv_data;
-    AVFrame *picture = data;
     int ret;
 
     if (buf_size < 2) {
@@ -75,10 +74,7 @@ static int 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_READABLE |
-                          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, "get_buffer() failed\n");
         return ret;
     }
@@ -109,19 +105,21 @@ 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;
-              copy_frame_default(&c->pic, c->decomp_buf,
+        c->pic->pict_type = AV_PICTURE_TYPE_I;
+        c->pic->key_frame = 1;
+              copy_frame_default(c->pic, c->decomp_buf,
                                  c->linelen, c->height);
     } else {
-        c->pic.pict_type = AV_PICTURE_TYPE_P;
-        c->pic.key_frame = 0;
-              add_frame_default(&c->pic, c->decomp_buf,
+        c->pic->pict_type = AV_PICTURE_TYPE_P;
+        c->pic->key_frame = 0;
+              add_frame_default(c->pic, c->decomp_buf,
                                 c->linelen, c->height);
     }
 
-    *picture = c->pic;
     *got_frame = 1;
+    if ((ret = av_frame_ref(data, c->pic)) < 0)
+        return ret;
+
     return buf_size;
 }
 
@@ -139,8 +137,6 @@ static av_cold int decode_init(AVCodecContext *avctx) {
             return AVERROR_INVALIDDATA;
     }
     c->bpp = avctx->bits_per_coded_sample;
-    avcodec_get_frame_defaults(&c->pic);
-    c->pic.data[0] = NULL;
     c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
     c->height = avctx->height;
     stride = FFALIGN(c->linelen, 4);
@@ -150,14 +146,16 @@ static av_cold int decode_init(AVCodecContext *avctx) {
         av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
         return AVERROR(ENOMEM);
     }
+    c->pic = av_frame_alloc();
+    if (!c->pic)
+        return AVERROR(ENOMEM);
     return 0;
 }
 
 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);
+    av_frame_free(&c->pic);
     return 0;
 }
 
diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c
index b3bf4f2b09a7891c073019440be405eb6255c205..8e45b3ad1234fa68601f85236d569c528ec7532a 100644
--- a/libavcodec/cyuv.c
+++ b/libavcodec/cyuv.c
@@ -40,7 +40,6 @@
 typedef struct CyuvDecodeContext {
     AVCodecContext *avctx;
     int width, height;
-    AVFrame frame;
 } CyuvDecodeContext;
 
 static av_cold int cyuv_decode_init(AVCodecContext *avctx)
@@ -53,7 +52,6 @@ static av_cold int cyuv_decode_init(AVCodecContext *avctx)
     if (s->width & 0x3)
         return AVERROR_INVALIDDATA;
     s->height = avctx->height;
-    avcodec_get_frame_defaults(&s->frame);
 
     return 0;
 }
@@ -65,6 +63,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;
@@ -106,35 +105,30 @@ 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];
 
     if (buf_size == rawsize) {
         int linesize = FFALIGN(s->width,2) * 2;
-        y_plane += s->frame.linesize[0] * s->height;
+        y_plane += frame->linesize[0] * s->height;
         for (stream_ptr = 0; stream_ptr < rawsize; stream_ptr += linesize) {
-            y_plane -= s->frame.linesize[0];
+            y_plane -= frame->linesize[0];
             memcpy(y_plane, buf+stream_ptr, linesize);
         }
     } else {
 
     /* 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++];
@@ -179,21 +173,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",
@@ -201,7 +184,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"),
@@ -215,7 +197,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)"),
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index 1b955e4e7be58b1435c3b0997eb2b4c9cfc046fa..fd518a755b5132554efaecc7acf6db330b230e88 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -2355,7 +2355,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;
     }
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index b324c6e5ba5c97e86eae2012831695e8bc3ec4b6..a2f18ae0e06c86e60dd4f5e9693ff92c99ebcbb4 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -29,8 +29,6 @@
 #include "libavutil/mem.h"
 
 typedef struct DfaContext {
-    AVFrame pic;
-
     uint32_t pal[256];
     uint8_t *frame_buf;
 } DfaContext;
@@ -317,6 +315,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;
@@ -325,10 +324,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;
     }
@@ -346,7 +342,7 @@ static int dfa_decode_frame(AVCodecContext *avctx,
                 s->pal[i] = bytestream2_get_be24(&gb) << 2;
                 s->pal[i] |= 0xFFU << 24 | (s->pal[i] >> 6) & 0x30303;
             }
-            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",
@@ -361,16 +357,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;
 }
@@ -379,9 +374,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;
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
index a791e8835a762e20f14b7f6265862b2d7276c9ca..aa158bfae19a0603d1b79abfeb1d82e73a7c5297 100644
--- a/libavcodec/diracdec.c
+++ b/libavcodec/diracdec.c
@@ -365,7 +365,7 @@ static void free_sequence_buffers(DiracContext *s)
 
     for (i = 0; i < MAX_FRAMES; i++) {
         if (s->all_frames[i].avframe.data[0]) {
-            s->avctx->release_buffer(s->avctx, &s->all_frames[i].avframe);
+            av_frame_unref(&s->all_frames[i].avframe);
             memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
         }
 
@@ -1671,7 +1671,7 @@ static int dirac_decode_picture_header(DiracContext *s)
             for (j = 0; j < MAX_FRAMES; j++)
                 if (!s->all_frames[j].avframe.data[0]) {
                     s->ref_pics[i] = &s->all_frames[j];
-                    ff_get_buffer(s->avctx, &s->ref_pics[i]->avframe);
+                    ff_get_buffer(s->avctx, &s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF);
                     break;
                 }
     }
@@ -1712,6 +1712,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
 {
     DiracFrame *out = s->delay_frames[0];
     int i, out_idx  = 0;
+    int ret;
 
     /* find frame with lowest picture number */
     for (i = 1; s->delay_frames[i]; i++)
@@ -1726,7 +1727,8 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
     if (out) {
         out->avframe.reference ^= DELAYED_PIC_REF;
         *got_frame = 1;
-        *(AVFrame *)picture = out->avframe;
+        if((ret = av_frame_ref(picture, &out->avframe)) < 0)
+            return ret;
     }
 
     return 0;
@@ -1809,7 +1811,7 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int
         pic->avframe.key_frame = s->num_refs == 0;             /* [DIRAC_STD] is_intra()      */
         pic->avframe.pict_type = s->num_refs + 1;              /* Definition of AVPictureType in avutil.h */
 
-        if (ff_get_buffer(avctx, &pic->avframe) < 0) {
+        if (ff_get_buffer(avctx, &pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
@@ -1836,11 +1838,12 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     uint8_t *buf        = pkt->data;
     int buf_size        = pkt->size;
     int i, data_unit_size, buf_idx = 0;
+    int ret;
 
     /* release unused frames */
     for (i = 0; i < MAX_FRAMES; i++)
         if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) {
-            avctx->release_buffer(avctx, &s->all_frames[i].avframe);
+            av_frame_unref(&s->all_frames[i].avframe);
             memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
         }
 
@@ -1906,12 +1909,14 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
         if (delayed_frame) {
             delayed_frame->avframe.reference ^= DELAYED_PIC_REF;
-            *(AVFrame*)data = delayed_frame->avframe;
+            if((ret=av_frame_ref(data, &delayed_frame->avframe)) < 0)
+                return ret;
             *got_frame = 1;
         }
     } else if (s->current_picture->avframe.display_picture_number == s->frame_number) {
         /* The right frame at the right time :-) */
-        *(AVFrame*)data = s->current_picture->avframe;
+        if((ret=av_frame_ref(data, &s->current_picture->avframe)) < 0)
+            return ret;
         *got_frame = 1;
     }
 
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index 429d9a518a8649ce9598ba4a48b5be932d326602..19921195b6f7bfbb8a70c2619aa3a6ba3974cddc 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -35,7 +35,6 @@
 
 typedef struct DNXHDContext {
     AVCodecContext *avctx;
-    AVFrame picture;
     GetBitContext gb;
     int64_t cid;                        ///< compression id
     unsigned int width, height;
@@ -67,10 +66,6 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
     DNXHDContext *ctx = avctx->priv_data;
 
     ctx->avctx = avctx;
-    avctx->coded_frame = &ctx->picture;
-    avcodec_get_frame_defaults(&ctx->picture);
-    ctx->picture.type = AV_PICTURE_TYPE_I;
-    ctx->picture.key_frame = 1;
     ctx->cid = -1;
     return 0;
 }
@@ -110,7 +105,8 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t 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;
@@ -124,8 +120,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);
     }
 
@@ -168,11 +164,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;
     }
@@ -284,11 +280,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;
@@ -309,19 +305,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;
@@ -342,7 +338,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++) {
@@ -352,7 +349,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");
         }
     }
@@ -365,6 +362,7 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     DNXHDContext *ctx = avctx->priv_data;
+    ThreadFrame frame = { .f = data };
     AVFrame *picture = data;
     int first_field = 1;
     int ret;
@@ -372,7 +370,7 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     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) &&
@@ -387,24 +385,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])
-            ff_thread_release_buffer(avctx, &ctx->picture);
-        if ((ret = ff_thread_get_buffer(avctx, &ctx->picture)) < 0) {
+        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             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 avpkt->size;
 }
@@ -413,8 +410,6 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
 {
     DNXHDContext *ctx = avctx->priv_data;
 
-    if (ctx->picture.data[0])
-        ff_thread_release_buffer(avctx, &ctx->picture);
     ff_free_vlc(&ctx->ac_vlc);
     ff_free_vlc(&ctx->dc_vlc);
     ff_free_vlc(&ctx->run_vlc);
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index 1ec837066d346bfb08d359c7b460a2a5724433d1..e6325ed637be5485d8f688817b7fb3052968854c 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -211,7 +211,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = (out + avctx->channels - 1) / 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;
     }
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index 310036b0cd06217d69e7851da669acdb9f978987..bcd72d263ae02420bfac65b6285833576a9e227c 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -25,11 +25,6 @@
 #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;
@@ -64,9 +59,7 @@ static int decode_frame(AVCodecContext *avctx,
 {
     const uint8_t *buf = avpkt->data;
     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[AV_NUM_DATA_POINTERS];
 
     unsigned int offset;
@@ -186,9 +179,7 @@ static int decode_frame(AVCodecContext *avctx,
             return AVERROR_INVALIDDATA;
     }
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-    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;
     }
@@ -262,36 +253,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,
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index 85eafcfcca46141f238cc491ceb8db52a48c9b93..4f6b731ea0b0ee5b2b32d72de61d44589ed60f32 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -305,8 +305,7 @@ 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 ((res = avctx->reget_buffer(avctx, &cin->frame))) {
+    if ((res = ff_reget_buffer(avctx, &cin->frame)) < 0) {
         av_log(cin->avctx, AV_LOG_ERROR, "failed to allocate a frame\n");
         return res;
     }
@@ -320,8 +319,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;
 }
@@ -330,8 +331,7 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
 {
     CinVideoContext *cin = avctx->priv_data;
 
-    if (cin->frame.data[0])
-        avctx->release_buffer(avctx, &cin->frame);
+    av_frame_unref(&cin->frame);
 
     destroy_buffers(cin);
 
@@ -363,7 +363,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;
     }
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index 64d2259a7b6c738d83ef700b4b4aedf09c01bffb..51e32b5fb31be1c986f9574aa3e981036c5d26f5 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -327,17 +327,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);
-
-    avcodec_get_frame_defaults(&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;
     }
@@ -361,7 +356,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
 
     /* return image */
     *got_frame = 1;
-    *(AVFrame*)data = s->picture;
+    av_frame_move_ref(data, &s->picture);
 
     return s->sys->frame_size;
 }
@@ -370,8 +365,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;
 }
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index a2fe5578df0316d4095f96ad0d80901bb660a42f..5d9da0011f3ca5093655035483224f46a535f6d2 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -39,7 +39,7 @@
  * Decoder context
  */
 typedef struct DxaDecContext {
-    AVFrame pic, prev;
+    AVFrame prev;
 
     int dsize;
     uint8_t *decomp_buf;
@@ -49,12 +49,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;
@@ -192,6 +192,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;
     DxaDecContext * const c = avctx->priv_data;
     uint8_t *outptr, *srcptr, *tmpptr;
     unsigned long dsize;
@@ -211,17 +212,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         pc = 1;
     }
 
-    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 (bytestream2_get_le32(&gb) == MKTAG('N','U','L','L'))
         compr = -1;
@@ -239,22 +240,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) && tmpptr){
                 for(i = 0; i < avctx->width; i++)
@@ -268,25 +269,24 @@ 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;
+        frame->key_frame = 0;
+        frame->pict_type = AV_PICTURE_TYPE_P;
         if (!c->prev.data[0]) {
             av_log(avctx, AV_LOG_ERROR, "Missing reference frame\n");
             return AVERROR_INVALIDDATA;
         }
-        decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]);
+        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", compr);
         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 avpkt->size;
@@ -298,7 +298,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    avcodec_get_frame_defaults(&c->pic);
     avcodec_get_frame_defaults(&c->prev);
 
     c->dsize = avctx->width * avctx->height * 2;
@@ -316,10 +315,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;
 }
diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c
index 30983f8056d3cb5611bc844551d1e25069785268..5b44f15d4fbebfad00932904d5c7ae4c29046fe2 100644
--- a/libavcodec/dxtory.c
+++ b/libavcodec/dxtory.c
@@ -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,
 };
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index d9d7d082483bffbe3d0363fbeaa4869effc1d998..355276b85154135ad66dc16a62808ad5edbb6f30 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -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]) {
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index 33c614588d461c0b2467177413f172df8ae3099f..78a42983a45a91fd62de04d1b87bc679ff51cc8f 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -36,31 +36,38 @@
 
 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;
 
 static av_cold int cmv_decode_init(AVCodecContext *avctx){
     CmvContext *s = avctx->priv_data;
-    avcodec_get_frame_defaults(&s->frame);
-    avcodec_get_frame_defaults(&s->last_frame);
-    avcodec_get_frame_defaults(&s->last2_frame);
 
     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;
     }
 }
@@ -84,7 +91,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;
 
@@ -92,29 +101,29 @@ 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;
-            if (s->last_frame.data[0])
-                cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
-                          s->last_frame.data[0], s->last_frame.linesize[0],
+            if (s->last_frame->data[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++;
@@ -134,10 +143,8 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t
     s->height = AV_RL16(&buf[6]);
     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])
-            s->avctx->release_buffer(s->avctx, &s->frame);
-        if (s->last_frame.data[0])
-            s->avctx->release_buffer(s->avctx, &s->last_frame);
+        av_frame_unref(s->last_frame);
+        av_frame_unref(s->last2_frame);
     }
 
     s->avctx->time_base.num = 1;
@@ -164,6 +171,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;
@@ -179,48 +188,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 = 3;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
-                            FF_BUFFER_HINTS_READABLE |
-                            FF_BUFFER_HINTS_PRESERVE;
-    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;
 }
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index b9679bca8612638a2ea047090bcccb6a17a255c7..1e8d395ae96d1fc37b11e69fec097ddcd7c21cc5 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -45,7 +45,6 @@
 typedef struct MadContext {
     AVCodecContext *avctx;
     DSPContext dsp;
-    AVFrame frame;
     AVFrame last_frame;
     GetBitContext gb;
     void *bitstream_buf;
@@ -78,15 +77,16 @@ 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) {
         unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
         if (offset >= (t->avctx->height - 7) * t->last_frame.linesize[0] - 7)
             return;
-        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] + offset,
              t->last_frame.linesize[0], add);
     } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
@@ -94,24 +94,25 @@ static inline void comp_block(MadContext *t, int mb_x, int mb_y,
         unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2);
         if (offset >= (t->avctx->height/2 - 7) * t->last_frame.linesize[index] - 7)
             return;
-        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] + offset,
              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);
     }
 }
 
@@ -186,7 +187,7 @@ static int decode_motion(GetBitContext *gb)
     return value;
 }
 
-static int decode_mb(MadContext *s, int inter)
+static int decode_mb(MadContext *s, AVFrame *frame, int inter)
 {
     int mv_map = 0;
     int mv_x, mv_y;
@@ -205,12 +206,12 @@ static int decode_mb(MadContext *s, int inter)
         if (mv_map & (1<<j)) {  // mv_x and mv_y are guarded by mv_map
             int add = 2*decode_motion(&s->gb);
             if (s->last_frame.data[0])
-                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);
             if(decode_block_intra(s, s->block) < 0)
                 return -1;
-            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);
         }
     }
     return 0;
@@ -233,9 +234,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;
-    int width, height, ret;
+    AVFrame *frame    = data;
+    int width, height;
     int chunk_type;
-    int inter;
+    int inter, ret;
 
     if (buf_size < 26) {
         av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n");
@@ -261,18 +263,12 @@ static int decode_frame(AVCodecContext *avctx,
         if ((ret = av_image_check_size(width, height, 0, avctx)) < 0)
             return ret;
         avcodec_set_dimensions(avctx, width, height);
-        if (s->frame.data[0])
-            avctx->release_buffer(avctx, &s->frame);
-        if (s->last_frame.data[0])
-            avctx->release_buffer(avctx, &s->last_frame);
+        av_frame_unref(&s->last_frame);
     }
 
-    s->frame.reference = 3;
-    if (!s->frame.data[0]) {
-        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, 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,
@@ -285,14 +281,16 @@ 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++)
-            if(decode_mb(s, inter) < 0)
+            if(decode_mb(s, frame, inter) < 0)
                 return AVERROR_INVALIDDATA;
 
     *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;
 }
@@ -300,10 +298,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;
 }
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index 524798b1b99d96e701586f7eeca06f3037c41480..cbf49a72bdbd895e3ac08a1ef08e58bff2afaa5d 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -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 int tgq_decode_mb(TgqContext *s, int mb_y, int mb_x)
+static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x)
 {
     int mode;
     int i;
@@ -160,7 +160,7 @@ static int tgq_decode_mb(TgqContext *s, int mb_y, int mb_x)
         init_get_bits(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), 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) {
@@ -178,7 +178,7 @@ static int tgq_decode_mb(TgqContext *s, int mb_y, int mb_x)
             av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode);
             return -1;
         }
-        tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc);
+        tgq_idct_put_mb_dconly(s, frame, mb_x, mb_y, dc);
     }
     return 0;
 }
@@ -201,6 +201,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;
 
@@ -220,48 +221,33 @@ 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++)
-            if (tgq_decode_mb(s, y, x) < 0)
+            if (tgq_decode_mb(s, frame, y, x) < 0)
                 return AVERROR_INVALIDDATA;
 
     *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"),
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index 7092ba679b26fd08b602a11681a0c93e1444e38d..54074b37ff98e3081edb79f8d593b19000387e82 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -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];
 
@@ -56,7 +57,6 @@ static av_cold int tgv_decode_init(AVCodecContext *avctx)
     s->avctx         = avctx;
     avctx->time_base = (AVRational){1, 15};
     avctx->pix_fmt   = AV_PIX_FMT_PAL8;
-    avcodec_get_frame_defaults(&s->frame);
     avcodec_get_frame_defaults(&s->last_frame);
     return 0;
 }
@@ -140,8 +140,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;
@@ -241,22 +241,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)
@@ -265,6 +256,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;
 
     if (buf_end - buf < EA_PREAMBLE_SIZE)
@@ -284,8 +276,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]);
@@ -299,46 +291,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 = 3;
-        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;
 }
@@ -346,8 +338,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;
@@ -362,4 +354,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,
 };
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index 5513848a8e4f4109034e9396253bc7a2f0881707..2c3e3efdbe6857353d51f560c78587217aacc76f 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -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,20 +132,17 @@ static int tqi_decode_frame(AVCodecContext *avctx,
     {
         if (tqi_decode_mb(s, t->block) < 0)
             goto end;
-        tqi_idct_put(t, t->block);
+        tqi_idct_put(t, frame, t->block);
     }
     end:
 
     *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;
 }
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 70a800a74654a3e2e95f699e76c26b5902db8532..078dc9f3368d64a78ea8ac71ebcb085351a45b44 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -147,7 +147,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
         for(b_x=0; b_x<w; b_x++){
             int mb_index_j= (b_x>>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= dc[b_x + b_y*stride];
                 distance= b_x;
@@ -160,7 +160,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
         for(b_x=w-1; b_x>=0; b_x--){
             int mb_index_j= (b_x>>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= dc[b_x + b_y*stride];
                 distance= b_x;
@@ -175,7 +175,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
         for(b_y=0; b_y<h; b_y++){
             int mb_index_j= (b_x>>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= dc[b_x + b_y*stride];
                 distance= b_y;
@@ -188,7 +188,7 @@ static void guess_dc(ERContext *s, int16_t *dc, int w,
         for(b_y=h-1; b_y>=0; b_y--){
             int mb_index_j= (b_x>>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= dc[b_x + b_y*stride];
                 distance= b_y;
@@ -205,7 +205,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
@@ -246,13 +246,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) &&
@@ -314,14 +314,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
@@ -386,7 +386,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
@@ -394,13 +394,13 @@ static void guess_mv(ERContext *s)
         fixed[mb_xy] = f;
         if (f == MV_FROZEN)
             num_avail++;
-        else if(s->last_pic->f.data[0] && s->last_pic->f.motion_val[0]){
+        else if(s->last_pic->f.data[0] && s->last_pic->motion_val[0]){
             const int mb_y= mb_xy / s->mb_stride;
             const int mb_x= mb_xy % s->mb_stride;
             const int mot_index= (mb_x + mb_y*mot_stride) * mot_step;
-            s->cur_pic->f.motion_val[0][mot_index][0]= s->last_pic->f.motion_val[0][mot_index][0];
-            s->cur_pic->f.motion_val[0][mot_index][1]= s->last_pic->f.motion_val[0][mot_index][1];
-            s->cur_pic->f.ref_index[0][4*mb_xy]      = s->last_pic->f.ref_index[0][4*mb_xy];
+            s->cur_pic->motion_val[0][mot_index][0]= s->last_pic->motion_val[0][mot_index][0];
+            s->cur_pic->motion_val[0][mot_index][1]= s->last_pic->motion_val[0][mot_index][1];
+            s->cur_pic->ref_index[0][4*mb_xy]      = s->last_pic->ref_index[0][4*mb_xy];
         }
     }
 
@@ -411,7 +411,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;
@@ -452,7 +452,7 @@ static void guess_mv(ERContext *s)
 
                     if (fixed[mb_xy] == MV_FROZEN)
                         continue;
-                    av_assert1(!IS_INTRA(s->cur_pic->f.mb_type[mb_xy]));
+                    av_assert1(!IS_INTRA(s->cur_pic->mb_type[mb_xy]));
                     av_assert1(s->last_pic && s->last_pic->f.data[0]);
 
                     j = 0;
@@ -483,38 +483,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)
@@ -572,19 +572,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 */
@@ -601,9 +601,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
@@ -648,8 +648,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,
@@ -731,7 +731,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);
@@ -740,7 +740,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--;
@@ -875,13 +875,25 @@ void ff_er_frame_end(ERContext *s)
         }
     }
 
-    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;
     }
@@ -1046,9 +1058,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
@@ -1056,15 +1068,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;
@@ -1083,13 +1095,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 */,
@@ -1103,7 +1115,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];
@@ -1125,12 +1137,12 @@ void ff_er_frame_end(ERContext *s)
                     int time_pb = s->pb_time;
 
                     av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);
-                    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;
@@ -1155,7 +1167,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];
 
@@ -1208,7 +1220,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];
 
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index 1865c3829fbc1454d5f0f9b7f5998901d54df7bd..3a4edecad13c2a5b723e19371833aa845448f032 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -79,8 +79,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;
 }
@@ -204,6 +203,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;
@@ -216,8 +216,7 @@ static int escape124_decode_frame(AVCodecContext *avctx,
     uint16_t* old_frame_data, *new_frame_data;
     unsigned old_stride, new_stride;
 
-    AVFrame new_frame;
-    avcodec_get_frame_defaults(&new_frame);
+    int ret;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -232,10 +231,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;
     }
@@ -268,14 +271,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;
 
@@ -356,10 +358,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;
diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c
index ca6a2531cef412550143b32f4fd5c5b2551f94b1..64d238307300fd3b0ee689724b13b84a46e85fb5 100644
--- a/libavcodec/escape130.c
+++ b/libavcodec/escape130.c
@@ -40,6 +40,7 @@ static av_cold int escape130_decode_init(AVCodecContext *avctx)
 {
     Escape130Context *s = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+    avcodec_get_frame_defaults(&s->frame);
 
     if((avctx->width&1) || (avctx->height&1)){
         av_log(avctx, AV_LOG_ERROR, "Dimensions are not a multiple of the block size\n");
@@ -55,8 +56,7 @@ static av_cold int escape130_decode_close(AVCodecContext *avctx)
 {
     Escape130Context *s = avctx->priv_data;
 
-    if (s->frame.data[0])
-        avctx->release_buffer(avctx, &s->frame);
+    av_frame_unref(&s->frame);
 
     av_freep(&s->bases);
 
@@ -108,6 +108,7 @@ static int escape130_decode_frame(AVCodecContext *avctx,
 
     GetBitContext gb;
     unsigned i;
+    int ret;
 
     uint8_t *old_y, *old_cb, *old_cr,
             *new_y, *new_cb, *new_cr;
@@ -120,7 +121,7 @@ static int escape130_decode_frame(AVCodecContext *avctx,
     unsigned y_base = 0;
     uint8_t *yb= s->bases;
 
-    AVFrame new_frame = { { 0 } };
+    AVFrame *frame = data;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -130,18 +131,17 @@ static int escape130_decode_frame(AVCodecContext *avctx,
     // Header; no useful information in here
     skip_bits_long(&gb, 128);
 
-    new_frame.reference = 3;
-    if (ff_get_buffer(avctx, &new_frame)) {
+    if (ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
 
-    new_y = new_frame.data[0];
-    new_cb = new_frame.data[1];
-    new_cr = new_frame.data[2];
-    new_y_stride = new_frame.linesize[0];
-    new_cb_stride = new_frame.linesize[1];
-    new_cr_stride = new_frame.linesize[2];
+    new_y = frame->data[0];
+    new_cb = frame->data[1];
+    new_cr = frame->data[2];
+    new_y_stride = frame->linesize[0];
+    new_cb_stride = frame->linesize[1];
+    new_cr_stride = frame->linesize[2];
     old_y = s->frame.data[0];
     old_cb = s->frame.data[1];
     old_cr = s->frame.data[2];
@@ -298,10 +298,10 @@ static int escape130_decode_frame(AVCodecContext *avctx,
            "Escape sizes: %i, %i\n",
            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 buf_size;
diff --git a/libavcodec/evrcdec.c b/libavcodec/evrcdec.c
index 5569ca251175280e30bf2ec19158ab30d41bacd4..76914554d407f2df94e4cf2fcda6930bf6a7f4b8 100644
--- a/libavcodec/evrcdec.c
+++ b/libavcodec/evrcdec.c
@@ -746,7 +746,7 @@ static int evrc_decode_frame(AVCodecContext *avctx, void *data,
     int   i, j, ret, error_flag = 0;
 
     frame->nb_samples = 160;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0)
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
     samples = (float *)frame->data[0];
 
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 143281751d4e1b9b0180ed17f1eda97bdd304b01..cc0995c2cf80c049eadde2dc35506a6d0288a0f7 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -70,7 +70,7 @@ typedef struct EXRThreadData {
 } EXRThreadData;
 
 typedef struct EXRContext {
-    AVFrame picture;
+    AVFrame *picture;
     int compr;
     enum ExrPixelType pixel_type;
     int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
@@ -336,7 +336,7 @@ static int decode_block(AVCodecContext *avctx, void *tdata,
                         int jobnr, int threadnr)
 {
     EXRContext *s = avctx->priv_data;
-    AVFrame *const p = &s->picture;
+    AVFrame *const p = s->picture;
     EXRThreadData *td = &s->thread_data[threadnr];
     const uint8_t *channel_buffer[4] = { 0 };
     const uint8_t *buf = s->buf;
@@ -458,8 +458,8 @@ static int decode_frame(AVCodecContext *avctx,
     const uint8_t *buf_end  = buf + buf_size;
 
     EXRContext *const s = avctx->priv_data;
+    ThreadFrame frame = { .f = data };
     AVFrame *picture  = data;
-    AVFrame *const p = &s->picture;
     uint8_t *ptr;
 
     int i, y, magic_number, version, flags, ret;
@@ -718,8 +718,6 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_PATCHWELCOME;
     }
 
-    if (s->picture.data[0])
-        ff_thread_release_buffer(avctx, &s->picture);
     if (av_image_check_size(w, h, 0, avctx))
         return AVERROR_INVALIDDATA;
 
@@ -756,7 +754,7 @@ static int decode_frame(AVCodecContext *avctx,
         memset(s->thread_data + prev_size, 0, s->thread_data_size - prev_size);
     }
 
-    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;
     }
@@ -764,46 +762,33 @@ static int decode_frame(AVCodecContext *avctx,
     if (buf_end - buf < scan_line_blocks * 8)
         return AVERROR_INVALIDDATA;
     s->table = buf;
-    ptr = p->data[0];
+    ptr = picture->data[0];
 
     // Zero out the start if ymin is not 0
     for (y = 0; y < s->ymin; y++) {
         memset(ptr, 0, out_line_size);
-        ptr += p->linesize[0];
+        ptr += picture->linesize[0];
     }
 
+    s->picture = picture;
     avctx->execute2(avctx, decode_block, s->thread_data, NULL, scan_line_blocks);
 
     // Zero out the end if ymax+1 is not h
     for (y = s->ymax + 1; y < avctx->height; y++) {
         memset(ptr, 0, out_line_size);
-        ptr += p->linesize[0];
+        ptr += picture->linesize[0];
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return buf_size;
 }
 
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    EXRContext *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)
 {
     EXRContext *s = avctx->priv_data;
     int i;
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
     for (i = 0; i < s->thread_data_size / sizeof(EXRThreadData); i++) {
         EXRThreadData *td = &s->thread_data[i];
         av_free(td->uncompressed_data);
@@ -822,7 +807,6 @@ AVCodec ff_exr_decoder = {
     .type               = AVMEDIA_TYPE_VIDEO,
     .id                 = AV_CODEC_ID_EXR,
     .priv_data_size     = sizeof(EXRContext),
-    .init               = decode_init,
     .close              = decode_end,
     .decode             = decode_frame,
     .capabilities       = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index c75f2aa619ab5cefa0c1e8683ad57d4f1b7af675..404b0e3a5960df3067a6fcbd8a1f4965b68110a2 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -191,10 +191,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];
diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h
index 02c3afa86e77d7b3e37842a83ff3d69d1a27dbbc..23633c9f9f21291a37837c614e7faf91d66b7e4e 100644
--- a/libavcodec/ffv1.h
+++ b/libavcodec/ffv1.h
@@ -89,8 +89,9 @@ typedef struct FFV1Context {
     int transparency;
     int flags;
     int picture_number;
-    AVFrame picture;
-    AVFrame last_picture;
+    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
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index cb72203468523dd335f84028c2efaa9b67f8c856..72e5ef338cee09784f13b1b1f59453f2d572d7cc 100644
--- a/libavcodec/ffv1dec.c
+++ b/libavcodec/ffv1dec.c
@@ -306,16 +306,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;
 }
@@ -326,7 +326,7 @@ static int decode_slice(AVCodecContext *c, void *arg)
     FFV1Context *f    = fs->avctx->priv_data;
     int width, height, x, y, ret;
     const int ps      = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1;
-    AVFrame * const p = &f->picture;
+    AVFrame * const p = f->cur;
 
     if (f->version > 2) {
         if (ffv1_init_slice_state(f, fs) < 0)
@@ -338,7 +338,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;
@@ -732,16 +732,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     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);
@@ -762,8 +758,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         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;
     }
@@ -806,6 +801,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
             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,
@@ -824,14 +821,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
             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,
@@ -841,10 +836,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
 
     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;
 }
diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c
index eb3b4551c0f5c442415c72052717944ca07869fb..4f392f2f3c7920fc8a5b30dbbcb380ae32be7a9b 100644
--- a/libavcodec/ffwavesynth.c
+++ b/libavcodec/ffwavesynth.c
@@ -444,7 +444,7 @@ static int wavesynth_decode(AVCodecContext *avc, void *rframe, int *rgot_frame,
     if (duration <= 0)
         return AVERROR(EINVAL);
     ws->frame.nb_samples = duration;
-    r = ff_get_buffer(avc, &ws->frame);
+    r = ff_get_buffer(avc, &ws->frame, 0);
     if (r < 0)
         return r;
     pcm = (int16_t *)ws->frame.data[0];
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index 91a25f02c48ad69ad15d7fd8973416a931def932..f3f46e685de3842d458b2e30e73aae01866ce992 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -545,7 +545,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;
     }
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 21464ed6b4aaf0439568c76a81b6586356ed2411..b5eb4355ab8e1efa1f6f4462b57dd91ba6c6c22b 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -41,6 +41,7 @@
 #include "avcodec.h"
 #include "bytestream.h"
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct BlockInfo {
     uint8_t *pos;
@@ -243,7 +244,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;
     int last_blockwidth = s->block_width;
     int last_blockheight= s->block_height;
@@ -337,13 +338,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 */
@@ -368,8 +365,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;
             }
 
@@ -451,8 +447,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",
@@ -468,8 +466,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);
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 2f8cd338027fd000872f919f1c5b63a526adbad5..caadbea19095243a09d62b7ebdef53cd3c723a61 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -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
@@ -185,9 +186,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 3;
-    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;
     }
@@ -466,8 +465,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;
 }
@@ -505,9 +506,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 3;
-    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;
     }
@@ -752,9 +751,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;
 }
@@ -800,8 +800,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;
 }
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
index 0ac018b35e7a2ef419429329e8143e4a1f5b21a5..b11a54af2bd8495c367e2add46face6e4e83f16e 100644
--- a/libavcodec/frame_thread_encoder.c
+++ b/libavcodec/frame_thread_encoder.c
@@ -92,9 +92,9 @@ static void * attribute_align_arg worker(void *v){
 
         ret = avcodec_encode_video2(avctx, pkt, frame, &got_packet);
         pthread_mutex_lock(&c->buffer_mutex);
-        c->parent_avctx->release_buffer(c->parent_avctx, frame);
+        av_frame_unref(frame);
         pthread_mutex_unlock(&c->buffer_mutex);
-        av_freep(&frame);
+        av_frame_free(&frame);
         if(got_packet) {
             av_dup_packet(pkt);
         } else {
@@ -222,11 +222,11 @@ int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVF
 
     if(frame){
         if(!(avctx->flags & CODEC_FLAG_INPUT_PRESERVED)){
-            AVFrame *new = avcodec_alloc_frame();
+            AVFrame *new = av_frame_alloc();
             if(!new)
                 return AVERROR(ENOMEM);
             pthread_mutex_lock(&c->buffer_mutex);
-            ret = ff_get_buffer(c->parent_avctx, new);
+            ret = ff_get_buffer(c->parent_avctx, new, 0);
             pthread_mutex_unlock(&c->buffer_mutex);
             if(ret<0)
                 return ret;
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index 5e2ba90d3f9b6f0fdefa6821f5af69b9efe48969..f80b41e6601a5948b7029179f922728b89ef221b 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -36,6 +36,7 @@
 #include "huffman.h"
 #include "bytestream.h"
 #include "dsputil.h"
+#include "internal.h"
 #include "thread.h"
 
 #define FPS_TAG MKTAG('F', 'P', 'S', 'x')
@@ -45,7 +46,6 @@
  */
 typedef struct FrapsContext {
     AVCodecContext *avctx;
-    AVFrame frame;
     uint8_t *tmpbuf;
     int tmpbuf_size;
     DSPContext dsp;
@@ -61,9 +61,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 {
     FrapsContext * const s = avctx->priv_data;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     s->avctx  = avctx;
     s->tmpbuf = NULL;
 
@@ -134,8 +131,8 @@ static int decode_frame(AVCodecContext *avctx,
     FrapsContext * const s = avctx->priv_data;
     const uint8_t *buf     = avpkt->data;
     int buf_size           = avpkt->size;
-    AVFrame *frame         = data;
-    AVFrame * const f      = &s->frame;
+    ThreadFrame frame = { .f = data };
+    AVFrame * const f = data;
     uint32_t header;
     unsigned int version,header_size;
     unsigned int x, y;
@@ -145,7 +142,6 @@ static int decode_frame(AVCodecContext *avctx,
     int i, j, ret, is_chroma;
     const int planes = 3;
     uint8_t *out;
-    enum AVPixelFormat pix_fmt;
 
     header      = AV_RL32(buf);
     version     = header & 0xff;
@@ -200,20 +196,12 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    if (f->data[0])
-        ff_thread_release_buffer(avctx, f);
     f->pict_type = AV_PICTURE_TYPE_I;
     f->key_frame = 1;
-    f->reference = 0;
-    f->buffer_hints = FF_BUFFER_HINTS_VALID;
 
-    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);
-    }
-    avctx->pix_fmt = pix_fmt;
+    avctx->pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
 
-    if ((ret = ff_thread_get_buffer(avctx, f))) {
+    if ((ret = ff_thread_get_buffer(avctx, &frame, 0))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -296,7 +284,6 @@ static int decode_frame(AVCodecContext *avctx,
         break;
     }
 
-    *frame = *f;
     *got_frame = 1;
 
     return buf_size;
@@ -312,9 +299,6 @@ 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_freep(&s->tmpbuf);
     return 0;
 }
diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c
index 43feb012f2498e797e6a844dfa610ded1f8de0ff..b7d8ca820c44656673934eedac20967c6209b0a6 100644
--- a/libavcodec/frwu.c
+++ b/libavcodec/frwu.c
@@ -38,10 +38,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;
 }
 
@@ -50,13 +46,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 {
     FRWUContext *s = avctx->priv_data;
     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;
@@ -66,8 +59,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;
     }
@@ -108,21 +100,10 @@ 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;
-}
-
 static const AVOption frwu_options[] = {
     {"change_field_order", "Change field order", offsetof(FRWUContext, change_field_order), FF_OPT_TYPE_INT,
      {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM},
@@ -142,7 +123,6 @@ AVCodec ff_frwu_decoder = {
     .id             = AV_CODEC_ID_FRWU,
     .priv_data_size = sizeof(FRWUContext),
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Forward Uncompressed"),
diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c
index b9c634b58046637efa34e2e5f869e195c7a7f8fa..796db920c2a937e4432656d7819ebf0754ca60ab 100644
--- a/libavcodec/g722dec.c
+++ b/libavcodec/g722dec.c
@@ -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;
     }
diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index d2cde8a864dc5621a6c2554d069ab1db71238cc7..7ee06c963cc5bde2282ee6d20111c21b001628e6 100644
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -1185,9 +1185,9 @@ static int g723_1_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     frame->nb_samples = FRAME_LEN;
-    if ((ret = ff_get_buffer(avctx, 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;
     }
 
     out = (int16_t *)frame->data[0];
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index 995d40a6c71c85305d268034684674a27cd14fb0..38f91a0af0c20d99940fadc27b0a280700d08788 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -449,7 +449,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;
     }
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
index db3f013f323b7acceab8968c7e4bbe41caa47b56..c9af3705b2fae563d60f9c28ed18383b88ab7391 100644
--- a/libavcodec/g729dec.c
+++ b/libavcodec/g729dec.c
@@ -420,7 +420,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
     int is_periodic = 0;         // whether one of the subframes is declared as periodic or not
 
     ctx->frame.nb_samples = SUBFRAME_SIZE<<1;
-    if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &ctx->frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 8fb1f4bbbd99eb3adb162ec1948a3a29becedea2..617e5b7583dbf877c31ee90ef593688b149083bf 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -39,7 +39,7 @@
 
 typedef struct GifState {
     const AVClass *class;
-    AVFrame picture;
+    AVFrame *frame;
     int screen_width;
     int screen_height;
     int has_global_palette;
@@ -130,7 +130,7 @@ static void gif_copy_img_rect(const uint32_t *src, uint32_t *dst,
     }
 }
 
-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, pal_size;
@@ -173,11 +173,11 @@ static int gif_read_image(GifState *s)
     if (s->keyframe) {
         if (s->transparent_color_index == -1 && s->has_global_palette) {
             /* transparency wasn't set before the first frame, fill with background color */
-            gif_fill(&s->picture, s->bg_color);
+            gif_fill(frame, s->bg_color);
         } else {
             /* otherwise fill with transparent color.
              * this is necessary since by default picture filled with 0x80808080. */
-            gif_fill(&s->picture, s->trans_color);
+            gif_fill(frame, s->trans_color);
         }
     }
 
@@ -190,10 +190,10 @@ static int gif_read_image(GifState *s)
 
     /* process disposal method */
     if (s->gce_prev_disposal == GCE_DISPOSAL_BACKGROUND) {
-        gif_fill_rect(&s->picture, s->stored_bg_color, s->gce_l, s->gce_t, s->gce_w, s->gce_h);
+        gif_fill_rect(frame, s->stored_bg_color, s->gce_l, s->gce_t, s->gce_w, s->gce_h);
     } else if (s->gce_prev_disposal == GCE_DISPOSAL_RESTORE) {
-        gif_copy_img_rect(s->stored_img, (uint32_t *)s->picture.data[0],
-            s->picture.linesize[0] / sizeof(uint32_t), s->gce_l, s->gce_t, s->gce_w, s->gce_h);
+        gif_copy_img_rect(s->stored_img, (uint32_t *)frame->data[0],
+            frame->linesize[0] / sizeof(uint32_t), s->gce_l, s->gce_t, s->gce_w, s->gce_h);
     }
 
     s->gce_prev_disposal = s->gce_disposal;
@@ -208,12 +208,12 @@ static int gif_read_image(GifState *s)
             else
                 s->stored_bg_color = s->bg_color;
         } else if (s->gce_disposal == GCE_DISPOSAL_RESTORE) {
-            av_fast_malloc(&s->stored_img, &s->stored_img_size, s->picture.linesize[0] * s->picture.height);
+            av_fast_malloc(&s->stored_img, &s->stored_img_size, frame->linesize[0] * frame->height);
             if (!s->stored_img)
                 return AVERROR(ENOMEM);
 
-            gif_copy_img_rect((uint32_t *)s->picture.data[0], s->stored_img,
-                s->picture.linesize[0] / sizeof(uint32_t), left, top, width, height);
+            gif_copy_img_rect((uint32_t *)frame->data[0], s->stored_img,
+                frame->linesize[0] / sizeof(uint32_t), left, top, width, height);
         }
     }
 
@@ -230,8 +230,8 @@ static int gif_read_image(GifState *s)
     }
 
     /* read all the image */
-    linesize = s->picture.linesize[0] / sizeof(uint32_t);
-    ptr1 = (uint32_t *)s->picture.data[0] + top * linesize + left;
+    linesize = frame->linesize[0] / sizeof(uint32_t);
+    ptr1 = (uint32_t *)frame->data[0] + top * linesize + left;
     ptr = ptr1;
     pass = 0;
     y1 = 0;
@@ -400,7 +400,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 (bytestream2_get_bytes_left(&s->gb)) {
         int code = bytestream2_get_byte(&s->gb);
@@ -410,7 +410,7 @@ static int gif_parse_next_image(GifState *s)
 
         switch (code) {
         case GIF_IMAGE_SEPARATOR:
-            return gif_read_image(s);
+            return gif_read_image(s, frame);
         case GIF_EXTENSION_INTRODUCER:
             if ((ret = gif_read_extension(s)) < 0)
                 return ret;
@@ -433,9 +433,9 @@ static av_cold int gif_decode_init(AVCodecContext *avctx)
     s->avctx = avctx;
 
     avctx->pix_fmt = AV_PIX_FMT_RGB32;
-    avcodec_get_frame_defaults(&s->picture);
-    avctx->coded_frame= &s->picture;
-    s->picture.data[0] = NULL;
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
     ff_lzw_decode_open(&s->lzw);
     return 0;
 }
@@ -443,15 +443,14 @@ static av_cold int gif_decode_init(AVCodecContext *avctx)
 static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
 {
     GifState *s = avctx->priv_data;
-    AVFrame *picture = data;
     int ret;
 
     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
-    s->picture.pts          = avpkt->pts;
-    s->picture.pkt_pts      = avpkt->pts;
-    s->picture.pkt_dts      = avpkt->dts;
-    av_frame_set_pkt_duration(&s->picture, avpkt->duration);
+    s->frame->pts     = avpkt->pts;
+    s->frame->pkt_pts = avpkt->pts;
+    s->frame->pkt_dts = avpkt->dts;
+    av_frame_set_pkt_duration(s->frame, avpkt->duration);
 
     if (avpkt->size >= 6) {
         s->keyframe = memcmp(avpkt->data, gif87a_sig, 6) == 0 ||
@@ -469,10 +468,8 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A
             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) {
+        av_frame_unref(s->frame);
+        if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -481,8 +478,8 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A
         if (!s->idx_line)
             return AVERROR(ENOMEM);
 
-        s->picture.pict_type = AV_PICTURE_TYPE_I;
-        s->picture.key_frame = 1;
+        s->frame->pict_type = AV_PICTURE_TYPE_I;
+        s->frame->key_frame = 1;
         s->keyframe_ok = 1;
     } else {
         if (!s->keyframe_ok) {
@@ -490,20 +487,21 @@ static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, A
             return AVERROR_INVALIDDATA;
         }
 
-        if ((ret = avctx->reget_buffer(avctx, &s->picture)) < 0) {
+        if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
             return ret;
         }
 
-        s->picture.pict_type = AV_PICTURE_TYPE_P;
-        s->picture.key_frame = 0;
+        s->frame->pict_type = AV_PICTURE_TYPE_P;
+        s->frame->key_frame = 0;
     }
 
-    ret = gif_parse_next_image(s);
+    ret = gif_parse_next_image(s, s->frame);
     if (ret < 0)
         return ret;
 
-    *picture = s->picture;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
     *got_frame = 1;
 
     return avpkt->size;
@@ -514,9 +512,7 @@ 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);
-
+    av_frame_free(&s->frame);
     av_freep(&s->idx_line);
     av_freep(&s->stored_img);
 
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index f20ef9a20ea0e03c7214d5beb013c256abb2b6a2..2db4bddc2858ba8f2fbb73107899f42e7effddc5 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -70,7 +70,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;
     }
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index eebfd02737103cf57de0c0825d61d26772f5fa60..f4f4dfb32055d58aaa6dc0bff94fc3dbe4409f90 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -215,7 +215,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;
@@ -330,14 +330,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;
 
@@ -632,8 +632,9 @@ retry:
     av_assert0(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
     av_assert0(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;
 
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index a7e60eac2c9df95110cab6f40080bd62dd81c773..e60e58e6b078be95e8db78880bee9be246097384 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -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 */
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 70e4febd228710e7147afd883cbb3cef88f1c277..4f3168256c64157ea54e6afa56e6d345c378c709 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -365,7 +365,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;
@@ -746,14 +747,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
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 56189614bb16917cab816afc31dab468314d6081..02b9a6773976885b6647ea481f949fc9f3c39d44 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -130,11 +130,11 @@ static void h264_er_decode_mb(void *opaque, int ref, int mv_dir, int mv_type,
         av_log(h->avctx, AV_LOG_DEBUG, "Reference not available for error concealing\n");
         ref = 0;
     }
-    if ((h->ref_list[0][ref].f.reference&3) != 3) {
+    if ((h->ref_list[0][ref].reference&3) != 3) {
         av_log(h->avctx, AV_LOG_DEBUG, "Reference invalid\n");
         return;
     }
-    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,
@@ -188,29 +188,26 @@ void ff_h264_draw_horiz_band(H264Context *h, int y, int height)
     }
 }
 
-static void free_frame_buffer(H264Context *h, Picture *pic)
-{
-    pic->period_since_free = 0;
-    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;
+
+    pic->period_since_free = 0;
+    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)
@@ -218,15 +215,76 @@ 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;
+    dst->sync                    = src->sync;
+    dst->period_since_free       = src->period_since_free;
+
+    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);
@@ -252,60 +310,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;
 
-    pic->owner2 = h;
+    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->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);
 }
 
@@ -317,9 +401,8 @@ static inline int pic_is_unused(H264Context *h, Picture *pic)
         return 0;
     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;
 }
 
@@ -327,17 +410,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;
@@ -594,8 +676,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;
@@ -607,8 +689,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;
@@ -625,7 +707,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;
@@ -697,7 +779,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;
 
@@ -705,24 +787,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);
                 }
@@ -814,7 +896,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);
     }
 
@@ -1043,13 +1125,17 @@ static void free_tables(H264Context *h, int free_rbsp)
     for (i = 0; i < 3; i++)
         av_freep(&h->visualization_buffer[i]);
 
-    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;
     }
 
@@ -1198,11 +1284,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);
     }
@@ -1413,8 +1498,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;
@@ -1462,6 +1545,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
     }
 
     ff_init_cabac_states();
+    avctx->internal->allocate_progress = 1;
 
     return 0;
 }
@@ -1470,7 +1554,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,
@@ -1482,7 +1566,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);
     }
@@ -1531,7 +1615,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)
         return 0;
@@ -1601,14 +1685,17 @@ static int decode_update_thread_context(AVCodecContext *dst,
         memset(&h->me, 0, sizeof(h->me));
         h->avctx = dst;
         h->DPB   = NULL;
+        h->qscale_table_pool = NULL;
+        h->mb_type_pool = NULL;
+        h->ref_index_pool = NULL;
+        h->motion_val_pool = NULL;
 
         if (h1->context_initialized) {
         h->context_initialized = 0;
 
-        h->picture_range_start  += MAX_PICTURE_COUNT;
-        h->picture_range_end    += MAX_PICTURE_COUNT;
-
-        h->cur_pic.f.extended_data = h->cur_pic.f.data;
+        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;
 
         if (ff_h264_alloc_tables(h) < 0) {
             av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");
@@ -1640,17 +1727,18 @@ 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++) {
         h->DPB[i].period_since_free ++;
+        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;
@@ -1741,7 +1829,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;
 
@@ -1761,8 +1849,9 @@ int ff_h264_frame_start(H264Context *h)
         avpriv_color_frame(&pic->f, c);
 
     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;
 
     if (CONFIG_ERROR_RESILIENCE) {
         ff_er_frame_start(&h->er);
@@ -1789,7 +1878,7 @@ int ff_h264_frame_start(H264Context *h)
            (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));
 
     // s->decode = (h->flags & CODEC_FLAG_PSNR) || !s->encoding ||
-    //             h->cur_pic.f.reference /* || h->contains_intra */ || 1;
+    //             h->cur_pic.reference /* || h->contains_intra */ || 1;
 
     /* We mark the current picture as non-reference after allocating it, so
      * that if we break out due to an error it can be released automatically
@@ -1798,7 +1887,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;
 
@@ -1823,7 +1912,6 @@ static void decode_postinit(H264Context *h, int setup_finished)
     Picture *cur = h->cur_pic_ptr;
     int i, pics, out_of_order, out_idx;
 
-    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)
@@ -1954,8 +2042,8 @@ static void decode_postinit(H264Context *h, int setup_finished)
     av_assert0(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;
 
     out = h->delayed_pic[0];
     out_idx = 0;
@@ -1973,10 +2061,9 @@ static void decode_postinit(H264Context *h, int setup_finished)
     out_of_order = out->poc < h->next_outputed_poc;
 
     if (out_of_order || 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];
     }
@@ -2400,7 +2487,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) {
@@ -2567,9 +2654,10 @@ static void flush_change(H264Context *h)
     h->outputed_poc = h->next_outputed_poc = INT_MIN;
     h->prev_interlaced_frame = 1;
     idr(h);
+
     h->prev_frame_num = -1;
     if (h->cur_pic_ptr) {
-        h->cur_pic_ptr->f.reference = 0;
+        h->cur_pic_ptr->reference = 0;
         for (j=i=0; h->delayed_pic[i]; i++)
             if (h->delayed_pic[i] != h->cur_pic_ptr)
                 h->delayed_pic[j++] = h->delayed_pic[i];
@@ -2595,17 +2683,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;
 
@@ -2738,7 +2825,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 &&
@@ -3132,9 +3219,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;
@@ -3362,11 +3448,11 @@ 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);
 
             /* 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,
+            if (!last_pic_droppable && h0->cur_pic_ptr->tf.owner == h0->avctx) {
+                ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                           last_pic_structure == PICT_BOTTOM_FIELD);
             }
 
@@ -3375,7 +3461,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                 /* 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 {
@@ -3385,7 +3471,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 {
@@ -3408,14 +3494,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;
                 }
             }
         }
@@ -3433,8 +3511,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;
@@ -3464,7 +3542,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) {
@@ -3474,7 +3552,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0)
                 h0->first_field = FIELD_PICTURE;
             } else {
                 if (h0->cur_pic_ptr->frame_num != h->frame_num) {
-                    ff_thread_report_progress((AVFrame*)h0->cur_pic_ptr, INT_MAX,
+                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,
                                               h0->picture_structure==PICT_BOTTOM_FIELD);
                     /* This and the previous field had different frame_nums.
                      * Consider this field first in pair. Throw away previous
@@ -3746,16 +3824,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;
                     }
@@ -3766,12 +3844,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->ref_count[0]) h->er.last_pic = &h->ref_list[0][0];
@@ -3834,11 +3912,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] = (void*)(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);
@@ -3849,14 +3927,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] =(void*)( 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);
@@ -3880,7 +3958,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] = (void*)(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;
@@ -3891,7 +3969,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);
@@ -3918,7 +3996,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)
@@ -3926,7 +4004,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;
         }
@@ -3940,25 +4018,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;
@@ -4063,7 +4141,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)
@@ -4098,8 +4176,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,
@@ -4121,9 +4199,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;
 }
 
@@ -4157,7 +4235,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);
 }
 
@@ -4720,9 +4798,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);
     }
 
@@ -4752,6 +4829,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     int buf_index      = 0;
     Picture *out;
     int i, out_idx;
+    int ret;
 
     h->flags  = avctx->flags;
 
@@ -4779,9 +4857,10 @@ static int decode_frame(AVCodecContext *avctx, void *data,
             h->delayed_pic[i] = h->delayed_pic[i + 1];
 
         if (out) {
-            out->f.reference &= ~DELAYED_PIC_REF;
+            out->reference &= ~DELAYED_PIC_REF;
+            if ((ret = av_frame_ref(pict, &out->f)) < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = out->f;
         }
 
         return buf_index;
@@ -4836,8 +4915,9 @@ not_extra:
         /* Wait for second field. */
         *got_frame = 0;
         if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
+            if ((ret = av_frame_ref(pict, &h->next_output_pic->f)) < 0)
+                return ret;
             *got_frame = 1;
-            *pict      = h->next_output_pic->f;
         }
     }
 
@@ -4872,13 +4952,15 @@ static av_cold int h264_decode_end(AVCodecContext *avctx)
     ff_h264_remove_all_refs(h);
     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;
 }
 
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 1dfb9fa3840feff2fa3061d3960b14c1203c411f..939426e9c57ecdb95cf93db2b10fb6d8d19a213f 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -270,8 +270,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
@@ -648,6 +646,11 @@ typedef struct H264Context {
     int16_t *dc_val_base;
 
     uint8_t *visualization_buffer[3]; ///< temporary buffer vor MV visualization
+
+    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[7][QP_MAX_NUM + 1]; ///< One chroma qp table for each possible bit depth (8-14).
@@ -903,7 +906,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);
@@ -924,7 +927,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]];
@@ -942,7 +945,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))
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 435343c989111a76d83e1ef95e019ec1ad176e85..b9c5bcad41979c156780f383846306e15b3b4201 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -1282,8 +1282,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] );
 }
@@ -1327,13 +1327,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;
@@ -1343,9 +1343,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;
     }
@@ -2316,7 +2316,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;
@@ -2418,7 +2418,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;
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index b75e653268b38cb6a3f394168324357c3953e7b5..e966878faeae1ef376c327537266133aff1431e5 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -770,11 +770,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;
     }
 
@@ -1074,7 +1074,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;
@@ -1155,7 +1155,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;
diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index c6be4557667e87076b18143a50ad28bbb87e9525..838aee7dcb3a42cd687d22d5ed1645d3c7910ada 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -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  = (void*)&h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = (void*)&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  = (void*)&h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = (void*)&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  = (void*)&h->ref_list[1][0].f.motion_val[0][h->mb2b_xy [mb_xy]];
-    l1mv1  = (void*)&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  = (void*)&h->ref_list[1][0].motion_val[0][h->mb2b_xy [mb_xy]];
+    l1mv1  = (void*)&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;
diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c
index 13d99f2306e7245ff6657d7fe2d84e65d252ce20..92f74b620d383e79b84e82c9d53557b404ad8bbd 100644
--- a/libavcodec/h264_loopfilter.c
+++ b/libavcodec/h264_loopfilter.c
@@ -253,10 +253,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 );
@@ -494,10 +494,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]);
@@ -512,12 +512,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);
@@ -577,12 +577,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.
             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, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_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);
                 //{ int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
-                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) {
@@ -662,7 +662,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, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], h->cur_pic.qscale_table[mbn_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);
         //{ int i; for (i = 0; i < 4; i++) tprintf(h->avctx, " bS[%d]:%d", i, bS[i]); tprintf(h->avctx, "\n"); }
@@ -703,7 +703,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;
@@ -759,9 +759,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;
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index 8830d3444bbbd066d1cf2fdb1f4018c329ce1f9d..d75a4dd1d1f8b81cfffe4504c5733149377d40a9 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -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;
@@ -272,7 +272,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;
diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c
index 2a035af27e66ca18e1949fa2c95fa8279eaa06aa..7aec43ba90cfd792cbd0c4df8a0e166883e3439a 100644
--- a/libavcodec/h264_mc_template.c
+++ b/libavcodec/h264_mc_template.c
@@ -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];
 
     av_assert2(IS_INTER(mb_type));
 
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index 41670fcbdcf52ee00a73933a34c8997499702b3c..492a9a794d0a544b07c7c41c27c5964b9a9b7888 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -47,15 +47,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];
@@ -252,8 +252,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;
@@ -369,7 +369,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) {
@@ -387,9 +387,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) {
@@ -409,11 +409,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)
@@ -479,7 +479,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];
 
                     av_assert2(left_xy[LTOP] == left_xy[LBOT]);
                     if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
@@ -601,9 +601,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;
             av_assert2(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
@@ -820,8 +820,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;
 }
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index d87106e7cb4bfd02cd07b73b427834de6f95d6a2..190aee5278f57a208ced7a7ae87167b89e914ded 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -34,13 +34,20 @@
 //#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];
@@ -48,10 +55,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;
@@ -67,9 +74,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;
@@ -133,8 +140,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);
@@ -182,13 +193,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;
@@ -225,11 +237,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;
                         }
@@ -246,8 +258,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;
@@ -265,9 +277,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);
                         }
@@ -287,7 +299,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){
                 for (i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)
                     h->last_pocs[i] = INT_MIN;
                 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;
             }
@@ -303,15 +315,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];
@@ -337,12 +349,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;
@@ -498,7 +510,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;
@@ -592,7 +604,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:
@@ -629,7 +641,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 "
@@ -648,7 +660,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;
         }
     }
 
diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c
index 159a517c982ce6b906903e466d6f87ef86ae30e3..8554ecf8f24957000ad8e988741c9fe8ad268d9b 100644
--- a/libavcodec/huffyuvdec.c
+++ b/libavcodec/huffyuvdec.c
@@ -256,7 +256,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;
     avcodec_get_frame_defaults(&s->picture);
     s->interlaced = s->height > 288;
 
@@ -364,7 +363,6 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
     HYuvContext *s = avctx->priv_data;
     int i;
 
-    avctx->coded_frame= &s->picture;
     if (ff_huffyuv_alloc_temp(s)) {
         ff_huffyuv_common_end(s);
         return AVERROR(ENOMEM);
@@ -473,7 +471,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];
@@ -490,14 +488,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;
 }
@@ -512,11 +510,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, ret;
 
-    AVFrame *picture = data;
-
     av_fast_padded_malloc(&s->bitstream_buffer,
                    &s->bitstream_buffer_size,
                    buf_size);
@@ -526,11 +523,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 ((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;
     }
@@ -601,7 +594,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;
@@ -623,7 +616,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         }
                     }
                 }
-                draw_slice(s, height);
+                draw_slice(s, p, height);
 
                 break;
             case MEDIAN:
@@ -680,7 +673,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);
 
@@ -695,7 +688,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                     }
                 }
 
-                draw_slice(s, height);
+                draw_slice(s, p, height);
                 break;
             }
         }
@@ -739,7 +732,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,
@@ -753,7 +746,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;
@@ -764,9 +756,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);
 
diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c
index 2070419d7e58c289779c2e49e18e1e3519dda74a..7e63da99878d05bd793454306622e02cb268ef0d 100644
--- a/libavcodec/idcinvideo.c
+++ b/libavcodec/idcinvideo.c
@@ -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 int idcin_decode_vlcs(IdcinContext *s)
+static int idcin_decode_vlcs(IdcinContext *s, AVFrame *frame)
 {
     hnode *hnodes;
     long x, y;
@@ -182,8 +179,8 @@ static int 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 int idcin_decode_vlcs(IdcinContext *s)
                 bit_pos--;
             }
 
-            s->frame.data[0][x] = node_num;
+            frame->data[0][x] = node_num;
             prev = node_num;
         }
     }
@@ -219,53 +216,39 @@ 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 ((ret = ff_get_buffer(avctx, &s->frame))) {
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    if (idcin_decode_vlcs(s))
+    if (idcin_decode_vlcs(s, frame))
         return AVERROR_INVALIDDATA;
 
     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"),
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 8e7f8cae468a19a21199ff41425bf31bbeb0c148..dc70b9fea4472e006c07a4a62306f65bf8fef0e0 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -40,7 +40,7 @@ typedef enum {
 } mask_type;
 
 typedef struct {
-    AVFrame frame;
+    AVFrame *frame;
     int planesize;
     uint8_t * planebuf;
     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
@@ -361,11 +361,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
 
     s->bpp = avctx->bits_per_coded_sample;
-    avcodec_get_frame_defaults(&s->frame);
+    s->frame = av_frame_alloc();
+    if (!s->frame)
+        return AVERROR(ENOMEM);
 
     if ((err = extract_header(avctx, NULL)) < 0)
         return err;
-    s->frame.reference = 3;
 
     return 0;
 }
@@ -662,18 +663,16 @@ static int decode_frame(AVCodecContext *avctx,
 
     if ((res = extract_header(avctx, avpkt)) < 0)
         return 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) {
+        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return res;
-    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
-        if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
+    }
+    if (!s->init && avctx->bits_per_coded_sample <= 8 &&
+        avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+        if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame->data[1])) < 0)
             return res;
-    } else if (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
+    } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
+               avctx->pix_fmt == AV_PIX_FMT_RGB32) {
         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
             return res;
     }
@@ -683,18 +682,18 @@ static int decode_frame(AVCodecContext *avctx,
     case 0:
         if (avctx->codec_tag == MKTAG('A','C','B','M')) {
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
-                memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
+                memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
                 for (plane = 0; plane < s->bpp; plane++) {
                     for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
-                        uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                        uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
                         buf += s->planesize;
                     }
                 }
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
-                memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
+                memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
                 for(y = 0; y < avctx->height; y++) {
-                    uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memset(s->ham_buf, 0, s->planesize * 8);
                     for (plane = 0; plane < s->bpp; plane++) {
                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
@@ -711,7 +710,7 @@ static int decode_frame(AVCodecContext *avctx,
             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
             int x;
             for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
-                uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
+                uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
                 buf += raw_width;
                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
@@ -722,7 +721,7 @@ static int decode_frame(AVCodecContext *avctx,
         } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
                 for(y = 0; y < avctx->height; y++ ) {
-                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
                     memset(row, 0, avctx->width);
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
@@ -731,7 +730,7 @@ static int decode_frame(AVCodecContext *avctx,
                 }
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
                 for (y = 0; y < avctx->height; y++) {
-                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
                     memset(s->ham_buf, 0, s->planesize * 8);
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
@@ -741,7 +740,7 @@ static int decode_frame(AVCodecContext *avctx,
                 }
             } else { // AV_PIX_FMT_BGR32
                 for(y = 0; y < avctx->height; y++ ) {
-                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
                     memset(row, 0, avctx->width << 2);
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                         decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
@@ -752,13 +751,13 @@ static int decode_frame(AVCodecContext *avctx,
         } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
                 for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
-                    uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
                     buf += avctx->width + (avctx->width % 2); // padding if odd
                 }
             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
-                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
                     buf += avctx->width + (avctx->width & 1); // padding if odd
                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
@@ -771,7 +770,7 @@ static int decode_frame(AVCodecContext *avctx,
         if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
                 for(y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                    uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
                     memset(row, 0, avctx->width);
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
@@ -780,7 +779,7 @@ static int decode_frame(AVCodecContext *avctx,
                 }
             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
                 for (y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
@@ -790,7 +789,7 @@ static int decode_frame(AVCodecContext *avctx,
                 }
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
                 for (y = 0; y < avctx->height ; y++) {
-                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
                     memset(s->ham_buf, 0, s->planesize * 8);
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
@@ -800,7 +799,7 @@ static int decode_frame(AVCodecContext *avctx,
                 }
             } else { //AV_PIX_FMT_BGR32
                 for(y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
                     memset(row, 0, avctx->width << 2);
                     for (plane = 0; plane < s->bpp; plane++) {
                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
@@ -811,12 +810,12 @@ static int decode_frame(AVCodecContext *avctx,
         } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
                 for(y = 0; y < avctx->height ; y++ ) {
-                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
                     buf += decode_byterun(row, avctx->width, buf, buf_end);
                 }
             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
                 for (y = 0; y < avctx->height ; y++) {
-                    uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                    uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
                     buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
                 }
@@ -825,7 +824,7 @@ static int decode_frame(AVCodecContext *avctx,
         } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
             if (av_get_bits_per_pixel(desc) == 32)
-                decode_deep_rle32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0]);
+                decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
             else
                 return unsupported(avctx);
         }
@@ -833,9 +832,9 @@ static int decode_frame(AVCodecContext *avctx,
     case 4:
         bytestream2_init(&gb, buf, buf_size);
         if (avctx->codec_tag == MKTAG('R','G','B','8'))
-            decode_rgb8(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
+            decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
         else if (avctx->codec_tag == MKTAG('R','G','B','N'))
-            decode_rgbn(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
+            decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
         else
             return unsupported(avctx);
         break;
@@ -843,7 +842,7 @@ static int decode_frame(AVCodecContext *avctx,
         if (avctx->codec_tag == MKTAG('D','E','E','P')) {
             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
             if (av_get_bits_per_pixel(desc) == 32)
-                decode_deep_tvdc32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0], s->tvdc);
+                decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
             else
                 return unsupported(avctx);
         } else
@@ -853,16 +852,18 @@ static int decode_frame(AVCodecContext *avctx,
         return unsupported(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_free(&s->frame);
     av_freep(&s->planebuf);
     av_freep(&s->ham_buf);
     av_freep(&s->ham_palbuf);
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 0f434614c6d655890faa2716e6d4d6991f52d543..2d7dd638a88652637513c2b9336ebac99e92f13a 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -948,7 +948,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;
     }
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index ec6ff3c18fc09ba71d1c136fbdad0c23d772aa59..b8925f70f758b5eb4d2e5df6de4045d1b09dd8e4 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -29,6 +29,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "indeo2data.h"
+#include "internal.h"
 #include "mathops.h"
 
 typedef struct Ir2Context{
@@ -148,9 +149,7 @@ static int ir2_decode_frame(AVCodecContext *avctx,
     AVFrame * const p    = &s->picture;
     int start, ret;
 
-    p->reference = 3;
-    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;
     }
@@ -203,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;
@@ -239,8 +240,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;
 }
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index a94b087bedb3928b97a04168454bd9c195c39ee4..fd302a76daea0cef0d174454a1689ac01b947dd0 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -82,7 +82,6 @@ typedef struct Cell {
 
 typedef struct Indeo3DecodeContext {
     AVCodecContext *avctx;
-    AVFrame         frame;
     DSPContext      dsp;
 
     GetBitContext   gb;
@@ -1048,7 +1047,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     ctx->avctx     = avctx;
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
-    avcodec_get_frame_defaults(&ctx->frame);
 
     build_requant_tab();
 
@@ -1064,6 +1062,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);
@@ -1089,11 +1088,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     /* use BS_BUFFER flag for buffer switching */
     ctx->buf_sel = (ctx->frame_flags >> BS_BUFFER) & 1;
 
-    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;
     }
@@ -1110,17 +1105,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         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;
 }
@@ -1128,13 +1122,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;
 }
 
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index 52dddd2ad99a698b7b43c5c03907f3bdf5c8973f..65bd9f211a3b00f8c4ca29de237338cd9edc5508 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -643,8 +643,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     ctx->pic_conf.tile_height   = avctx->height;
     ctx->pic_conf.luma_bands    = ctx->pic_conf.chroma_bands = 1;
 
-    avcodec_get_frame_defaults(&ctx->frame);
-
     result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf);
     if (result) {
         av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n");
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 315b42fa65e0339ebd05c7e4bbc44919356ff606..8d0832b39c74afde04d8efa794d2f7c1f6b553f0 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -26,34 +26,33 @@
 
 #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;
 
     /**
      * temporary buffer used for encoders to store their bitstream
@@ -184,7 +196,13 @@ 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);
 
 int ff_thread_can_start_frame(AVCodecContext *avctx);
 
@@ -192,10 +210,6 @@ int ff_get_logical_cpus(AVCodecContext *avctx);
 
 int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
 
-void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table,
-                         uint8_t *visualization_buffer[3], int *low_delay,
-                         int mb_width, int mb_height, int mb_stride, int quarter_sample);
-
 /**
  * Call avcodec_open2 recursively by decrementing counter, unlocking mutex,
  * calling the function and then restoring again. Assumes the mutex is
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index e0550a702b37e8ebecfbc0f4fee9ba4cd0b21fad..3647c807573e65865b1065de2f5c1ff609e6a92a 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -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, "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(s->avctx, "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(s->avctx, "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(s->avctx, "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(s->avctx, "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, "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(s->avctx, "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, "decode problem on frame %d, @ block (%d, %d)\n",
@@ -942,12 +941,13 @@ static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
 
     ff_dsputil_init(&s->dsp, avctx);
 
-    avcodec_get_frame_defaults(&s->second_last_frame);
-    avcodec_get_frame_defaults(&s->last_frame);
-    avcodec_get_frame_defaults(&s->current_frame);
-
-    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;
 }
@@ -959,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,19 +970,16 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
     if (buf_size < s->decoding_map_size)
         return buf_size;
 
-    if (s->last_frame.data[0] && av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
-        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);
+    if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) {
+        av_frame_unref(s->last_frame);
+        av_frame_unref(s->second_last_frame);
     }
 
     s->decoding_map = buf;
     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, "get_buffer() failed\n");
         return ret;
     }
@@ -989,22 +987,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;
@@ -1014,11 +1010,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;
 }
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index 06496ca659600bd3e86bec0b6863c3ddd4dbf252..67e16ab8dad2f09532a6b15590b6a9687d56549a 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -771,7 +771,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;
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index d43ed399727856626e109b4590893596fe740033..5d604efb45cfd69c3bf99571f3120a038e8ab732 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -353,20 +353,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) {
@@ -378,7 +378,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)
@@ -396,7 +396,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)
@@ -621,7 +621,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);
@@ -654,7 +654,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);
@@ -679,7 +679,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);
@@ -707,8 +707,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
@@ -791,7 +791,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);
@@ -806,11 +806,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);
             }
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index bdcc4159104d0d1c4edd0e10116b3db8804d2bd0..9a03f02448d39ff878e3b13cc4fae52a1eec4cf1 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -271,7 +271,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);
 
@@ -525,8 +525,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);
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index 21954ec5a4357fbc5c90bdc8288e69cad637d347..a3dfc0e57b318ea8dfe904a29592b591359f1a14 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -846,6 +846,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;
 
@@ -903,30 +904,25 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (!ctx->is_nonnull_frame(ctx))
         return buf_size;
 
-    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;
 }
@@ -943,9 +939,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)
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index 86acbe67fcc5661a3d584a5181dfe76d9c9e9dc5..130fd128cc6222ab76b7dac2c92900e4f00af1f2 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -197,7 +197,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;
diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c
index 53c4f079f8c89417ee3474fb16765dddcb376cfa..fef03487d034f3574abf2aa62604936e392e000d 100644
--- a/libavcodec/j2kdec.c
+++ b/libavcodec/j2kdec.c
@@ -49,7 +49,7 @@ typedef struct {
 
 typedef struct {
     AVCodecContext *avctx;
-    AVFrame picture;
+    AVFrame *picture;
     GetByteContext g;
 
     int width, height; ///< image width and height
@@ -281,14 +281,12 @@ static int get_siz(J2kDecoderContext *s)
         break;
     }
 
-    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, s->picture, 0)) < 0)
         return ret;
 
-    s->picture.pict_type = AV_PICTURE_TYPE_I;
-    s->picture.key_frame = 1;
+    s->picture->pict_type = AV_PICTURE_TYPE_I;
+    s->picture->key_frame = 1;
 
     return 0;
 }
@@ -859,7 +857,7 @@ static int decode_tile(J2kDecoderContext *s, J2kTile *tile)
     if (s->precision <= 8) {
         for (compno = 0; compno < s->ncomponents; compno++){
             y = tile->comp[compno].coord[1][0] - s->image_offset_y;
-            line = s->picture.data[0] + y * s->picture.linesize[0];
+            line = s->picture->data[0] + y * s->picture->linesize[0];
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]){
                 uint8_t *dst;
 
@@ -875,13 +873,13 @@ static int decode_tile(J2kDecoderContext *s, J2kTile *tile)
                     *dst = *src[compno]++;
                     dst += s->ncomponents;
                 }
-                line += s->picture.linesize[0];
+                line += s->picture->linesize[0];
             }
         }
     } else {
         for (compno = 0; compno < s->ncomponents; compno++) {
             y = tile->comp[compno].coord[1][0] - s->image_offset_y;
-            line = s->picture.data[0] + y * s->picture.linesize[0];
+            line = s->picture->data[0] + y * s->picture->linesize[0];
             for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
                 uint16_t *dst;
 
@@ -896,7 +894,7 @@ static int decode_tile(J2kDecoderContext *s, J2kTile *tile)
                     *dst = val;
                     dst += s->ncomponents;
                 }
-                line += s->picture.linesize[0];
+                line += s->picture->linesize[0];
             }
         }
     }
@@ -1025,6 +1023,8 @@ static int decode_frame(AVCodecContext *avctx,
     AVFrame *picture = data;
     int tileno, ret;
 
+    s->picture = picture;
+
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
     s->curtileno = -1;
 
@@ -1062,7 +1062,6 @@ static int decode_frame(AVCodecContext *avctx,
     cleanup(s);
 
     *got_frame = 1;
-    *picture = s->picture;
 
     return bytestream2_tell(&s->g);
 
@@ -1076,8 +1075,6 @@ static av_cold int j2kdec_init(AVCodecContext *avctx)
     J2kDecoderContext *s = avctx->priv_data;
 
     s->avctx = avctx;
-    avcodec_get_frame_defaults((AVFrame*)&s->picture);
-    avctx->coded_frame = (AVFrame*)&s->picture;
 
     ff_j2k_init_tier1_luts();
 
@@ -1088,9 +1085,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 {
     J2kDecoderContext *s = avctx->priv_data;
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
     return 0;
 }
 
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index 53d8285788bf7a1ac7c3ffae1c3dd4ba5309e5ac..067845eeba08c7378ad279ba9c1aacf19d87d039 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -28,6 +28,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "libavutil/intreadwrite.h"
 
 typedef struct JvContext {
@@ -135,7 +136,7 @@ static int decode_frame(AVCodecContext *avctx,
     JvContext *s           = avctx->priv_data;
     const uint8_t *buf     = avpkt->data;
     const uint8_t *buf_end = buf + avpkt->size;
-    int video_size, video_type, ret, i, j;
+    int video_size, video_type, i, j, ret;
 
     if (avpkt->size < 6)
         return AVERROR_INVALIDDATA;
@@ -149,7 +150,7 @@ static int decode_frame(AVCodecContext *avctx,
             av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size);
             return AVERROR_INVALIDDATA;
         }
-        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;
         }
@@ -190,8 +191,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 avpkt->size;
@@ -201,8 +203,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;
 }
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index 6b81095af9cd9f2ec4cede9b217f9e4cf0d04130..9c4823988e1ee77b3b903e91f8fc1d8882570978 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -32,20 +32,20 @@
 
 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  = c->cur.data[0];
+    out  = frame->data[0];
     if (c->prev.data[0]) {
         prev = c->prev.data[0];
     } else {
@@ -147,12 +145,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;
 }
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index ffef77138bcd567e75d3f0a56b1ee882cd14abaa..2034ebdbce99a3e3f7219051cbd9aad2a3e5a1f9 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -41,7 +41,6 @@
  */
 typedef struct KmvcContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int setpal;
     int palsize;
@@ -263,6 +262,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;
@@ -270,12 +270,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 = 3;
-    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;
     }
@@ -293,15 +289,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] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
@@ -309,17 +305,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);
 
@@ -344,12 +340,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 */
@@ -362,7 +358,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;
@@ -416,7 +411,6 @@ static av_cold int decode_init(AVCodecContext * avctx)
         c->setpal = 1;
     }
 
-    avcodec_get_frame_defaults(&c->pic);
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     return 0;
@@ -433,8 +427,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;
 }
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index eb8a77e84cd8ee925919e9195ff07bb63d52ff7e..200cbdc715dc138b55177561be25459be7eb7135 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -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 */
@@ -512,7 +511,8 @@ static int lag_decode_frame(AVCodecContext *avctx,
     const uint8_t *buf = avpkt->data;
     unsigned 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];
@@ -520,12 +520,6 @@ static int lag_decode_frame(AVCodecContext *avctx,
     int i, j, planes = 3;
     int ret;
 
-    AVFrame *picture = data;
-
-    if (p->data[0])
-        ff_thread_release_buffer(avctx, p);
-
-    p->reference = 0;
     p->key_frame = 1;
 
     frametype = buf[0];
@@ -545,7 +539,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
                 planes = 4;
             }
 
-        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;
         }
@@ -574,7 +568,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 ((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;
         }
@@ -633,7 +627,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YUY2:
         avctx->pix_fmt = AV_PIX_FMT_YUV422P;
 
-        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;
         }
@@ -659,7 +653,7 @@ static int lag_decode_frame(AVCodecContext *avctx,
     case FRAME_ARITH_YV12:
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-        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;
         }
@@ -691,7 +685,6 @@ static int lag_decode_frame(AVCodecContext *avctx,
         return AVERROR_PATCHWELCOME;
     }
 
-    *picture = *p;
     *got_frame = 1;
 
     return buf_size;
@@ -711,8 +704,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;
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index f8d45da95aa74bdc5538ba4fadaf6efbabc6c5d5..45308ccbbe817e16582b119e904fd4cd8b54eaa0 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -55,8 +55,6 @@
  * Decoder context
  */
 typedef struct LclDecContext {
-    AVFrame pic;
-
     // Image type
     int imgtype;
     // Compression type
@@ -166,6 +164,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;
@@ -182,17 +181,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) {
@@ -386,9 +380,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++) {
@@ -397,9 +391,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:
@@ -412,14 +406,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;
         }
@@ -432,9 +426,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:
@@ -445,26 +439,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:
@@ -473,7 +467,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;
@@ -492,7 +485,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
                                 FFALIGN(avctx->height, 4);
     unsigned int max_decomp_size;
 
-    avcodec_get_frame_defaults(&c->pic);
     if (avctx->extradata_size < 8) {
         av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
         return AVERROR_INVALIDDATA;
@@ -638,8 +630,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);
diff --git a/libavcodec/libcelt_dec.c b/libavcodec/libcelt_dec.c
index a66f9f563498082ffcda1fda25a449331104c04e..496b95a0ed87f5f3751edb8a40af09974b1eb1f3 100644
--- a/libavcodec/libcelt_dec.c
+++ b/libavcodec/libcelt_dec.c
@@ -111,7 +111,7 @@ static int libcelt_dec_decode(AVCodecContext *c, void *data,
     int16_t *pcm;
 
     frame->nb_samples = c->frame_size;
-    err = ff_get_buffer(c, frame);
+    err = ff_get_buffer(c, frame, 0);
     if (err < 0) {
         av_log(c, AV_LOG_ERROR, "get_buffer() failed\n");
         return err;
diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c
index 328c7c7e418e3e0e74bbe66462e0b7079618c3ba..66fe0ae1b1ebf4b3938edb8bd35ec5f9abdd034d 100644
--- a/libavcodec/libgsm.c
+++ b/libavcodec/libgsm.c
@@ -207,7 +207,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;
     }
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
index 98053484b11348473f0f72e7aa69e49c8555ebbf..dd44bebc3e6e05956f81e5f53b34467707a9b408 100644
--- a/libavcodec/libilbc.c
+++ b/libavcodec/libilbc.c
@@ -93,7 +93,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;
     }
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index f52d160502c9e49ef0e22605ca18bf59496b0ba8..5b8e8e66410de7da0e7071d42a09575f902cb14a 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -104,7 +104,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;
     }
@@ -343,7 +343,7 @@ static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 320;
-    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;
     }
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index eeb3dd63f68adbde82601b1d7bd5769a26ef1176..5476e0a70a8b6da54013f31e70870a488f4deeaa 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -67,7 +67,6 @@ static const enum AVPixelFormat libopenjpeg_all_pix_fmts[]  = {RGB_PIXEL_FORMATS
 typedef struct {
     AVClass *class;
     opj_dparameters_t dec_params;
-    AVFrame image;
     int lowqual;
 } LibOpenJPEGContext;
 
@@ -221,16 +220,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;
 }
 
@@ -241,7 +230,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;
@@ -320,10 +310,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;
     }
@@ -385,7 +372,6 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
         goto done;
     }
 
-    *output    = ctx->image;
     *got_frame = 1;
     ret        = buf_size;
 
@@ -395,15 +381,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
 
@@ -425,11 +402,9 @@ 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,
     .max_lowres       = 31,
     .long_name        = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
     .priv_class       = &class,
-    .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy),
 };
diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c
index 686b8a6798a404a8cd7bad6c61b795772d7d590c..71078c4a14f7d6ade28aa462be34a1bc8350cfc6 100644
--- a/libavcodec/libopusdec.c
+++ b/libavcodec/libopusdec.c
@@ -132,7 +132,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;
diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c
index 985ae60835cf7bb33c1dbb3fcafb320dba630714..7720344dbcf60abc1d29e56b29ca26f7e59cc6c3 100644
--- a/libavcodec/libschroedingerdec.c
+++ b/libavcodec/libschroedingerdec.c
@@ -66,9 +66,6 @@ typedef struct SchroDecoderParams {
 
     /** end of sequence pulled */
     int eos_pulled;
-
-    /** decoded picture */
-    AVFrame dec_frame;
 } SchroDecoderParams;
 
 typedef struct SchroParseUnitContext {
@@ -215,6 +212,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;
@@ -308,35 +306,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. */
@@ -357,9 +349,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);
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c
index 1b2db78015e890ffa8e00be1c1d8cb8dd3da131c..1544647691877d14eee7b9e6f15637c133785cd8 100644
--- a/libavcodec/libspeexdec.c
+++ b/libavcodec/libspeexdec.c
@@ -118,7 +118,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;
     }
diff --git a/libavcodec/libvorbisdec.c b/libavcodec/libvorbisdec.c
index 99fb83aac0ba5fac054caeee91b7077b1f9a0f56..e54e4b32d96ec24b0e344633c9430402d7c8abf3 100644
--- a/libavcodec/libvorbisdec.c
+++ b/libavcodec/libvorbisdec.c
@@ -143,7 +143,7 @@ static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data,
     }
 
     frame->nb_samples = 8192*4;
-    if ((ret = ff_get_buffer(avccontext, frame)) < 0) {
+    if ((ret = ff_get_buffer(avccontext, frame, 0)) < 0) {
         av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 7e41e80646b5332fdbc8ad25c4b065d19bcdcd2a..5e80a9f63e638c3a3eaf6d5c6994dbd2fb0edcd3 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -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 */
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index 064b9114b9b1e8c830da43f78749736f3085974c..76c3cb9e43fb3139a6e75620fec7ccf4b43d10c7 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -68,7 +68,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;
 
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index 2b7116685d5df382e8ee35273e1851975b445469..5019e7ad6cb2b293000ffe8f82ebdc3daa4aa348 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -45,7 +45,6 @@ enum LOCO_MODE {
 
 typedef struct LOCOContext {
     AVCodecContext *avctx;
-    AVFrame pic;
     int lossy;
     int mode;
 } LOCOContext;
@@ -176,14 +175,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;
     }
@@ -247,7 +242,6 @@ static int decode_frame(AVCodecContext *avctx,
     buf_size -= decoded;
 
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
 
     return avpkt->size - buf_size;
 buf_too_small:
@@ -305,19 +299,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     if (avctx->debug & FF_DEBUG_PICT_INFO)
         av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode);
 
-    avcodec_get_frame_defaults(&l->pic);
-
-    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;
 }
 
@@ -327,7 +308,6 @@ AVCodec ff_loco_decoder = {
     .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"),
diff --git a/libavcodec/mace.c b/libavcodec/mace.c
index e78c49fbf50588b5b42dd779a5af214ce3e9ea09..4ac1af8d6c3285ab225179c98341682e3a682408 100644
--- a/libavcodec/mace.c
+++ b/libavcodec/mace.c
@@ -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;
     }
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index 7e59c3437c061c7e723d62fd2c972be1b35f93fb..561c2edd5da16f3e666dee5e3f70b845289cddc6 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -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,13 +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;
 
-    avcodec_get_frame_defaults(&a->picture);
-    avctx->coded_frame = &a->picture;
     a->avctx           = avctx;
 
     ff_dsputil_init(&a->dsp, avctx);
@@ -230,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;
@@ -240,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;
 }
 
@@ -254,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;
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index 54d27e8af3837665eec86e1b3c0b07cc4ec10979..90e39690aef3abc04b1619aacf25eae4ff275f80 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -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 = 3;
-    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),
 };
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index 52842332c24e8eb532ade510348dea32d5dac997..4327c10d9446d0d1f52d0a909df691785cc9f485 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -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;
@@ -141,17 +141,13 @@ read_header:
         return buf_size;
     }
 
-    *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;
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index f3080d9aa0e3530c58886279cd3af155abd8555d..2f751944da7efafc8112eed606ac44c2070acb9d 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -303,7 +303,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
     if (   width != s->width || height != s->height
         || memcmp(s->h_count, h_count, sizeof(h_count))
         || memcmp(s->v_count, v_count, sizeof(v_count))) {
-        av_freep(&s->qscale_table);
 
         s->width      = width;
         s->height     = height;
@@ -325,7 +324,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;
     }
 
@@ -443,10 +441,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;
     }
@@ -1640,7 +1636,6 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     int start_code;
     int i, index;
     int ret = 0;
-    AVFrame *picture = data;
 
     buf_ptr = buf;
     buf_end = buf + buf_size;
@@ -1741,22 +1736,17 @@ eoi_parser:
                     if (s->bottom_field == !s->interlace_polarity)
                         break;
                 }
-                *picture   = *s->picture_ptr;
+                if ((ret = av_frame_ref(data, s->picture_ptr)) < 0)
+                    return ret;
                 *got_frame = 1;
                 s->got_picture = 0;
 
-                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;
@@ -1864,11 +1854,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;
 
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index c763624f1c3aca1f64473877b8212697a993e569..5473318451eed61636359c5e0be761eecc3d9f14 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -1023,7 +1023,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;
     }
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index c61cd576e499b70082d9e4c3b6e0b6adc32c0947..3b780eec50da27e6e498c8ed9b2d7530ae47d06d 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -34,6 +34,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define MM_PREAMBLE_SIZE    6
 
@@ -61,8 +62,6 @@ static av_cold int mm_decode_init(AVCodecContext *avctx)
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     avcodec_get_frame_defaults(&s->frame);
-    s->frame.reference = 3;
-
     return 0;
 }
 
@@ -188,7 +187,7 @@ static int mm_decode_frame(AVCodecContext *avctx,
     buf_size -= MM_PREAMBLE_SIZE;
     bytestream2_init(&s->gb, buf, buf_size);
 
-    if ((res = 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 res;
     }
@@ -210,8 +209,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 avpkt->size;
 }
@@ -220,8 +221,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;
 }
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 352321393fb2a416bb0e424d72dc0261f41fbfe3..faccfbb25e66923638d8d828d529fd2737c7b813 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -495,16 +495,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;
     }
 }
 
@@ -586,8 +586,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)
             c->ymax = - 16*s->mb_y + s->height - 8*(block>>1);
         }
 
-        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);
 
@@ -596,10 +596,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);
@@ -656,8 +656,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;
     }
@@ -913,16 +913,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);
@@ -1054,9 +1054,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);
@@ -1422,7 +1422,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;
@@ -1432,8 +1432,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);
@@ -1522,7 +1522,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;
@@ -1693,14 +1693,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;
                         }
                     }
                 }
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index 4fa45e9c5db0abaf25abfd09eb684fbae05e0284..1d5624500b1663e5bd5a30635b816263532b40a6 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -22,6 +22,7 @@
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
+#include "internal.h"
 
 #define MAX_HUFF_CODES 16
 
@@ -264,9 +265,7 @@ static int mp_decode_frame(AVCodecContext *avctx,
     GetBitContext gb;
     int i, count1, count2, sz, ret;
 
-    mp->frame.reference = 3;
-    mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if ((ret = avctx->reget_buffer(avctx, &mp->frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, &mp->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -314,8 +313,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;
 }
 
@@ -327,8 +327,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;
 }
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index d4f5e2d4163b98c748f83afe2ffcf0e0dae75d6e..26969b1c5e6c9a40550874a8bd1d040820574339 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -225,7 +225,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = 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;
     }
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index 489737a8c99cf4083459ad76870dcbdf8af89e13..c7cf7fb462c3dca6b63dab375c5bac40cf72d7eb 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -254,7 +254,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;
     }
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 1e11ea798d9f31952de86c86485c6f16f302c410..bf23e07a7ab17e76b176e88cd77222656d6bfaf1 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -763,21 +763,22 @@ 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)) {
                 av_log(s->avctx, AV_LOG_ERROR, "skip with previntra\n");
                 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;
-//            av_assert2(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;
@@ -1126,7 +1127,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;
 }
@@ -1607,6 +1608,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;
 
@@ -1625,7 +1628,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);
@@ -1770,7 +1778,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);
@@ -1788,12 +1796,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];
                     av_assert2(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1);
                 }
                 xy += wrap;
@@ -1973,23 +1981,25 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
     if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field && !s->first_slice) {
         /* 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);
             }
         }
 
@@ -2290,8 +2300,10 @@ static int decode_chunks(AVCodecContext *avctx,
                 if (CONFIG_VDPAU && uses_vdpau(avctx))
                     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;
                 }
@@ -2560,7 +2572,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;
diff --git a/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c
index 7444f26a9df997f22fcbef8f1bbb51f8c43266d2..9b86997a56bffd749b514de326e1635f7637615e 100644
--- a/libavcodec/mpeg4video.c
+++ b/libavcodec/mpeg4video.c
@@ -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){
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 09bd0dcce27bd6ce67431e9c6d547e412f7c570c..be4aa375898c8a9c42958823690446563647e6de 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -24,6 +24,7 @@
 
 #include "libavutil/opt.h"
 #include "error_resilience.h"
+#include "internal.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
 #include "h263.h"
@@ -59,7 +60,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;
@@ -574,13 +575,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++){
@@ -596,7 +597,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:
@@ -608,11 +609,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       ]=
@@ -638,7 +639,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;
@@ -664,11 +665,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       ] =
@@ -677,7 +678,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);
@@ -729,9 +730,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);
@@ -744,7 +745,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;
@@ -758,10 +759,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);
@@ -774,7 +775,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;
@@ -1095,20 +1096,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);
 
@@ -1126,7 +1127,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
 
@@ -1139,7 +1140,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)) {
@@ -1192,14 +1193,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;
@@ -1234,7 +1235,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);
@@ -1242,7 +1243,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;
 
@@ -1264,7 +1265,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);
@@ -1281,7 +1282,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);
@@ -1314,11 +1315,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 */
@@ -1331,7 +1332,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;
         }
 
@@ -1437,7 +1438,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);
@@ -1452,9 +1453,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){
@@ -1501,9 +1502,9 @@ end:
 
             if(s->pict_type==AV_PICTURE_TYPE_B){
                 const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
-                ff_thread_await_progress(&s->next_picture_ptr->f,
+                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->next_picture.f.mbskip_table[xy + delta])
+                if (s->next_picture.mbskip_table[xy + delta])
                     return SLICE_OK;
             }
 
@@ -2303,6 +2304,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;
 }
 
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index a07f956af01161db32f30eedb414bd609b5e86da..566273554e3c819c1cc316ae65744d834304cecc 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -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,
             av_assert2(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]=
@@ -641,7 +641,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;
 
                         if(x+16 > s->width || y+16 > s->height){
@@ -759,8 +759,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);
                 }
             }
 
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index 0266afeb74a22d04c5e39b61fb5ec304b7c9c1c8..763244d9c8afe2285a1d011ed5b9dcf12c064366 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -1628,7 +1628,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;
         }
@@ -1935,7 +1935,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;
     }
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 938579824fc94000124aa24a452047ebc155ec33..0628f58c06dc3f8645613182cf0f97abfdf870e1 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -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"
@@ -232,29 +233,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)
-{
-    pic->period_since_free = 0;
-    /* 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) + 64, 32);
@@ -298,16 +276,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 +300,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 +315,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 +424,139 @@ 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)
-        }
-
-        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 (!pic->qscale_table_buf)
+        ret = alloc_picture_tables(s, pic);
+    else
+        ret = make_tables_writable(pic);
+    if (ret < 0)
+        goto 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->period_since_free = 0;
 
-    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;
+    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);
+
+    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,8 +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 err;
+    int i, ret;
     MpegEncContext *s = dst->priv_data, *s1 = src->priv_data;
 
     if (dst == src)
@@ -602,12 +695,12 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
         s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0;
 
         if (s1->context_initialized){
-            s->picture_range_start  += MAX_PICTURE_COUNT;
-            s->picture_range_end    += MAX_PICTURE_COUNT;
-            if((err = ff_MPV_common_init(s)) < 0){
+//             s->picture_range_start  += MAX_PICTURE_COUNT;
+//             s->picture_range_end    += MAX_PICTURE_COUNT;
+            if((ret = ff_MPV_common_init(s)) < 0){
                 memset(s, 0, sizeof(MpegEncContext));
                 s->avctx = dst;
-                return err;
+                return ret;
             }
         }
     }
@@ -616,8 +709,8 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
         s->context_reinit = 0;
         s->height = s1->height;
         s->width  = s1->width;
-        if ((err = ff_MPV_common_frame_size_change(s)) < 0)
-            return err;
+        if ((ret = ff_MPV_common_frame_size_change(s)) < 0)
+            return ret;
     }
 
     s->avctx->coded_height  = s1->avctx->coded_height;
@@ -630,16 +723,29 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
     s->input_picture_number = s1->input_picture_number;
 
     av_assert0(!s->picture || s->picture != s1->picture);
-    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;
         s->picture[i].period_since_free ++;
     }
 
+#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);
     s->next_picture_ptr    = REBASE_PICTURE(s1->next_picture_ptr,    s, s1);
@@ -728,9 +834,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;
 }
 
@@ -978,12 +1081,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 (init_context_frame(s))
             goto fail;
@@ -1096,10 +1204,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;
         }
 
@@ -1189,18 +1298,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         =
@@ -1305,12 +1420,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]);
         }
     }
 }
@@ -1323,9 +1436,8 @@ static inline int pic_is_unused(MpegEncContext *s, Picture *pic)
         return 0;
     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;
 }
 
@@ -1334,16 +1446,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;
         }
@@ -1370,10 +1478,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);
         }
     }
@@ -1407,7 +1516,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;
 
@@ -1421,22 +1530,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]);
                 }
             }
         }
@@ -1459,12 +1566,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++;
@@ -1491,9 +1598,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;
@@ -1546,10 +1656,8 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
                 for(i=0; i<avctx->height; i++)
                     memset(s->last_picture_ptr->f.data[0] + s->last_picture_ptr->f.linesize[0]*i, 16, avctx->width);
             }
-
-            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) &&
@@ -1566,29 +1674,35 @@ 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 0 // BUFREF-FIXME
     memset(s->last_picture.f.data, 0, sizeof(s->last_picture.f.data));
     memset(s->next_picture.f.data, 0, sizeof(s->next_picture.f.data));
-    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);
+#endif
+    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++) {
@@ -1642,7 +1756,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) &&
               !s->avctx->lowres
@@ -1684,11 +1798,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
@@ -1699,9 +1811,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);
 }
 
 /**
@@ -1795,13 +1906,15 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex,
 /**
  * Print debugging info for the given picture.
  */
-void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_table,
+void ff_print_debug_info2(AVCodecContext *avctx, Picture *p, uint8_t *mbskip_table,
                          uint8_t *visualization_buffer[3], int *low_delay,
                          int mb_width, int mb_height, int mb_stride, int quarter_sample)
 {
-    if (   avctx->hwaccel || !pict || !pict->mb_type
+    AVFrame *pict;
+    if (avctx->hwaccel || !p || !p->mb_type
         || (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU))
         return;
+    pict = &p->f;
 
 
     if (avctx->debug & (FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)) {
@@ -1819,10 +1932,10 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
                 }
                 if (avctx->debug & FF_DEBUG_QP) {
                     av_log(avctx, AV_LOG_DEBUG, "%2d",
-                           pict->qscale_table[x + y * mb_stride]);
+                           p->qscale_table[x + y * mb_stride]);
                 }
                 if (avctx->debug & FF_DEBUG_MB_TYPE) {
-                    int mb_type = pict->mb_type[x + y * mb_stride];
+                    int mb_type = p->mb_type[x + y * mb_stride];
                     // Type & MV direction
                     if (IS_PCM(mb_type))
                         av_log(avctx, AV_LOG_DEBUG, "P");
@@ -1897,8 +2010,7 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
             memcpy(visualization_buffer[i], pict->data[i], size);
             pict->data[i] = visualization_buffer[i];
         }
-        pict->type   = FF_BUFFER_TYPE_COPY;
-        pict->opaque= NULL;
+        pict->opaque = NULL;
         ptr          = pict->data[0];
         block_height = 16 >> v_chroma_shift;
 
@@ -1906,7 +2018,7 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
             int mb_x;
             for (mb_x = 0; mb_x < mb_width; mb_x++) {
                 const int mb_index = mb_x + mb_y * mb_stride;
-                if ((avctx->debug_mv) && pict->motion_val[0]) {
+                if ((avctx->debug_mv) && p->motion_val[0]) {
                     int type;
                     for (type = 0; type < 3; type++) {
                         int direction = 0;
@@ -1930,46 +2042,46 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
                             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, pict->linesize[0], 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, pict->linesize[0], 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,
@@ -1979,14 +2091,14 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
                               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, pict->linesize[0], 100);
                         }
                     }
                 }
                 if ((avctx->debug & FF_DEBUG_VIS_QP)) {
-                    uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) *
+                    uint64_t c = (p->qscale_table[mb_index] * 128 / 31) *
                                  0x0101010101010101ULL;
                     int y;
                     for (y = 0; y < block_height; y++) {
@@ -1999,8 +2111,8 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
                     }
                 }
                 if ((avctx->debug & FF_DEBUG_VIS_MB_TYPE) &&
-                    pict->motion_val[0]) {
-                    int mb_type = pict->mb_type[mb_index];
+                    p->motion_val[0]) {
+                    int mb_type = p->mb_type[mb_index];
                     uint64_t u,v;
                     int y;
 #define COLOR(theta, r) \
@@ -2064,7 +2176,7 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
                             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++)
@@ -2086,10 +2198,10 @@ void ff_print_debug_info2(AVCodecContext *avctx, AVFrame *pict, uint8_t *mbskip_
     }
 }
 
-void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
+void ff_print_debug_info(MpegEncContext *s, Picture *p)
 {
-    ff_print_debug_info2(s->avctx, pict, s->mbskip_table, s->visualization_buffer, &s->low_delay,
-                             s->mb_width, s->mb_height, s->mb_stride, s->quarter_sample);
+    ff_print_debug_info2(s->avctx, p, s->mbskip_table, s->visualization_buffer, &s->low_delay,
+                         s->mb_width, s->mb_height, s->mb_stride, s->quarter_sample);
 }
 
 static inline int hpel_motion_lowres(MpegEncContext *s,
@@ -2586,20 +2698,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) {
@@ -2634,7 +2744,7 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
                 s->mb_skipped= 0;
                 av_assert2(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 */
@@ -2661,12 +2771,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);
                     }
@@ -2850,7 +2960,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;
@@ -2986,12 +3096,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;
@@ -3234,7 +3340,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
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index b6226e2c2d74dd5b32e1ca13dc58b3abf0f880d8..8e044d99c09c87ac41197526793a2de650c44561 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -38,6 +38,7 @@
 #include "parser.h"
 #include "mpeg12data.h"
 #include "rl.h"
+#include "thread.h"
 #include "videodsp.h"
 
 #include "libavutil/opt.h"
@@ -95,10 +96,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)
@@ -139,17 +168,13 @@ 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)
     int period_since_free;      ///< "cycles" since this Picture has been freed
-    /**
-     * hardware accelerator private data
-     */
-    void *hwaccel_picture_private;
+
+    int reference;
+    int shared;
 } Picture;
 
 /**
@@ -318,8 +343,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;
@@ -719,7 +742,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 */
@@ -784,7 +807,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);
@@ -805,7 +828,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,
@@ -932,4 +954,12 @@ 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);
+
+void ff_print_debug_info2(AVCodecContext *avctx, Picture *pict, uint8_t *mbskip_table,
+                         uint8_t *visualization_buffer[3], int *low_delay,
+                         int mb_width, int mb_height, int mb_stride, int quarter_sample);
+
+
 #endif /* AVCODEC_MPEGVIDEO_H */
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 1906a53b7d199ad05818efaa633f6f98c0dff853..b7839715be1993e53b9b76d59ea5531a0442fc4c 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -174,7 +174,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++) {
@@ -970,9 +970,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;
@@ -1011,7 +1011,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;
@@ -1028,14 +1028,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 {
@@ -1043,16 +1041,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;
@@ -1068,7 +1066,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->codec_id == AV_CODEC_ID_AMV && !(s->avctx->flags & CODEC_FLAG_EMU_EDGE)) {
                         h = ((s->height + 15)/16*16) >> v_shift;
@@ -1098,9 +1096,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 */
@@ -1123,7 +1121,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);
@@ -1219,7 +1217,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;
@@ -1290,7 +1288,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];
@@ -1311,17 +1309,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);
@@ -1425,14 +1413,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
 
@@ -1442,41 +1431,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;
 }
@@ -1827,7 +1809,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) {
@@ -2726,8 +2708,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);
@@ -2914,7 +2896,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);
 
@@ -2981,8 +2963,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:
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index 565f6cb286693a593eeaa5e61f6036c2d1837fbb..8b77e73847deba7d52d320785dad4b80c86ad593 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -641,7 +641,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;
diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c
index f30124cf44b115d56272901bc0d0b0959cb8f7e9..6b0c6acbd9097fb89460251adf49960b3e43a842 100644
--- a/libavcodec/mpegvideo_xvmc.c
+++ b/libavcodec/mpegvideo_xvmc.c
@@ -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];
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 278c5fcfdc1a7a70c95fbf461b14dfa1837e64cf..395dffc05b53b2a02b5030a82f4a3ce6ec7c65d1 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -407,7 +407,7 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
 static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
 {
     int cbp, code, i;
-    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) {
@@ -498,7 +498,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) {
diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c
index 7187d1a5e1927544f15ee276fad002142cb478d5..3b82b82ff472c7901329e7a8ee3d975c0da1a458 100644
--- a/libavcodec/msrle.c
+++ b/libavcodec/msrle.c
@@ -33,6 +33,7 @@
 #include <string.h>
 
 #include "avcodec.h"
+#include "internal.h"
 #include "msrledec.h"
 
 typedef struct MsrleContext {
@@ -92,9 +93,7 @@ static int msrle_decode_frame(AVCodecContext *avctx,
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 3;
-    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;
     }
@@ -136,8 +135,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;
@@ -148,8 +149,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;
 }
diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c
index 446339b0942212bbe75032176c69437561bb2ae1..b6cd42555c802304b1d7cd4108ac74e7f6fc1321 100644
--- a/libavcodec/mss1.c
+++ b/libavcodec/mss1.c
@@ -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;
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index 71bd0b858bba31f3e5bf32bf786deb2d6c73cdae..7f10f9fe42b56bce51c23cc5fc17212c27715e3e 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -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;
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
index d5bb2d4e356573feae1d4f69a519f1c36deefda2..089b722e4896f3aec6e3e184e33d241b08df02ef 100644
--- a/libavcodec/mss3.c
+++ b/libavcodec/mss3.c
@@ -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);
 
diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c
index 977e1e55525723b22ab52ff5d080cad8d3afb604..526c4c052293d76c15bc21a0385eba0180dbcc2d 100644
--- a/libavcodec/mss4.c
+++ b/libavcodec/mss4.c
@@ -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);
diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c
index fd98b3132709d5c9d442286de7011f531e1b575c..e45ee72f410f725b47e8594616d4baab95adecf8 100644
--- a/libavcodec/msvideo1.c
+++ b/libavcodec/msvideo1.c
@@ -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) \
@@ -293,15 +294,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 = 3;
-    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) {
@@ -318,8 +318,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;
@@ -329,8 +331,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;
 }
diff --git a/libavcodec/mvcdec.c b/libavcodec/mvcdec.c
index 5131ae2ebaf24ea16b4bef9b0d374c36c6e239f1..7848d32efd94f91ff75611dcaee16b7e8ea67e18 100644
--- a/libavcodec/mvcdec.c
+++ b/libavcodec/mvcdec.c
@@ -27,8 +27,10 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct MvcContext {
+    AVFrame *frame;
     int vflip;
 } MvcContext;
 
@@ -48,8 +50,8 @@ static av_cold int mvc_decode_init(AVCodecContext *avctx)
         avcodec_set_dimensions(avctx, width, height);
 
     avctx->pix_fmt = (avctx->codec_id == AV_CODEC_ID_MVC1) ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_BGRA;
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
+    s->frame = av_frame_alloc();
+    if (!s->frame)
         return AVERROR(ENOMEM);
 
     s->vflip = avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9);
@@ -228,10 +230,7 @@ static int mvc_decode_frame(AVCodecContext *avctx,
     GetByteContext gb;
     int ret;
 
-    avctx->coded_frame->reference = 3;
-    avctx->coded_frame->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                            FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    ret = avctx->reget_buffer(avctx, avctx->coded_frame);
+    ret = ff_reget_buffer(avctx, s->frame);
     if (ret < 0) {
         av_log (avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return AVERROR(ENOMEM);
@@ -239,22 +238,25 @@ static int mvc_decode_frame(AVCodecContext *avctx,
 
     bytestream2_init(&gb, avpkt->data, avpkt->size);
     if (avctx->codec_id == AV_CODEC_ID_MVC1)
-        ret = decode_mvc1(avctx, &gb, avctx->coded_frame->data[0], avctx->width, avctx->height, avctx->coded_frame->linesize[0]);
+        ret = decode_mvc1(avctx, &gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
     else
-        ret = decode_mvc2(avctx, &gb, avctx->coded_frame->data[0], avctx->width, avctx->height, avctx->coded_frame->linesize[0], s->vflip);
+        ret = decode_mvc2(avctx, &gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0], s->vflip);
     if (ret < 0)
         return ret;
 
-    *got_frame      = 1;
-    *(AVFrame*)data = *avctx->coded_frame;
+    *got_frame = 1;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
+
     return avpkt->size;
 }
 
 static av_cold int mvc_decode_end(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-    av_freep(&avctx->coded_frame);
+    MvcContext *s = avctx->priv_data;
+
+    av_frame_free(&s->frame);
+
     return 0;
 }
 
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index 59d41b6abe1dd1194df9d9f0b79a6b01708682d3..5b72d42447b4ffd0b154a9844e9f7cd9d6249657 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -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);
 }
@@ -168,7 +167,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;
@@ -249,9 +247,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);
                     }
@@ -270,7 +268,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);
                     }
@@ -294,8 +293,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];
 
@@ -319,10 +321,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);
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index 4b4b61c4721a3f802e5ebfa7e9312c7479b4c41d..2e1cb978a47b7315fe7de169ddf51f8ace6ee404 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -171,7 +171,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;
     }
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index dffe339ca3d02a7f826af948e5be433a9c456e87..48348ea6b278bedec4200501cbbc714d18852d52 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -28,6 +28,7 @@
 #include "libavutil/lzo.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "rtjpeg.h"
 
 typedef struct {
@@ -240,14 +241,12 @@ retry:
         buf_size -= RTJPEG_HEADER_SIZE;
     }
 
-    if ((size_change || keyframe) && c->pic.data[0]) {
-        avctx->release_buffer(avctx, &c->pic);
+    if (size_change || 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;
@@ -290,7 +289,9 @@ retry:
         return AVERROR_INVALIDDATA;
     }
 
-    *picture   = c->pic;
+    if ((result = av_frame_ref(picture, &c->pic)) < 0)
+        return result;
+
     *got_frame = 1;
     return orig_size;
 }
@@ -325,8 +326,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;
 }
diff --git a/libavcodec/options.c b/libavcodec/options.c
index a922365a17b09a66b2ecd8bf03abbc556e051f83..1d10128481ffb14d48417564f9cff9c7e1141e8a 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -111,8 +111,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
     av_opt_set_defaults2(s, flags, flags);
 
     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;
@@ -121,7 +120,6 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
     s->sample_fmt          = AV_SAMPLE_FMT_NONE;
     s->timecode_frame_start = -1;
 
-    s->reget_buffer        = avcodec_default_reget_buffer;
     s->reordered_opaque    = AV_NOPTS_VALUE;
     if(codec && codec->priv_data_size){
         if(!s->priv_data){
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index d0c55a2a440d16dda092035ab5944834c306dc68..23032377fc6851fa5d9fe243558d1e9f42ae492e 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -411,6 +411,7 @@ static const AVOption options[]={
 {"do_nothing",  NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_DO_NOTHING},  INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
 {"auto",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC},   INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
 {"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"},
+{"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|D },
 {NULL},
 };
 
diff --git a/libavcodec/paf.c b/libavcodec/paf.c
index 78a5d97b2029a05a00857cbaaed731188161c6fd..5ff09b9816a68c049be5e5614920f5910846433b 100644
--- a/libavcodec/paf.c
+++ b/libavcodec/paf.c
@@ -251,8 +251,7 @@ static int paf_vid_decode(AVCodecContext *avctx, void *data,
     uint8_t code, *dst, *src, *end;
     int i, frame, ret;
 
-    c->pic.reference = 3;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0)
+    if ((ret =ff_reget_buffer(avctx, &c->pic)) < 0)
         return ret;
 
     bytestream2_init(&c->gb, pkt->data, pkt->size);
@@ -356,9 +355,10 @@ static int paf_vid_decode(AVCodecContext *avctx, void *data,
     }
 
     c->current_frame = (c->current_frame + 1) & 3;
+    if ((ret = av_frame_ref(data, &c->pic)) < 0)
+        return ret;
 
     *got_frame       = 1;
-    *(AVFrame *)data = c->pic;
 
     return pkt->size;
 }
@@ -368,8 +368,7 @@ static av_cold int paf_vid_close(AVCodecContext *avctx)
     PAFVideoDecContext *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 < 4; i++)
         av_freep(&c->frame[i]);
@@ -404,7 +403,7 @@ static int paf_aud_decode(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
 
     frame->nb_samples = PAF_SOUND_SAMPLES * frames;
-    if ((ret = ff_get_buffer(avctx, frame)) < 0)
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
 
     output_samples = (int16_t *)frame->data[0];
diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c
index 08aad95fba6dba3c03020fe637169b4853143b84..6743b1c6e64a854982564f5442d448b5ae4be16f 100644
--- a/libavcodec/pcm-mpeg.c
+++ b/libavcodec/pcm-mpeg.c
@@ -153,7 +153,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;
     }
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index 4a8a4f78f9d2a4289b7e1e258fbd9e9a1f945dbb..2cc14c1a4c6352bab4abc97aa3f1a92a2fc311fc 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -356,7 +356,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;
     }
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index e7f9c240f6a01fe4a3adf27d08945ea0237e9409..9e94e4bf3ee46b1b0326b4c4bcc44c79e7e91d23 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -28,20 +28,6 @@
 #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;
-}
-
 static void pcx_rle_decode(GetByteContext *gb, uint8_t *dst,
                            unsigned int bytes_per_scanline, int compressed)
 {
@@ -76,12 +62,9 @@ static void pcx_palette(GetByteContext *gb, uint32_t *dst, int pallen)
 }
 
 static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
-                            AVPacket *avpkt)
-{
-    PCXContext * const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame * const p = &s->picture;
+                            AVPacket *avpkt) {
     GetByteContext gb;
+    AVFrame * const p = data;
     int compressed, xmin, ymin, xmax, ymax, ret;
     unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x,
                  bytes_per_scanline;
@@ -144,14 +127,11 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     bytestream2_skipu(&gb, 60);
 
-    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;
     }
@@ -239,7 +219,6 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         pcx_palette(&gb, (uint32_t *) p->data[1], 16);
     }
 
-    *picture = s->picture;
     *got_frame = 1;
 
 end:
@@ -247,23 +226,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"),
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index 69d23828b33b395b94a8701c8d07f55ad36130a6..8d7c009a7dea4fb658f421c46ea6893adcd78745 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -31,16 +31,16 @@
 #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) {
@@ -97,22 +97,15 @@ static const uint8_t cga_mode45_index[6][4] = {
     [5] = { 0, 11, 12, 15 }, // mode5, high intensity
 };
 
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    PicContext *s = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&s->frame);
-    return 0;
-}
-
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame,
                         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, val;
+    int i, x, y, plane, tmp, ret, val;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
 
@@ -151,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;
@@ -236,9 +227,9 @@ 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);
                 } else {
-                    picmemset(s, val, run, &x, &y, &plane, bits_per_plane);
+                    picmemset(s, frame, val, run, &x, &y, &plane, bits_per_plane);
                 }
             }
         }
@@ -246,38 +237,27 @@ static int decode_frame(AVCodecContext *avctx,
         if (x < avctx->width && y >= 0) {
             int run = (y + 1) * avctx->width - x;
             if (bits_per_plane == 8)
-                picmemset_8bpp(s, val, run, &x, &y);
+                picmemset_8bpp(s, frame, val, run, &x, &y);
             else
-                picmemset(s, val, run / (8 / bits_per_plane), &x, &y, &plane, bits_per_plane);
+                picmemset(s, frame, val, run / (8 / bits_per_plane), &x, &y, &plane, bits_per_plane);
         }
     } else {
         while (y >= 0 && bytestream2_get_bytes_left(&s->g) > 0) {
-            memcpy(s->frame.data[0] + y * s->frame.linesize[0], s->g.buffer, FFMIN(avctx->width, bytestream2_get_bytes_left(&s->g)));
+            memcpy(frame->data[0] + y * frame->linesize[0], s->g.buffer, FFMIN(avctx->width, bytestream2_get_bytes_left(&s->g)));
             bytestream2_skip(&s->g, avctx->width);
             y--;
         }
     }
 
     *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),
-    .init           = decode_init,
-    .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"),
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index 36db29e53e7b0270bac97c5d679739440812f7fe..564baaf831552afb16c1c1095ba8a7605086d3e0 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -42,8 +42,7 @@ typedef struct PNGDecContext {
     AVCodecContext *avctx;
 
     GetByteContext gb;
-    AVFrame picture1, picture2;
-    AVFrame *current_picture, *last_picture;
+    AVFrame *prev;
 
     int state;
     int width, height;
@@ -508,18 +507,13 @@ 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;
     AVDictionary *metadata  = NULL;
     uint8_t *crow_buf_base  = NULL;
-    AVFrame *p;
     uint32_t tag, length;
     int64_t sig;
     int ret;
 
-    FFSWAP(AVFrame *, s->current_picture, s->last_picture);
-    avctx->coded_frame = s->current_picture;
-    p = s->current_picture;
-
     bytestream2_init(&s->gb, buf, buf_size);
 
     /* check signature */
@@ -642,11 +636,8 @@ static int decode_frame(AVCodecContext *avctx,
                                                  s->bit_depth, s->color_type);
                     goto fail;
                 }
-                if (p->data[0])
-                    avctx->release_buffer(avctx, p);
 
-                p->reference = 3;
-                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;
                 }
@@ -762,7 +753,7 @@ static int decode_frame(AVCodecContext *avctx,
 
     if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
         int i, j, k;
-        uint8_t *pd = s->current_picture->data[0];
+        uint8_t *pd = p->data[0];
         for (j = 0; j < s->height; j++) {
             i = s->width / 8;
             for (k = 7; k >= 1; k--)
@@ -783,7 +774,7 @@ static int decode_frame(AVCodecContext *avctx,
     }
     if (s->bits_per_pixel == 2){
         int i, j;
-        uint8_t *pd = s->current_picture->data[0];
+        uint8_t *pd = p->data[0];
         for (j = 0; j < s->height; j++) {
             i = s->width / 4;
             if (s->color_type == PNG_COLOR_TYPE_PALETTE){
@@ -812,7 +803,7 @@ static int decode_frame(AVCodecContext *avctx,
     }
     if (s->bits_per_pixel == 4){
         int i, j;
-        uint8_t *pd = s->current_picture->data[0];
+        uint8_t *pd = p->data[0];
         for (j = 0; j < s->height; j++) {
             i = s->width/2;
             if (s->color_type == PNG_COLOR_TYPE_PALETTE){
@@ -833,15 +824,15 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
      /* 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)
-            && s->last_picture->width == s->current_picture->width
-            && s->last_picture->height== s->current_picture->height
-            && s->last_picture->format== s->current_picture->format
+            && s->prev->width == p->width
+            && s->prev->height== p->height
+            && s->prev->format== p->format
          ) {
             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++) {
@@ -853,9 +844,13 @@ static int decode_frame(AVCodecContext *avctx,
         }
     }
 
-    av_frame_set_metadata(&s->current_picture, metadata);
+    av_frame_set_metadata(p, metadata);
     metadata   = NULL;
-    *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);
@@ -876,10 +871,9 @@ 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);
 
@@ -892,10 +886,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;
 }
diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c
index 6d1eb6d0edc3891d3bcfa57ae39dab67682b67c7..33b8896555e907517a38bfd4d08020c9ded52608 100644
--- a/libavcodec/pnm.c
+++ b/libavcodec/pnm.c
@@ -193,16 +193,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;
diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h
index bb2cc77b873fa2c7e33251cfeec636a1b90fd0ff..92edf8dfefcd20f7da2486f8d3c3ef285f792745 100644
--- a/libavcodec/pnm.h
+++ b/libavcodec/pnm.h
@@ -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 */
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index 3280eef6720557e3e676525c0d024f6587bacd55..a34acf812de938f4b000a6b56bb4e5e836eab44d 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -31,8 +31,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, is_mono = 0;
     unsigned char *ptr;
     int components, sample_len, ret;
@@ -44,11 +43,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;
     }
@@ -230,7 +225,6 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
         }
         break;
     }
-    *picture   = s->picture;
     *got_frame = 1;
 
     return s->bytestream - s->bytestream_start;
@@ -243,8 +237,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"),
@@ -257,8 +249,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"),
@@ -271,8 +261,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"),
@@ -285,8 +273,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"),
@@ -299,8 +285,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"),
diff --git a/libavcodec/proresdec.h b/libavcodec/proresdec.h
index 1c56227cbfd36dc6dbe94f6db9617a8abf8e1b8b..5a1481c0d701a12a6526a0312b06f43b48a7bf92 100644
--- a/libavcodec/proresdec.h
+++ b/libavcodec/proresdec.h
@@ -37,7 +37,7 @@ typedef struct {
 typedef struct {
     DSPContext dsp;
     ProresDSPContext prodsp;
-    AVFrame frame;
+    AVFrame *frame;
     int frame_type;              ///< 0 = progressive, 1 = tff, 2 = bff
     uint8_t qmat_luma[64];
     uint8_t qmat_chroma[64];
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index 4634e704e2df020bcedb75262a9d63808a920a2b..b7aef36d238b330fd1b3763c15872b08ec339062 100644
--- a/libavcodec/proresdec2.c
+++ b/libavcodec/proresdec2.c
@@ -73,10 +73,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
     ff_dsputil_init(&ctx->dsp, avctx);
     ff_proresdsp_init(&ctx->prodsp, avctx);
 
-    avctx->coded_frame = &ctx->frame;
-    ctx->frame.type = AV_PICTURE_TYPE_I;
-    ctx->frame.key_frame = 1;
-
     ff_init_scantable_permutation(idct_permutation,
                                   ctx->prodsp.idct_permutation_type);
 
@@ -123,8 +119,8 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
         ctx->scan = ctx->progressive_scan; // permuted
     } else {
         ctx->scan = ctx->interlaced_scan; // permuted
-        ctx->frame.interlaced_frame = 1;
-        ctx->frame.top_field_first = ctx->frame_type == 1;
+        ctx->frame->interlaced_frame = 1;
+        ctx->frame->top_field_first = ctx->frame_type == 1;
     }
 
     avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10;
@@ -431,7 +427,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
     ProresContext *ctx = avctx->priv_data;
     SliceContext *slice = &ctx->slices[jobnr];
     const uint8_t *buf = slice->data;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = ctx->frame;
     int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
     int luma_stride, chroma_stride;
     int y_data_size, u_data_size, v_data_size;
@@ -486,7 +482,7 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int
     dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
     dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
 
-    if (ctx->frame_type && ctx->first_field ^ ctx->frame.top_field_first) {
+    if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) {
         dest_y += pic->linesize[0];
         dest_u += pic->linesize[1];
         dest_v += pic->linesize[2];
@@ -526,7 +522,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                         AVPacket *avpkt)
 {
     ProresContext *ctx = avctx->priv_data;
-    AVFrame *frame = avctx->coded_frame;
+    AVFrame *frame = data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     int frame_hdr_size, pic_size;
@@ -536,6 +532,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return -1;
     }
 
+    ctx->frame = frame;
     ctx->first_field = 1;
 
     buf += 8;
@@ -548,10 +545,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     buf += frame_hdr_size;
     buf_size -= frame_hdr_size;
 
-    if (frame->data[0])
-        avctx->release_buffer(avctx, frame);
-
-    if (ff_get_buffer(avctx, frame) < 0)
+    if (ff_get_buffer(avctx, frame, 0) < 0)
         return -1;
 
  decode_picture:
@@ -575,7 +569,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     *got_frame      = 1;
-    *(AVFrame*)data = *frame;
 
     return avpkt->size;
 }
@@ -584,9 +577,6 @@ static av_cold int decode_close(AVCodecContext *avctx)
 {
     ProresContext *ctx = avctx->priv_data;
 
-    AVFrame *frame = avctx->coded_frame;
-    if (frame->data[0])
-        avctx->release_buffer(avctx, frame);
     av_freep(&ctx->slices);
 
     return 0;
diff --git a/libavcodec/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c
index 5c53882ce39448f209ed998bac12ffb9f1efc4fe..10551666424b0d2fabaee982bb4df4fd5f64c0c0 100644
--- a/libavcodec/proresdec_lgpl.c
+++ b/libavcodec/proresdec_lgpl.c
@@ -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);
 
-    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;
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index c582bfc64c77f9ee544c08b974161fcd35beac6e..5903e0991e698b954d438a7b665504c848aa6f1f 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -55,6 +55,7 @@
 #include "avcodec.h"
 #include "internal.h"
 #include "thread.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 
 #if HAVE_PTHREADS
@@ -86,9 +87,6 @@ typedef struct ThreadContext {
     int done;
 } ThreadContext;
 
-/// Max number of frame buffers that can be allocated when using frame threads.
-#define MAX_BUFFERS (34+1)
-
 /**
  * Context used by codec threads and stored in their AVCodecContext thread_opaque.
  */
@@ -128,16 +126,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().
-     */
-    volatile int     progress[MAX_BUFFERS][2];
-    volatile 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;
 
 /**
@@ -397,11 +391,13 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
         if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
 
         pthread_mutex_lock(&p->progress_mutex);
+#if 0 //BUFREF-FIXME
         for (i = 0; i < MAX_BUFFERS; i++)
             if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) {
                 p->progress[i][0] = INT_MAX;
                 p->progress[i][1] = INT_MAX;
             }
+#endif
         p->state = STATE_INPUT_READY;
 
         pthread_cond_broadcast(&p->progress_cond);
@@ -477,8 +473,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;
@@ -511,14 +510,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;
-    volatile 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)
 {
@@ -528,11 +519,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);
     }
 }
@@ -586,15 +579,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);
             }
@@ -656,7 +652,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;
 
@@ -681,10 +677,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;
-    volatile int *progress = f->thread_opaque;
+    volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
 
     if (!progress || progress[field] >= n) return;
 
@@ -699,10 +695,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;
-    volatile int *progress = f->thread_opaque;
+    volatile int *progress = f->progress ? (int*)f->progress->data : NULL;
 
     if (!progress || progress[field] >= n) return;
 
@@ -789,8 +785,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);
@@ -798,6 +792,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);
@@ -934,23 +929,6 @@ void ff_thread_flush(AVCodecContext *avctx)
     }
 }
 
-static volatile 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_can_start_frame(AVCodecContext *avctx)
 {
     PerThreadContext *p = avctx->thread_opaque;
@@ -962,20 +940,17 @@ int ff_thread_can_start_frame(AVCodecContext *avctx)
     return 1;
 }
 
-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 err;
-    volatile int *progress;
 
     f->owner = avctx;
 
-    ff_init_buffer_info(avctx, f);
+    ff_init_buffer_info(avctx, f->f);
 
-    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 &&
@@ -984,23 +959,29 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
         return -1;
     }
 
-    pthread_mutex_lock(&p->parent->buffer_mutex);
-    f->thread_opaque = (int*)(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;
+    pthread_mutex_lock(&p->parent->buffer_mutex);
 
-    if (avctx->thread_safe_callbacks ||
-        avctx->get_buffer == avcodec_default_get_buffer) {
-        err = ff_get_buffer(avctx, f);
+    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 {
         pthread_mutex_lock(&p->progress_mutex);
-        p->requested_frame = f;
+        p->requested_frame = f->f;
+        p->requested_flags = flags;
         p->state = STATE_GET_BUFFER;
         pthread_cond_broadcast(&p->progress_cond);
 
@@ -1015,41 +996,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));
 }
 
 /**
diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c
index 1a76c55c89420ef57bc0eb655bccd56bf1aeb3f6..93bb57d40d070ff8780a5a5e46c804e61215d9e4 100644
--- a/libavcodec/ptx.c
+++ b/libavcodec/ptx.c
@@ -25,26 +25,11 @@
 #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;
     }
@@ -93,7 +75,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) {
@@ -104,22 +85,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"),
diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c
index 76b51f841cdf75705fcf6e25e26ee6fcef68fbf0..3f482a91bff385fd1772a5b4c1ed142357a629c6 100644
--- a/libavcodec/qcelpdec.c
+++ b/libavcodec/qcelpdec.c
@@ -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;
     }
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 7136cf1c233c0e900c6045a97cdee320a0dc11d8..6e313b41fc4329b1d20af60e3ca4205113ba1aed 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -1985,7 +1985,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;
     }
diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c
index 4ad64aadae8812acb9d48968593c1179ef40fba4..96962dd2e6071f75c9dca408cae5254c18dbd98b 100644
--- a/libavcodec/qdrw.c
+++ b/libavcodec/qdrw.c
@@ -29,11 +29,6 @@
 #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,43 +127,26 @@ 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;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
-    QdrawContext * const a = avctx->priv_data;
-
-    avcodec_get_frame_defaults(&a->pic);
     avctx->pix_fmt= AV_PIX_FMT_PAL8;
 
     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"),
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index 73d652e5d8b3210e05fed7cba53ee0ca6597445c..b4f5433c9b68a18624be49d81e16e42c65386fb8 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -268,12 +268,10 @@ static int decode_frame(AVCodecContext *avctx,
 
     bytestream2_init(&a->buffer, avpkt->data, avpkt->size);
 
-    if(ref->data[0])
-        avctx->release_buffer(avctx, ref);
-    FFSWAP(AVFrame, *ref, *p);
+    av_frame_unref(ref);
+    av_frame_move_ref(ref, p);
 
-    p->reference= 3;
-    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;
     }
@@ -296,8 +294,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;
 }
@@ -332,10 +332,8 @@ static av_cold int decode_end(AVCodecContext *avctx){
     AVFrame * const p = &a->pic;
     AVFrame * const ref= &a->ref;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
-    if(ref->data[0])
-        avctx->release_buffer(avctx, ref);
+    av_frame_unref(p);
+    av_frame_unref(ref);
 
     return 0;
 }
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index 1b92885b321db7b5edfdfd48911acaf28963ac38..4a5437ffe07c681a4ded27899cb37dc451df1e85 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -37,6 +37,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 typedef struct QtrleContext {
     AVCodecContext *avctx;
@@ -412,10 +413,7 @@ static int qtrle_decode_frame(AVCodecContext *avctx,
     int ret;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
-    s->frame.reference = 3;
-    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;
     }
@@ -501,8 +499,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;
@@ -512,8 +511,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;
 }
diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c
index b58f11f9be4d2c49caf662add4212d5a52794aaa..198914c749960e8920274ca8ab5648eeeb9170bf 100644
--- a/libavcodec/r210dec.c
+++ b/libavcodec/r210dec.c
@@ -30,10 +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();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
     return 0;
 }
 
@@ -41,22 +37,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 uint32_t *src = (const uint32_t *)avpkt->data;
     int aligned_width = FFALIGN(avctx->width,
                                 avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 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;
@@ -91,28 +83,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"),
@@ -124,7 +104,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"),
@@ -136,7 +115,6 @@ AVCodec ff_avrp_decoder = {
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_AVRP,
     .init           = decode_init,
-    .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c
index f12954b2f77acac7a20cfa92eb76d4980152c189..9cc054cac4b7ce8fe3d67cc6265929e206a2ba4e 100644
--- a/libavcodec/ra144dec.c
+++ b/libavcodec/ra144dec.c
@@ -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;
     }
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index dac8aa60325fbd5865eb350399f3d8830e69591e..57602f105084402ed12e5ce87f64c59819f88cb3 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -198,7 +198,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;
     }
diff --git a/libavcodec/ralf.c b/libavcodec/ralf.c
index b163a895abc99dcdbbf402a290ba208c4fe5bf00..91c984f083a725d7731c69921af7240d366a6561 100644
--- a/libavcodec/ralf.c
+++ b/libavcodec/ralf.c
@@ -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;
     }
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index efd802066c5a3a6b2d6f9dbf2424c40f20affa59..00730dc6f739a0ecc213f97407c63af8e46e50ae 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -236,10 +236,6 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
     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->frame_size) ||
-        (desc->flags & PIX_FMT_PSEUDOPAL)) {
-        frame->data[1] = (uint8_t*)context->palette;
-    }
 
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
@@ -254,6 +250,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
             frame->palette_has_changed = 1;
         }
     }
+
     if ((avctx->pix_fmt==AV_PIX_FMT_BGR24    ||
         avctx->pix_fmt==AV_PIX_FMT_GRAY8    ||
         avctx->pix_fmt==AV_PIX_FMT_RGB555LE ||
@@ -280,6 +277,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
             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;
diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c
index b908a83f488929f50a312931e16ad7c36bcb5d03..5a8064b72bcc2cd376245a4af11bb51b25c935d3 100644
--- a/libavcodec/rl2.c
+++ b/libavcodec/rl2.c
@@ -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)
@@ -138,7 +137,6 @@ static av_cold int rl2_decode_init(AVCodecContext *avctx)
 
     s->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
-    avcodec_get_frame_defaults(&s->frame);
 
     /** parse extra data */
     if (!avctx->extradata || avctx->extradata_size < EXTRADATA1_SIZE) {
@@ -178,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;
@@ -216,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;
diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c
index 6812f9af7061887de2f938890c97513625c5ba85..2309b0b8575574c924ec449b1a7af0dd87b71cc4 100644
--- a/libavcodec/roqvideodec.c
+++ b/libavcodec/roqvideodec.c
@@ -28,6 +28,7 @@
 #include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 #include "roqvideo.h"
 
 static void roqvideo_decode_frame(RoqContext *ri)
@@ -179,10 +180,15 @@ static av_cold int roq_decode_init(AVCodecContext *avctx)
 
     s->width = avctx->width;
     s->height = avctx->height;
-    avcodec_get_frame_defaults(&s->frames[0]);
-    avcodec_get_frame_defaults(&s->frames[1]);
-    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;
@@ -198,8 +204,7 @@ static int roq_decode_frame(AVCodecContext *avctx,
     int copy= !s->current_frame->data[0];
     int ret;
 
-    s->current_frame->reference = 3;
-    if ((ret = avctx->reget_buffer(avctx, s->current_frame)) < 0) {
+    if ((ret = ff_reget_buffer(avctx, s->current_frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
@@ -211,8 +216,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);
@@ -224,11 +230,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;
 }
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index 02f1a452ae8879c7c77863060fbb841c3066ad5e..187b848bac4e275acb95e7912b7c5b09b2fc0ea9 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -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));
 
@@ -1031,8 +1051,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;
         }
@@ -1054,22 +1074,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,
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index a5da96720fa9359204d0df7061136b45ce5048d3..c73e40e5379cdff78176cec6966593bc1952fbc5 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -41,6 +41,7 @@
 #include "libavutil/internal.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 
 typedef struct RpzaContext {
 
@@ -256,17 +257,17 @@ static int rpza_decode_frame(AVCodecContext *avctx,
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 3;
-    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;
@@ -276,8 +277,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;
 }
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index e51adc030739b7488ae877074cb125790966a20a..e2ccee7aecdebee7c601ee2a2a2db7d8b9a0643c 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -680,7 +680,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;
@@ -739,14 +739,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...)
     }
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index 7f8f8cbc7f4c1c089033f969543a3bc8e69522e8..a99980e5f15bba0f6470a96c979bd18e1dc508a2 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -146,7 +146,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))
@@ -158,9 +158,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){
@@ -200,9 +200,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){
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index 31e5d033326f69431cff688843b125bbb2ad6457..629564a8ea351f69d2e030aac2359a72f7a22ab6 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -358,7 +358,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]));
@@ -368,7 +368,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;
@@ -394,7 +394,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)
@@ -402,7 +402,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]));
@@ -411,7 +411,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]));
@@ -476,27 +476,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]);
@@ -504,8 +504,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;
         }
     }
 }
@@ -556,25 +556,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;
     }
 
@@ -585,12 +585,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);
     }
 }
 
@@ -607,27 +607,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]);
@@ -636,8 +636,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;
             }
         }
     }
@@ -675,24 +675,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;
@@ -705,7 +705,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);
     }
 
@@ -854,11 +854,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;
         }
@@ -866,23 +866,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:
@@ -1150,7 +1150,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))
@@ -1193,26 +1193,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;
@@ -1295,21 +1295,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;
@@ -1449,7 +1449,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);
 
         }
@@ -1508,6 +1508,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;
 }
 
@@ -1525,6 +1527,7 @@ int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
         if ((err = rv34_decoder_alloc(r)) < 0)
             return err;
     }
+
     return 0;
 }
 
@@ -1568,24 +1571,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;
 }
@@ -1610,7 +1615,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;
@@ -1619,7 +1624,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;
@@ -1782,7 +1788,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");
@@ -1791,7 +1800,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;
         }
     }
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index fe3608e3a2798d16357d9dbb11b63fa4aa23062e..d6dfc5e4b78c9ae35ebfbc8b17c6f163fd4ddb80 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -366,7 +366,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))
@@ -381,7 +381,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;
@@ -396,7 +396,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;
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index d641c2ec6af0ad4016dda4c5b5263ac1b916440e..e61bbe796372845301d65ebf955d596a7d6724e0 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -106,7 +106,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;
     }
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index caeaa366a650ae334fe0eefaf420658417c05fee..826873088a87379db25878a885b31638d3b7b160 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -46,7 +46,7 @@ typedef struct {
     int aligned_width, aligned_height;
     int prev_seq;
 
-    AVFrame frame, *output;
+    AVFrame *frame;
     uint16_t *frm0, *frm1, *frm2;
     uint8_t *stored_frame;
     uint32_t frm0_size, frm1_size, frm2_size;
@@ -274,8 +274,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "error allocating buffers\n");
         return AVERROR(ENOMEM);
     }
-    ctx->output          = &ctx->frame;
-    ctx->output->data[0] = 0;
 
     make_glyphs(ctx->p4x4glyphs[0], glyph4_x, glyph4_y, 4);
     make_glyphs(ctx->p8x8glyphs[0], glyph8_x, glyph8_y, 8);
@@ -302,11 +300,6 @@ static av_cold int decode_end(AVCodecContext *avctx)
 
     destroy_buffers(ctx);
 
-    if (ctx->frame.data[0]) {
-        avctx->release_buffer(avctx, &ctx->frame);
-        ctx->frame.data[0] = 0;
-    }
-
     return 0;
 }
 
@@ -1151,13 +1144,13 @@ static int copy_output(SANMVideoContext *ctx, SANMFrameHeader *hdr)
     int ret, dstpitch, height = ctx->height;
     int srcpitch = ctx->pitch * (hdr ? sizeof(ctx->frm0[0]) : 1);
 
-    if ((ret = ff_get_buffer(ctx->avctx, ctx->output)) < 0) {
+    if ((ret = ff_get_buffer(ctx->avctx, ctx->frame, 0)) < 0) {
         av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    dst      = ctx->output->data[0];
-    dstpitch = ctx->output->linesize[0];
+    dst      = ctx->frame->data[0];
+    dstpitch = ctx->frame->linesize[0];
 
     while (height--) {
         memcpy(dst, src, srcpitch);
@@ -1174,9 +1167,8 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     SANMVideoContext *ctx = avctx->priv_data;
     int i, ret;
 
+    ctx->frame = data;
     bytestream2_init(&ctx->gb, pkt->data, pkt->size);
-    if (ctx->output->data[0])
-        avctx->release_buffer(avctx, ctx->output);
 
     if (!ctx->version) {
         int to_store = 0;
@@ -1258,7 +1250,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
             memcpy(ctx->stored_frame, ctx->frm0, ctx->buf_size);
         if ((ret = copy_output(ctx, NULL)))
             return ret;
-        memcpy(ctx->output->data[1], ctx->pal, 1024);
+        memcpy(ctx->frame->data[1], ctx->pal, 1024);
     } else {
         SANMFrameHeader header;
 
@@ -1266,12 +1258,12 @@ static int decode_frame(AVCodecContext *avctx, void *data,
             return ret;
 
         ctx->rotate_code = header.rotate_code;
-        if ((ctx->output->key_frame = !header.seq_num)) {
-            ctx->output->pict_type = AV_PICTURE_TYPE_I;
+        if ((ctx->frame->key_frame = !header.seq_num)) {
+            ctx->frame->pict_type = AV_PICTURE_TYPE_I;
             fill_frame(ctx->frm1, ctx->npixels, header.bg_color);
             fill_frame(ctx->frm2, ctx->npixels, header.bg_color);
         } else {
-            ctx->output->pict_type = AV_PICTURE_TYPE_P;
+            ctx->frame->pict_type = AV_PICTURE_TYPE_P;
         }
 
         if (header.codec < FF_ARRAY_ELEMS(v1_decoders)) {
@@ -1293,7 +1285,6 @@ static int decode_frame(AVCodecContext *avctx, void *data,
         rotate_bufs(ctx, ctx->rotate_code);
 
     *got_frame_ptr  = 1;
-    *(AVFrame*)data = *ctx->output;
 
     return pkt->size;
 }
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index 51bd5d6f8d0d189b80d7de937f6a1af3f962186e..4b98daf4f49ce74ebee45c9031221861ff8c1d13 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -27,7 +27,6 @@
 #include "sgi.h"
 
 typedef struct SgiState {
-    AVFrame picture;
     unsigned int width;
     unsigned int height;
     unsigned int depth;
@@ -156,8 +155,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;
@@ -207,11 +205,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;
     }
@@ -233,7 +227,6 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     if (ret == 0) {
-        *picture   = s->picture;
         *got_frame = 1;
         return avpkt->size;
     } else {
@@ -241,32 +234,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,
diff --git a/libavcodec/sgirledec.c b/libavcodec/sgirledec.c
index 0ce6afda822ccc3a971af202f3ad3053996f50e1..59f8e3150c61d0dfa55eb2767f70e73a7e4ef27a 100644
--- a/libavcodec/sgirledec.c
+++ b/libavcodec/sgirledec.c
@@ -27,12 +27,18 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
+
+typedef struct SGIRLEContext {
+    AVFrame *frame;
+} SGIRLEContext;
 
 static av_cold int sgirle_decode_init(AVCodecContext *avctx)
 {
+    SGIRLEContext *s = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_BGR8;
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
+    s->frame = av_frame_alloc();
+    if (!s->frame)
         return AVERROR(ENOMEM);
     return 0;
 }
@@ -106,33 +112,32 @@ static int sgirle_decode_frame(AVCodecContext *avctx,
                             void *data, int *got_frame,
                             AVPacket *avpkt)
 {
-    AVFrame *frame = avctx->coded_frame;
+    SGIRLEContext *s = avctx->priv_data;
     int ret;
 
-    frame->reference = 3;
-    frame->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
-    ret = avctx->reget_buffer(avctx, frame);
+    ret = ff_reget_buffer(avctx, s->frame);
     if (ret < 0) {
         av_log (avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
 
-    ret = decode_sgirle8(avctx, frame->data[0], avpkt->data, avpkt->size, avctx->width, avctx->height, frame->linesize[0]);
+    ret = decode_sgirle8(avctx, s->frame->data[0], avpkt->data, avpkt->size, avctx->width, avctx->height, s->frame->linesize[0]);
     if (ret < 0)
         return ret;
 
     *got_frame      = 1;
-    *(AVFrame*)data = *frame;
+    if ((ret = av_frame_ref(data, s->frame)) < 0)
+        return ret;
 
     return avpkt->size;
 }
 
 static av_cold int sgirle_decode_end(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-    av_freep(&avctx->coded_frame);
+    SGIRLEContext *s = avctx->priv_data;
+
+    av_frame_free(&s->frame);
+
     return 0;
 }
 
@@ -140,6 +145,7 @@ AVCodec ff_sgirle_decoder = {
     .name           = "sgirle",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_SGIRLE,
+    .priv_data_size = sizeof(SGIRLEContext),
     .init           = sgirle_decode_init,
     .close          = sgirle_decode_end,
     .decode         = sgirle_decode_frame,
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index 3a6d6340122a7313d365cc2dfe73f3710e4b8868..c84a57cdd6e78ec895fe1ad8228f887640c798b0 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -596,7 +596,7 @@ static int shorten_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;
                 }
diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c
index dc169361934e6dade9deb8e8e8dd8854692579b5..41c119795c1d7bcf066bea9e203fb31fd1b05fb8 100644
--- a/libavcodec/sipr.c
+++ b/libavcodec/sipr.c
@@ -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;
     }
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index ad1d4c3171698acb9ca3a5889d152f78424cbde4..1b4898beb8fbf8a95bcb0325e2bfc03ab9790803 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -381,9 +381,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     if (avpkt->size <= 769)
         return AVERROR_INVALIDDATA;
 
-    smk->pic.reference = 3;
-    smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if((ret = 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 ret;
     }
@@ -513,8 +511,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;
@@ -565,8 +565,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;
 }
@@ -636,7 +635,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;
     }
diff --git a/libavcodec/smc.c b/libavcodec/smc.c
index 6294f0969194c52dae6524e9ff4823709dbd2e68..e0b0f6be566082089577503f638f93998634bfcb 100644
--- a/libavcodec/smc.c
+++ b/libavcodec/smc.c
@@ -35,6 +35,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #define CPAIR 2
 #define CQUAD 4
@@ -430,15 +431,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 = 3;
-    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) {
@@ -449,7 +448,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;
@@ -459,8 +459,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;
 }
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index b2c6714a40e6289d5a55b56e46954c9344e2a5c1..126acf3cb548a432e35f4b6a2d615037ff447700 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -471,7 +471,7 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) {
     int ret, emu_buf_size;
 
     if(!s->scratchbuf) {
-        if ((ret = ff_get_buffer(s->avctx, &s->mconly_picture)) < 0) {
+        if ((ret = ff_get_buffer(s->avctx, &s->mconly_picture, AV_GET_BUFFER_FLAG_REF)) < 0) {
             av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return ret;
         }
@@ -586,7 +586,7 @@ void ff_snow_release_buffer(AVCodecContext *avctx)
     int i;
 
     if(s->last_picture[s->max_ref_frames-1].data[0]){
-        avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]);
+        av_frame_unref(&s->last_picture[s->max_ref_frames-1]);
         for(i=0; i<9; i++)
             if(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3])
                 av_free(s->halfpel_plane[s->max_ref_frames-1][1+i/3][i%3] - EDGE_WIDTH*(1+s->current_picture.linesize[i%3]));
@@ -595,6 +595,7 @@ void ff_snow_release_buffer(AVCodecContext *avctx)
 
 int ff_snow_frame_start(SnowContext *s){
    AVFrame tmp;
+   int i;
    int w= s->avctx->width; //FIXME round up to x16 ?
    int h= s->avctx->height;
 
@@ -612,13 +613,14 @@ int ff_snow_frame_start(SnowContext *s){
 
     ff_snow_release_buffer(s->avctx);
 
-    tmp= s->last_picture[s->max_ref_frames-1];
-    memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame));
+    av_frame_move_ref(&tmp, &s->last_picture[s->max_ref_frames-1]);
+    for(i=s->max_ref_frames-1; i>0; i--)
+        av_frame_move_ref(&s->last_picture[i+1], &s->last_picture[i]);
     memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
     if(USE_HALFPEL_PLANE && s->current_picture.data[0])
         halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);
-    s->last_picture[0]= s->current_picture;
-    s->current_picture= tmp;
+    av_frame_move_ref(&s->last_picture[0], &s->current_picture);
+    av_frame_move_ref(&s->current_picture, &tmp);
 
     if(s->keyframe){
         s->ref_frames= 0;
@@ -634,8 +636,7 @@ int ff_snow_frame_start(SnowContext *s){
         }
     }
 
-    s->current_picture.reference= 3;
-    if(ff_get_buffer(s->avctx, &s->current_picture) < 0){
+    if(ff_get_buffer(s->avctx, &s->current_picture, AV_GET_BUFFER_FLAG_REF) < 0){
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -670,7 +671,7 @@ av_cold void ff_snow_common_end(SnowContext *s)
         av_freep(&s->ref_scores[i]);
         if(s->last_picture[i].data[0]) {
             av_assert0(s->last_picture[i].data[0] != s->current_picture.data[0]);
-            s->avctx->release_buffer(s->avctx, &s->last_picture[i]);
+            av_frame_unref(&s->last_picture[i]);
         }
     }
 
@@ -683,8 +684,6 @@ av_cold void ff_snow_common_end(SnowContext *s)
             }
         }
     }
-    if (s->mconly_picture.data[0])
-        s->avctx->release_buffer(s->avctx, &s->mconly_picture);
-    if (s->current_picture.data[0])
-        s->avctx->release_buffer(s->avctx, &s->current_picture);
+    av_frame_unref(&s->mconly_picture);
+    av_frame_unref(&s->current_picture);
 }
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index 1bfd0969c885251895ff09b3779328a065385f60..c8a03277e643c2cdb0711c250b5694680304fac3 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -551,9 +551,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     ff_snow_release_buffer(avctx);
 
     if(!(s->avctx->debug&2048))
-        *picture= s->current_picture;
+        av_frame_ref(picture, &s->current_picture);
     else
-        *picture= s->mconly_picture;
+        av_frame_ref(picture, &s->mconly_picture);
 
     *got_frame = 1;
 
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index c0c847a9fb1e67ff431d2ecee33e92080ca69fea..624278bd655ca86ee7f4c57080506d06db7f3eea 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -239,7 +239,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
     ff_set_cmp(&s->dsp, s->dsp.me_cmp, s->avctx->me_cmp);
     ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, s->avctx->me_sub_cmp);
 
-    if ((ret = ff_get_buffer(s->avctx, &s->input_picture)) < 0)
+    if ((ret = ff_get_buffer(s->avctx, &s->input_picture, AV_GET_BUFFER_FLAG_REF)) < 0)
         return ret;
 
     if(s->avctx->me_method == ME_ITER){
@@ -1948,8 +1948,7 @@ static av_cold int encode_end(AVCodecContext *avctx)
     SnowContext *s = avctx->priv_data;
 
     ff_snow_common_end(s);
-    if (s->input_picture.data[0])
-        avctx->release_buffer(avctx, &s->input_picture);
+    av_frame_unref(&s->input_picture);
     av_free(avctx->stats_out);
 
     return 0;
diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c
index ae54388ff6132b8b5dc93f40e11ab21ab3db8337..7f11ca74d696f68878569774a00fced94c12671e 100644
--- a/libavcodec/sonic.c
+++ b/libavcodec/sonic.c
@@ -877,7 +877,7 @@ static int sonic_decode_frame(AVCodecContext *avctx,
     if (buf_size == 0) return 0;
 
     s->frame.nb_samples = s->frame_size;
-    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
+    if ((ret = ff_get_buffer(avctx, &s->frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c
index bfdf2b7e2a903428f56820c464a9e20fa0336c6d..533ff62367d328230fca3e8f01c2fcf8b44fa3bc 100644
--- a/libavcodec/sunrast.c
+++ b/libavcodec/sunrast.c
@@ -26,27 +26,12 @@
 #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, *ptr2 = NULL;
     const uint8_t *bufstart = buf;
@@ -115,12 +100,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;
     }
@@ -222,28 +204,15 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
         av_freep(&ptr_free);
     }
 
-    *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"),
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 5b9a620591a8d0b89e348b0fc61c01d01e9302ff..ec961e733a1bcf9c2adbca6427052e6dd89a6e79 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -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;
@@ -610,14 +610,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;
 
@@ -692,7 +689,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         } else {
             /* delta frame */
             uint8_t *previous = s->prev->data[i];
-            if (!previous || s->prev->width != s->cur->width || s->prev->height != s->cur->height) {
+            if (!previous || s->prev->width != cur->width || s->prev->height != cur->height) {
                 av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
                 result = AVERROR_INVALIDDATA;
                 goto err;
@@ -722,10 +719,12 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *(AVFrame*)data = *cur;
-    cur->qscale_table = NULL;
-    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;
@@ -741,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;
@@ -798,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;
@@ -812,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 = {
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index d12dfcdb01fc492d030e3e35751ad03fa387a055..cfa06f3655a418affeee5d118ed5c93bfd63a531 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -323,9 +323,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
@@ -546,8 +546,8 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     }
 
     if (!s->current_picture.data[0]) {
-        if ((ret = ff_get_buffer(avctx, &s->current_picture))< 0 ||
-            (ret = ff_get_buffer(avctx, &s->last_picture))   < 0) {
+        if ((ret = ff_get_buffer(avctx, &s->current_picture, 0))< 0 ||
+            (ret = ff_get_buffer(avctx, &s->last_picture, 0))   < 0) {
             return ret;
         }
         s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2);
@@ -610,10 +610,9 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx)
         av_freep(&s->motion_val8[i]);
         av_freep(&s->motion_val16[i]);
     }
-    if(s->current_picture.data[0])
-        avctx->release_buffer(avctx, &s->current_picture);
-    if(s->last_picture.data[0])
-        avctx->release_buffer(avctx, &s->last_picture);
+
+    av_frame_unref(&s->current_picture);
+    av_frame_unref(&s->last_picture);
 
     return 0;
 }
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index 0481c807aba4917bc2f1667ff179ae8b02ecbf2d..4f5548fd8f6bd2cd73dffd0d8b8169746bdb4f47 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -376,8 +376,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 /
@@ -458,7 +458,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);
         }
@@ -482,7 +482,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);
 
@@ -492,7 +492,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)
@@ -522,21 +522,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;
@@ -544,7 +544,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
@@ -567,7 +567,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) {
@@ -575,7 +575,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));
             }
         }
@@ -657,11 +657,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));
         }
     }
@@ -747,7 +747,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);
@@ -1021,6 +1021,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;
@@ -1031,27 +1043,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)
@@ -1061,6 +1080,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;
 }
 
@@ -1077,7 +1099,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;
         }
@@ -1107,8 +1131,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;
@@ -1119,7 +1142,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);
@@ -1240,7 +1267,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;
         }
 
@@ -1262,9 +1289,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)
@@ -1272,25 +1301,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;
@@ -1299,6 +1316,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);
 
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
index ae751fed1672e9663f1cab1206bb0027fcbac227..43382f10349c813cf0d68235469334143bed9145 100644
--- a/libavcodec/takdec.c
+++ b/libavcodec/takdec.c
@@ -749,7 +749,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_raw_sample <= 16) {
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index 2d1d3dfb13c740c18970a2ba14523cf6bf29d2de..9601a27a0b33afb85e21372b79d00a790e025539 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -27,7 +27,6 @@
 #include "targa.h"
 
 typedef struct TargaContext {
-    AVFrame picture;
     GetByteContext gb;
 } TargaContext;
 
@@ -112,8 +111,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, pal, compr, y, w, h, bpp, flags, ret;
@@ -170,9 +168,6 @@ static int decode_frame(AVCodecContext *avctx,
         return AVERROR_INVALIDDATA;
     }
 
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
-
     if (colors && (colors + first_clr) > 256) {
         av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr);
         return AVERROR_INVALIDDATA;
@@ -182,7 +177,7 @@ static int decode_frame(AVCodecContext *avctx,
         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;
     }
@@ -298,39 +293,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"),
diff --git a/libavcodec/targa_y216dec.c b/libavcodec/targa_y216dec.c
index 3b97000c534b0b8e306448a642e89e33a929232e..67d19a118117f7bf54c30f43c23c501feadca3c5 100644
--- a/libavcodec/targa_y216dec.c
+++ b/libavcodec/targa_y216dec.c
@@ -27,35 +27,23 @@ static av_cold int y216_decode_init(AVCodecContext *avctx)
     avctx->pix_fmt             = AV_PIX_FMT_YUV422P16;
     avctx->bits_per_raw_sample = 14;
 
-    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 y216_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint16_t *src = (uint16_t *)avpkt->data;
     uint16_t *y, *u, *v, aligned_width = FFALIGN(avctx->width, 4);
     int i, j;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < 4 * avctx->height * aligned_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);
     }
@@ -82,17 +70,12 @@ static int y216_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
 
 static av_cold int y216_decode_close(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
 
     return 0;
 }
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index e83803073f8df7f1acc313484c4ce0ad0863c36b..24e62b4967d24b504b4c0e4e78e31a1924f0b111 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -27,9 +27,19 @@
 #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);
diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c
index 3ae7c88174f362f07236fa12cf13ad66683e51bb..5b93dc219dcd1031fb810bcdb8d0a7eccfcd0bf7 100644
--- a/libavcodec/tiertexseqv.c
+++ b/libavcodec/tiertexseqv.c
@@ -27,6 +27,7 @@
 #include "avcodec.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 
 typedef struct SeqVideoContext {
@@ -228,21 +229,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 = 3;
-    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, "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;
 }
@@ -251,8 +252,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;
 }
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 43d12db14a392bc55d12b3b5a34859345b408aa4..b749a6be257048abe298adb153a68f6c77815918 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -43,8 +43,8 @@
 
 typedef struct TiffContext {
     AVCodecContext *avctx;
-    AVFrame picture;
     GetByteContext gb;
+    AVFrame picture;
 
     int width, height;
     unsigned int bpp, bppcount;
@@ -597,7 +597,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;
@@ -642,18 +642,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 < 1<<s->bpp; i++)
                 pal[i] = 0xFFU << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
         }
@@ -1041,8 +1039,7 @@ static int decode_frame(AVCodecContext *avctx,
                         void *data, int *got_frame, AVPacket *avpkt)
 {
     TiffContext *const s = avctx->priv_data;
-    AVFrame *picture = data;
-    AVFrame *const p = &s->picture;
+    AVFrame *const p = data;
     unsigned off;
     int id, le, ret;
     int i, j, entries;
@@ -1075,7 +1072,7 @@ static int decode_frame(AVCodecContext *avctx,
     free_geotags(s);
     /* metadata has been destroyed from lavc internals, that pointer is not
      * valid anymore */
-    av_frame_set_metadata(&s->picture, NULL);
+    av_frame_set_metadata(p, NULL);
 
     // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
     // that further identifies the file as a TIFF file"
@@ -1123,7 +1120,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) {
@@ -1197,14 +1194,13 @@ static int decode_frame(AVCodecContext *avctx,
     }
 
     if (s->invert) {
-        dst = s->picture.data[0];
+        dst = p->data[0];
         for (i = 0; i < s->height; i++) {
-            for (j = 0; j < s->picture.linesize[0]; j++)
+            for (j = 0; j < p->linesize[0]; j++)
                 dst[j] = (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
-            dst += s->picture.linesize[0];
+            dst += p->linesize[0];
         }
     }
-    *picture   = s->picture;
     *got_frame = 1;
 
     return avpkt->size;
@@ -1217,8 +1213,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();
 
@@ -1233,8 +1227,6 @@ static av_cold int tiff_end(AVCodecContext *avctx)
 
     ff_lzw_decode_close(&s->lzw);
     av_freep(&s->deinvert_buf);
-    if (s->picture.data[0])
-        avctx->release_buffer(avctx, &s->picture);
     return 0;
 }
 
diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c
index f8d7969d40db7db84a5254c9870cc3065b95d069..2e6a22badfb3e05d60d9884273b7fb8d5664cbe3 100644
--- a/libavcodec/tmv.c
+++ b/libavcodec/tmv.c
@@ -35,14 +35,10 @@
 
 #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;
@@ -50,10 +46,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;
     }
@@ -65,45 +58,33 @@ 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);
-    memset(tmv->pic.data[1] + 16 * 4, 0, AVPALETTE_SIZE - 16 * 4);
+    frame->palette_has_changed = 1;
+    memcpy(frame->data[1], ff_cga_palette, 16 * 4);
+    memset(frame->data[1] + 16 * 4, 0, AVPALETTE_SIZE - 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],
                             avpriv_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;
 }
 
 static av_cold int tmv_decode_init(AVCodecContext *avctx)
 {
-    TMVContext *tmv = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
-    avcodec_get_frame_defaults(&tmv->pic);
-    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;
 }
 
@@ -111,9 +92,7 @@ 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"),
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index ed6b5d95cf512c04d45e6df4fa3543203a586ecf..8af92f501a5a39683e362931b63b76ef7f59cbe8 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -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);
@@ -869,10 +869,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx,
     if ((ret = truemotion1_decode_header(s)) < 0)
         return ret;
 
-    s->frame.reference = 3;
-    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;
     }
@@ -883,8 +880,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;
@@ -894,9 +893,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;
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index eacd728ca418ae59c2495e813b8570d71ea2983d..8c28a816f61ab741dfdc48973252c4a90711bd07 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -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
@@ -866,9 +867,8 @@ static int decode_frame(AVCodecContext *avctx,
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
         return AVERROR(ENOMEM);
     }
-    p->reference = 3;
-    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");
         return ret;
     }
@@ -902,9 +902,9 @@ static int decode_frame(AVCodecContext *avctx,
 
     l->cur = !l->cur;
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
+    ret = av_frame_ref(data, &l->pic);
 
-    return buf_size;
+    return (ret < 0) ? ret : buf_size;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx)
@@ -989,8 +989,7 @@ static av_cold int decode_end(AVCodecContext *avctx)
     av_freep(&l->buffer);
     l->buffer_size = 0;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
+    av_frame_unref(pic);
 
     return 0;
 }
diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c
index fea9ae4195033372a8d6083dc126b438b6c9a092..67d77fd3105271c789e818d15fa3034da84346f8 100644
--- a/libavcodec/truespeech.c
+++ b/libavcodec/truespeech.c
@@ -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;
     }
diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c
index 7c2d2319bb19162ae1e7fbe9cc0057294e5081e4..d9072410b6ae67f35485ac9428fa3033b3ddfcdd 100644
--- a/libavcodec/tscc.c
+++ b/libavcodec/tscc.c
@@ -47,7 +47,7 @@
 typedef struct TsccContext {
 
     AVCodecContext *avctx;
-    AVFrame pic;
+    AVFrame *frame;
 
     // Bits per pixel
     int bpp;
@@ -69,13 +69,12 @@ 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 = c->frame;
     int zret; // Zlib return code
     int ret, len = buf_size;
 
-    c->pic.reference = 3;
-    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+    if ((ret = ff_reget_buffer(avctx, frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return ret;
     }
 
@@ -99,7 +98,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 */
@@ -107,14 +106,15 @@ 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);
     }
 
+    if ((ret = av_frame_ref(data, frame)) < 0)
+        return ret;
     *got_frame      = 1;
-    *(AVFrame*)data = c->pic;
 
     /* always report that the buffer was completely consumed */
     return buf_size;
@@ -129,7 +129,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     c->height = avctx->height;
 
-    avcodec_get_frame_defaults(&c->pic);
     // Needed if zlib unused or init aborted before inflateInit
     memset(&c->zstream, 0, sizeof(z_stream));
     switch(avctx->bits_per_coded_sample){
@@ -163,6 +162,8 @@ static av_cold int decode_init(AVCodecContext *avctx)
         return AVERROR_UNKNOWN;
     }
 
+    c->frame = av_frame_alloc();
+
     return 0;
 }
 
@@ -171,9 +172,8 @@ static av_cold int decode_end(AVCodecContext *avctx)
     CamtasiaContext * const c = avctx->priv_data;
 
     av_freep(&c->decomp_buf);
+    av_frame_free(&c->frame);
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
     inflateEnd(&c->zstream);
 
     return 0;
diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c
index b71e7fa25b6ae3c95cb1b40426f1b51ab863bd44..f87ab406f21c8128e9d516174b797da9de98846b 100644
--- a/libavcodec/tscc2.c
+++ b/libavcodec/tscc2.c
@@ -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);
 
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 4240946aa26eb282d2529e30adafd9251d86d52d..0d1075098b609924161bae8bc52e4da7f7e93889 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -334,7 +334,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;
     }
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index e9d206e2902b253bfe63e2b297d5c33bfec93219..8cd6ccf23efaf3e13148e83477ac90f0668e1df4 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -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;
         }
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index b5b34acf3c185cf124b91f4f595f3c68eaebb27d..a51d766aee5a0e372a8a1d458199d78ec1f6d68c 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -28,25 +28,10 @@
 #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;
     }
@@ -143,7 +125,6 @@ static int txd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         }
     }
 
-    *picture   = s->picture;
     *got_frame = 1;
 
     return avpkt->size;
@@ -153,22 +134,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"),
diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c
index a9413ad7280ca878dd0e68b9e6584228cc55b6c1..a6d8216dad5970191347c2e068d686571cbf55be 100644
--- a/libavcodec/ulti.c
+++ b/libavcodec/ulti.c
@@ -30,6 +30,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "internal.h"
 
 #include "ulti_cb.h"
 
@@ -61,8 +62,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;
 }
@@ -222,15 +222,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 = 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;
     }
 
     bytestream2_init(&s->gb, buf, buf_size);
@@ -408,7 +406,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;
 
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index e42b72e431a1f0b763d190cd9bbbf31f87f8a82e..d68c28093bc3a0565e4c929ab032bd592105567d 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -31,6 +31,7 @@
 #include "libavutil/bprint.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"
@@ -179,8 +180,6 @@ void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
     s->height       = -((-height) >> s->lowres);
 }
 
-#define INTERNAL_BUFFER_SIZE (32 + 1)
-
 #if (ARCH_ARM && HAVE_NEON) || ARCH_PPC || HAVE_MMX
 #   define STRIDE_ALIGN 16
 #else
@@ -358,89 +357,26 @@ int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
     return ret;
 }
 
-static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+static int update_frame_pool(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)
-{
-    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;
-    }
-
-    if (av_image_check_size(w, h, 0, s) || s->pix_fmt<0) {
-        av_log(s, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n");
-        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;
-        }
-    }
+    FramePool *pool = avctx->internal->pool;
+    int i, ret;
 
-    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;
         }
@@ -448,16 +384,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;
 
@@ -465,49 +402,156 @@ 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 && size[i]; i++) {
-            const int h_shift = i == 0 ? 0 : h_chroma_shift;
-            const int v_shift = i == 0 ? 0 : v_chroma_shift;
+        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;
 
-            buf->linesize[i] = picture.linesize[i];
+        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;
 
-            buf->base[i] = av_malloc(size[i] + 16); //FIXME 16
-            if (buf->base[i] == NULL)
-                return AVERROR(ENOMEM);
+        pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL);
+        if (!pool->pools[0]) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
 
-            // 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]);
+        pool->format     = frame->format;
+        pool->planes     = planes;
+        pool->channels   = ch;
+        pool->samples = frame->nb_samples;
+        break;
         }
-        for (; i < AV_NUM_DATA_POINTERS; i++) {
-            buf->base[i]     = buf->data[i] = NULL;
-            buf->linesize[i] = 0;
+    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;
+}
+
+static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+{
+    FramePool *pool = avctx->internal->pool;
+    int planes = pool->planes;
+    int i;
+
+    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;
     }
 
-    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];
+    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);
+}
+
+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);
 }
 
 void avpriv_color_frame(AVFrame *frame, const int c[4])
@@ -532,9 +576,17 @@ void avpriv_color_frame(AVFrame *frame, const int c[4])
     }
 }
 
-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);
@@ -576,94 +628,204 @@ void ff_init_buffer_info(AVCodecContext *s, AVFrame *frame)
     }
 }
 
-int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
+#if FF_API_GET_BUFFER
+int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame)
 {
-    ff_init_buffer_info(avctx, frame);
+    return avcodec_default_get_buffer2(avctx, frame, 0);
+}
 
-    return avctx->get_buffer(avctx, frame);
+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);
 }
 
-void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic)
+static void compat_release_buffer(void *opaque, uint8_t *data)
 {
-    int i;
-    InternalBuffer *buf, *last;
-    AVCodecInternal *avci = s->internal;
+    AVBufferRef *buf = opaque;
+    av_buffer_unref(&buf);
+}
+#endif
 
-    av_assert0(s->codec_type == AVMEDIA_TYPE_VIDEO);
+int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
+{
+    int ret;
+
+    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+        if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0 || avctx->pix_fmt<0) {
+            av_log(avctx, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n");
+            return AVERROR(EINVAL);
+        }
+    }
+    ff_init_buffer_info(avctx, frame);
 
-    assert(pic->type == FF_BUFFER_TYPE_INTERNAL);
-    assert(avci->buffer_count);
+#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;
 
-    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;
+        if (flags & AV_GET_BUFFER_FLAG_REF)
+            frame->reference    = 1;
+
+        ret = avctx->get_buffer(avctx, frame);
+        if (ret < 0)
+            return ret;
+
+        /* return if the buffers are already set up
+         * this would happen e.g. when a custom get_buffer() calls
+         * avcodec_default_get_buffer
+         */
+        if (frame->buf[0])
+            return 0;
+
+        priv = av_mallocz(sizeof(*priv));
+        if (!priv) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
         }
-        av_assert0(i < avci->buffer_count);
-        avci->buffer_count--;
-        last = &avci->buffer[avci->buffer_count];
+        priv->avctx = *avctx;
+        priv->frame = *frame;
 
-        if (buf != last)
-            FFSWAP(InternalBuffer, *buf, *last);
-    }
+        dummy_buf = av_buffer_create(NULL, 0, compat_free_buffer, priv, 0);
+        if (!dummy_buf) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
 
-    for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
-        pic->data[i] = NULL;
-//        pic->base[i]=NULL;
+#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;
 
-    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);
-}
+            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];
 
-int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic)
-{
-    AVFrame temp_pic;
-    int i, ret;
+                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;
+                }
+            }
 
-    av_assert0(s->codec_type == AVMEDIA_TYPE_VIDEO);
+            for (i = 0; i < FFMIN(planes, FF_ARRAY_ELEMS(frame->buf)); i++)
+                WRAP_PLANE(frame->buf[i], frame->extended_data[i], frame->linesize[0]);
 
-    if (pic->data[0] && (pic->width != s->width || pic->height != s->height || pic->format != s->pix_fmt)) {
-        av_log(s, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n",
-               pic->width, pic->height, av_get_pix_fmt_name(pic->format), s->width, s->height, av_get_pix_fmt_name(s->pix_fmt));
-        s->release_buffer(s, pic);
+            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);
+
+        return 0;
+
+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;
 
-    ff_init_buffer_info(s, pic);
+    av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO);
 
-    /* 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);
+    if (frame->data[0] && (frame->width != avctx->width || frame->height != avctx->height || frame->format != avctx->pix_fmt)) {
+        av_log(avctx, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n",
+               frame->width, frame->height, av_get_pix_fmt_name(frame->format), avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
+        av_frame_unref(frame);
     }
 
-    assert(s->pix_fmt == pic->format);
+    ff_init_buffer_info(avctx, frame);
 
-    /* If internal buffer type return the same buffer */
-    if (pic->type == FF_BUFFER_TYPE_INTERNAL) {
+    if (!frame->data[0])
+        return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF);
+
+    if (av_frame_is_writable(frame))
         return 0;
-    }
 
-    /*
-     * 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 ((ret = ff_get_buffer(s, pic)))
+    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;
-    /* 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_assert0(s->codec_type == AVMEDIA_TYPE_VIDEO);
+
+    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;
@@ -844,6 +1006,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);
@@ -1138,6 +1306,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;
@@ -1670,6 +1840,7 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
                                               int *got_picture_ptr,
                                               const AVPacket *avpkt)
 {
+    AVCodecInternal *avci = avctx->internal;
     int ret;
     // copy to ensure we do not change avpkt
     AVPacket tmp = *avpkt;
@@ -1685,6 +1856,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)) {
         int did_split = av_packet_split_side_data(&tmp);
         apply_param_change(avctx, &tmp);
@@ -1720,7 +1894,15 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi
                 ret = avpkt->size;
         }
 
-        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++;
             av_frame_set_best_effort_timestamp(picture,
                                                guess_correct_pts(avctx,
@@ -1791,6 +1973,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
                                               int *got_frame_ptr,
                                               const AVPacket *avpkt)
 {
+    AVCodecInternal *avci = avctx->internal;
     int planar, channels;
     int ret = 0;
 
@@ -1807,6 +1990,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) {
         uint8_t *side;
         int side_size;
@@ -1832,6 +2018,10 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
                 av_frame_set_channels(frame, avctx->channels);
             if (!frame->sample_rate)
                 frame->sample_rate = avctx->sample_rate;
+            if (!avctx->refcounted_frames) {
+                avci->to_free = *frame;
+                avci->to_free.extended_data = avci->to_free.data;
+            }
         }
         add_metadata_from_side_data(avctx, frame);
 
@@ -1876,6 +2066,9 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
             if(ret == tmp.size)
                 ret = avpkt->size;
         }
+
+        if (ret < 0 && frame->data[0])
+            av_frame_unref(frame);
     }
 
     /* many decoders assign whole AVFrames, thus overwriting extended_data;
@@ -2040,6 +2233,8 @@ av_cold int avcodec_close(AVCodecContext *avctx)
         return ret;
 
     if (avcodec_is_open(avctx)) {
+        FramePool *pool = avctx->internal->pool;
+        int i;
         if (HAVE_THREADS && avctx->internal->frame_thread_encoder && avctx->thread_count > 1) {
             ff_unlock_avcodec();
             ff_frame_thread_encoder_free(avctx);
@@ -2049,10 +2244,14 @@ av_cold int avcodec_close(AVCodecContext *avctx)
             ff_thread_free(avctx);
         if (avctx->codec && avctx->codec->close)
             avctx->codec->close(avctx);
-        avcodec_default_free_buffers(avctx);
         avctx->coded_frame = NULL;
         avctx->internal->byte_buffer_size = 0;
         av_freep(&avctx->internal->byte_buffer);
+        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);
         av_dict_free(&avctx->metadata);
     }
@@ -2336,49 +2535,6 @@ void avcodec_flush_buffers(AVCodecContext *avctx)
     avctx->pts_correction_last_dts = INT64_MIN;
 }
 
-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) {
@@ -2784,29 +2940,48 @@ 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, ThreadFrame *f, int flags)
 {
     f->owner = avctx;
 
-    return ff_get_buffer(avctx, f);
+    return ff_get_buffer(avctx, f->f, flags);
 }
 
-void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f)
+void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f)
 {
-    f->owner->release_buffer(f->owner, f);
+    av_frame_unref(f->f);
 }
 
 void ff_thread_finish_setup(AVCodecContext *avctx)
 {
 }
 
-void ff_thread_report_progress(AVFrame *f, int progress, int field)
+void ff_thread_report_progress(ThreadFrame *f, int progress, int field)
 {
 }
 
-void ff_thread_await_progress(AVFrame *f, int progress, int field)
+void ff_thread_await_progress(ThreadFrame *f, int progress, int field)
 {
 }
 
diff --git a/libavcodec/utvideo.h b/libavcodec/utvideo.h
index 266291cec7e6f5c2f54aa01668d5fea286cde764..c00179ed98f64e118621739df38684e46eb1afc2 100644
--- a/libavcodec/utvideo.h
+++ b/libavcodec/utvideo.h
@@ -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;
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index 259030aac57c6c704412287f6a338b7e1c7a7077..1bb2eb5b2fd09a6beee741148369871b88badd7d 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -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 = 3;
-    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;
     }
@@ -394,42 +390,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);
@@ -439,18 +435,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);
                 }
@@ -459,12 +455,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;
@@ -532,9 +527,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;
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index 132b42ad979a8d01db88279f184b75363a707262..42e25cc0173858ddfd2c3ea3186f4addf68b2364 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -60,10 +60,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);
-
     s->unpack_frame            = v210_planar_unpack_c;
 
     if (HAVE_MMX)
@@ -78,7 +74,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
     V210DecContext *s = avctx->priv_data;
 
     int h, w, ret, stride, aligned_input;
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *psrc = avpkt->data;
     uint16_t *y, *u, *v;
 
@@ -108,11 +104,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
             v210_x86_init(s);
     }
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
-    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];
@@ -155,21 +147,10 @@ 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;
-}
-
 #define V210DEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
 static const AVOption v210dec_options[] = {
     {"custom_stride", "Custom V210 stride", offsetof(V210DecContext, custom_stride), FF_OPT_TYPE_INT,
@@ -190,7 +171,6 @@ AVCodec ff_v210_decoder = {
     .id             = AV_CODEC_ID_V210,
     .priv_data_size = sizeof(V210DecContext),
     .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"),
diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c
index cb9fc6f27a812bc8f36665c6237210437f35e444..0d885def824a357c09c1e28b94fb44091af3eced 100644
--- a/libavcodec/v210x.c
+++ b/libavcodec/v210x.c
@@ -33,10 +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();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
     return 0;
 }
 
@@ -44,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;
@@ -62,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];
@@ -124,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"),
diff --git a/libavcodec/v308dec.c b/libavcodec/v308dec.c
index b5567f85742c4938d7284e6f26c32a5a4b38d123..a85d655eb9f63e3c53c249f1118070110d83436e 100644
--- a/libavcodec/v308dec.c
+++ b/libavcodec/v308dec.c
@@ -29,35 +29,23 @@ static av_cold int v308_decode_init(AVCodecContext *avctx)
     if (avctx->width & 1)
         av_log(avctx, AV_LOG_WARNING, "v308 requires width to be even.\n");
 
-    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 v308_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *src = avpkt->data;
     uint8_t *y, *u, *v;
     int i, j;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < 3 * 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);
     }
@@ -89,10 +77,6 @@ static int v308_decode_frame(AVCodecContext *avctx, void *data,
 
 static av_cold int v308_decode_close(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
 
     return 0;
 }
diff --git a/libavcodec/v408dec.c b/libavcodec/v408dec.c
index 470853d55136cf6babd4c1804ea89b5c623bb718..b295d4abdfd5fd6d600006f22cb75432ecdbeb0d 100644
--- a/libavcodec/v408dec.c
+++ b/libavcodec/v408dec.c
@@ -26,35 +26,23 @@ static av_cold int v408_decode_init(AVCodecContext *avctx)
 {
     avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
 
-    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 v408_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *src = avpkt->data;
     uint8_t *y, *u, *v, *a;
     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);
     }
@@ -89,17 +77,12 @@ static int v408_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
 
 static av_cold int v408_decode_close(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
 
     return 0;
 }
diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c
index ff2381741a9b158d023792aa55f49b210ce17822..9e125443d9f5f60916b7613f1af6521a9fc228b5 100644
--- a/libavcodec/v410dec.c
+++ b/libavcodec/v410dec.c
@@ -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"),
 };
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index 349dc1bb017069e4d537c6f4b7683ac43cef7404..b4ae27aca0c658c30b077ff95a6a26673197bf2f 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -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++)
diff --git a/libavcodec/vb.c b/libavcodec/vb.c
index 3b5a83be17aa16fd2f532c2cfadd3128ea766f75..ebb06f522fb346c095b3c994d78829cd600a7d01 100644
--- a/libavcodec/vb.c
+++ b/libavcodec/vb.c
@@ -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 = 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;
     }
@@ -226,22 +223,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;
@@ -253,7 +249,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     c->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
-    avcodec_get_frame_defaults(&c->pic);
 
     c->frame      = av_mallocz(avctx->width * avctx->height);
     c->prev_frame = av_mallocz(avctx->width * avctx->height);
@@ -267,8 +262,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;
 }
diff --git a/libavcodec/vble.c b/libavcodec/vble.c
index c8037bdb808ec9fdb1f33da82b1cb596e5dbf1c3..76dfef87500ccd2ad6e1e3f895fe69f2274f8574 100644
--- a/libavcodec/vble.c
+++ b/libavcodec/vble.c
@@ -80,10 +80,10 @@ static int vble_unpack(VBLEContext *ctx, GetBitContext *gb)
     return 0;
 }
 
-static void vble_restore_plane(VBLEContext *ctx, GetBitContext *gb, int plane,
+static void vble_restore_plane(VBLEContext *ctx, AVFrame *pic,
+                               GetBitContext *gb, 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];
@@ -115,26 +115,20 @@ 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);
-
     if (avpkt->size < 4 || avpkt->size - 4 > INT_MAX/8) {
         av_log(avctx, AV_LOG_ERROR, "Invalid packet size\n");
         return AVERROR_INVALIDDATA;
     }
 
     /* 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);
     }
@@ -158,19 +152,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, &gb, 0, offset, avctx->width, avctx->height);
+    vble_restore_plane(ctx, pic, &gb, 0, offset, avctx->width, avctx->height);
 
     /* Chroma */
     if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
         offset += avctx->width * avctx->height;
-        vble_restore_plane(ctx, &gb, 1, offset, width_uv, height_uv);
+        vble_restore_plane(ctx, pic, &gb, 1, offset, width_uv, height_uv);
 
         offset += width_uv * height_uv;
-        vble_restore_plane(ctx, &gb, 2, offset, width_uv, height_uv);
+        vble_restore_plane(ctx, pic, &gb, 2, offset, width_uv, height_uv);
     }
 
     *got_frame       = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
@@ -178,12 +171,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;
@@ -199,12 +186,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);
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index fb4046b2d21d0de1749f0ea0bac6a5cf226ec9d7..aafc358fd661cc1962869cee2cbb83dd427f344a 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -362,8 +362,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;
@@ -621,8 +621,8 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir)
         default:
             av_assert2(0);
         }
-        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;
     }
@@ -813,8 +813,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
         }
@@ -828,8 +828,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;
 
@@ -1399,30 +1399,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;
@@ -1444,7 +1444,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);
@@ -1607,15 +1607,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];
     }
@@ -1639,24 +1639,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;
     }
@@ -1666,14 +1666,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]) {
@@ -1693,11 +1693,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) {
@@ -1708,11 +1708,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]) {
@@ -1722,11 +1722,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;
@@ -1737,12 +1737,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;
@@ -1831,18 +1831,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];
     }
@@ -2060,17 +2060,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));
@@ -2079,18 +2079,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
@@ -2165,10 +2165,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;
@@ -2244,10 +2244,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)
@@ -2258,14 +2258,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]
@@ -2280,10 +2280,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;
         }
@@ -2401,17 +2401,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;
     }
@@ -2421,7 +2421,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;
     }
@@ -2792,11 +2792,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)
@@ -3015,11 +3015,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)
@@ -3337,7 +3337,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 ||
@@ -3399,7 +3399,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);
@@ -3493,10 +3493,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 ? */
@@ -3513,7 +3513,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,
@@ -3567,8 +3567,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);
         }
@@ -3611,7 +3611,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;
@@ -3674,7 +3674,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;
@@ -3684,7 +3684,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:
@@ -3759,9 +3759,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;
@@ -3771,7 +3771,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];
@@ -3863,7 +3863,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++) {
@@ -3892,8 +3892,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;
@@ -3930,11 +3930,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];
@@ -3965,7 +3965,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;
@@ -3996,7 +3996,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);
         }
@@ -4060,7 +4060,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) {
@@ -4097,7 +4097,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;
@@ -4112,7 +4112,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);
@@ -4134,7 +4134,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);
         }
@@ -4201,11 +4201,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];
@@ -4239,7 +4239,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);
@@ -4305,7 +4305,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);
         }
@@ -4385,10 +4385,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);
@@ -4525,9 +4525,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)
@@ -4543,7 +4543,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];
@@ -5040,12 +5040,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;
     }
@@ -5310,9 +5306,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);
@@ -5346,7 +5341,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;
@@ -5368,7 +5363,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;
@@ -5760,17 +5756,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);
         }
     }
 
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index e9b1a7b7951307572ddb756dafa58834d23bdd41..6ef7165c8d03277e6c9276c98775a32a1331a15c 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -29,25 +29,12 @@
 #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;
-    avcodec_get_frame_defaults(&a->picture);
-
-    return 0;
-}
-
 static av_cold int vcr1_decode_init(AVCodecContext *avctx)
 {
-    vcr1_common_init(avctx);
-
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
 
     if (avctx->width % 8 || avctx->height%4) {
@@ -57,37 +44,22 @@ static av_cold int vcr1_decode_init(AVCodecContext *avctx)
     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);
-
     if(buf_size < 16 + avctx->height + avctx->width*avctx->height*5/8){
         av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
         return AVERROR(EINVAL);
     }
 
-    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;
     }
@@ -101,11 +73,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++;
@@ -141,7 +113,6 @@ static int vcr1_decode_frame(AVCodecContext *avctx, void *data,
         }
     }
 
-    *picture   = a->picture;
     *got_frame = 1;
 
     return buf_size;
@@ -153,7 +124,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"),
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 6df7f4af9594a32eb87ffc0d8329fea7d6bba931..5606902984763b8371f0d37367b21c402a0e3a35 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -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;
diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c
index 0f79c5868fc0c1e79642619789b61baebc6d40d2..ad1aff0acb5f9682036386fd40ccc7d61f192a7e 100644
--- a/libavcodec/vdpau_h264.c
+++ b/libavcodec/vdpau_h264.c
@@ -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;
         }
     }
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 3e5fa945eebb6eef8161eed49f4017850075c9b0..6522c12e20f37b083214dd2332f2ddd5b3ae3dbd 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -112,5 +112,8 @@
 #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 */
diff --git a/libavcodec/vima.c b/libavcodec/vima.c
index 604e0ce1102e6ec3768e3630ae2096f944177f78..658c6ce700975ba6b2971797ed77345365cc65a7 100644
--- a/libavcodec/vima.c
+++ b/libavcodec/vima.c
@@ -170,7 +170,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
     }
 
     frame->nb_samples = 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;
     }
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index d7f136c8a1e37eb6aedbd59dfb1566a3fd972cce..e8574c10e2e539df25594190f9e3f5220f3df7d8 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -59,7 +59,6 @@
 typedef struct VmdVideoContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
     AVFrame prev_frame;
 
     const unsigned char *buf;
@@ -202,7 +201,7 @@ static int rle_unpack(const unsigned char *src, int src_len, int src_count,
     return ps - src;
 }
 
-static void vmd_decode(VmdVideoContext *s)
+static void vmd_decode(VmdVideoContext *s, AVFrame *frame)
 {
     int i;
     unsigned int *palette32;
@@ -253,8 +252,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 */
@@ -283,7 +282,7 @@ static void vmd_decode(VmdVideoContext *s)
             pb_end = s->unpack_buffer + 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:
@@ -313,7 +312,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;
@@ -324,7 +323,7 @@ static void vmd_decode(VmdVideoContext *s)
                     return;
                 memcpy(dp, pb, frame_width);
                 pb += frame_width;
-                dp += s->frame.linesize[0];
+                dp += frame->linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
             break;
@@ -361,7 +360,7 @@ static void vmd_decode(VmdVideoContext *s)
                     av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n",
                         ofs, frame_width);
                 }
-                dp += s->frame.linesize[0];
+                dp += frame->linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
             break;
@@ -405,7 +404,6 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
         palette32[i] = (r << 16) | (g << 8) | (b);
     }
 
-    avcodec_get_frame_defaults(&s->frame);
     avcodec_get_frame_defaults(&s->prev_frame);
 
     return 0;
@@ -418,6 +416,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;
@@ -425,24 +425,22 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx,
     if (buf_size < 16)
         return buf_size;
 
-    s->frame.reference = 3;
-    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, "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;
@@ -452,8 +450,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;
@@ -600,7 +597,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;
     }
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index eb39fc923d1de7d0cfb4db5f8d7c6a423fc8d75b..a53adac6dcfeaef65b9fd90d9e634f91cb63a67e 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -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 = 3;
-    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;
@@ -456,7 +455,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;
@@ -511,8 +511,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);
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index bd5b2e43c3e4f44c25d9f562d248acf9bc6d2058..581b7bc86901c633e33627768f342f26d20789aa 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1729,7 +1729,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;
     }
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 686683d56ddc93e034768179927970f4a49e6366..a77bf8fe59a7e29b7ec1b8528cb5ca883fa7dd0d 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -135,9 +135,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;
     uint8_t idct_permutation[64];
     DSPContext dsp;
@@ -266,19 +266,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);
 }
 
@@ -299,6 +291,12 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx)
 
     s->theora_tables = 0;
 
+    /* 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;
 
@@ -315,8 +313,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;
 }
@@ -1297,8 +1293,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;
 
@@ -1427,14 +1423,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);
 }
 
 /**
@@ -1443,7 +1439,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;
 
@@ -1476,10 +1472,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];
@@ -1658,14 +1654,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, keyframe);
+            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, idct_permutation);
+        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,8 +1949,7 @@ static int vp3_decode_frame(AVCodecContext *avctx,
     int buf_size = avpkt->size;
     Vp3DecodeContext *s = avctx->priv_data;
     GetBitContext gb;
-    int i;
-    int ret;
+    int i, ret;
 
     init_get_bits(&gb, buf, buf_size * 8);
 
@@ -1992,16 +2022,15 @@ 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;
-    s->current_frame.key_frame = s->keyframe;
-    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;
+    s->current_frame.f->key_frame = s->keyframe;
+    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)
@@ -2022,17 +2051,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);
         }
     }
@@ -2066,7 +2095,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;
@@ -2080,11 +2109,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;
 
@@ -2092,7 +2125,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;
 }
@@ -2146,7 +2179,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
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index 10dab39e4c97b7593c85570c170d417b375b359e..b2d7de94f1f556cc76a1d4f0afd63706e89cee27 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -40,10 +40,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)
@@ -137,7 +137,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];
             }
 
@@ -148,7 +148,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];
                     }
 
@@ -263,8 +263,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;
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index b4af2cac71f1d633a3d3adb3f1d212a6bad01f90..00334d12822f8208c75a8d3d81477df09b8bd347 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -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(VP56Context *s)
 {
     AVCodecContext *avctx = s->avctx;
-    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(VP56Context *s)
     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(VP56Context *s)
         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,
@@ -500,23 +498,11 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 {
     const uint8_t *buf = avpkt->data;
     VP56Context *s = avctx->priv_data;
-    AVFrame *p = 0;
+    AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
     int remaining_buf_size = avpkt->size;
     int av_uninit(alpha_offset);
     int i, res;
 
-    /* select a current frame from the unused frames */
-    for (i = 0; i < 4; ++i) {
-        if (!s->frames[i].data[0]) {
-            p = &s->frames[i];
-            break;
-        }
-    }
-    av_assert0(p != 0);
-    s->framep[VP56_FRAME_CURRENT] = p;
-    if (s->alpha_context)
-        s->alpha_context->framep[VP56_FRAME_CURRENT] = p;
-
     if (s->has_alpha) {
         if (remaining_buf_size < 3)
             return -1;
@@ -532,20 +518,25 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
     if (res == VP56_SIZE_CHANGE) {
         for (i = 0; i < 4; i++) {
-            if (s->frames[i].data[0])
-                avctx->release_buffer(avctx, &s->frames[i]);
+            av_frame_unref(s->frames[i]);
+            if (s->alpha_context)
+                av_frame_unref(s->alpha_context->frames[i]);
         }
     }
 
-    p->reference = 3;
-    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 (s->has_alpha) {
+        av_frame_unref(s->alpha_context->frames[VP56_FRAME_CURRENT]);
+        av_frame_ref(s->alpha_context->frames[VP56_FRAME_CURRENT], p);
+    }
+
     if (res == VP56_SIZE_CHANGE) {
         if (vp56_size_changed(s)) {
-            avctx->release_buffer(avctx, p);
+            av_frame_unref(p);
             return -1;
         }
     }
@@ -567,28 +558,15 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                 avctx->coded_width  = bak_cw;
                 avctx->coded_height = bak_ch;
             }
-            avctx->release_buffer(avctx, p);
+            av_frame_unref(p);
             return -1;
         }
     }
 
     avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, s->has_alpha + 1);
 
-    /* release frames that aren't in use */
-    for (i = 0; i < 4; ++i) {
-        AVFrame *victim = &s->frames[i];
-        if (!victim->data[0])
-            continue;
-        if (victim != s->framep[VP56_FRAME_PREVIOUS] &&
-            victim != s->framep[VP56_FRAME_GOLDEN] &&
-            (!s->has_alpha || victim != s->alpha_context->framep[VP56_FRAME_GOLDEN]))
-            avctx->release_buffer(avctx, victim);
-    }
-
-    p->qstride = 0;
-    p->qscale_table = s->qscale_table;
-    p->qscale_type = FF_QSCALE_TYPE_VP56;
-    *(AVFrame*)data = *p;
+    if ((res = av_frame_ref(data, p)) < 0)
+        return res;
     *got_frame = 1;
 
     return avpkt->size;
@@ -600,9 +578,10 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
     VP56Context *s0 = avctx->priv_data;
     int is_alpha = (jobnr == 1);
     VP56Context *s = is_alpha ? s0->alpha_context : s0;
-    AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
+    AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
     int mb_row, mb_col, mb_row_flip, mb_offset = 0;
     int block, y, uv, stride_y, stride_uv;
+    int res;
 
     if (p->key_frame) {
         p->pict_type = AV_PICTURE_TYPE_I;
@@ -683,21 +662,24 @@ static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
 
 next:
     if (p->key_frame || s->golden_frame) {
-        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;
     }
 
-    FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],
-                      s->framep[VP56_FRAME_PREVIOUS]);
+    av_frame_unref(s->frames[VP56_FRAME_PREVIOUS]);
+    FFSWAP(AVFrame *, s->frames[VP56_FRAME_CURRENT],
+                      s->frames[VP56_FRAME_PREVIOUS]);
     return 0;
 }
 
-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;
-    ff_vp56_init_context(avctx, s, flip, has_alpha);
+    return ff_vp56_init_context(avctx, s, flip, has_alpha);
 }
 
-av_cold void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
+av_cold int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
                                   int flip, int has_alpha)
 {
     int i;
@@ -713,12 +695,13 @@ av_cold void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
     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];
-        avcodec_get_frame_defaults(&s->frames[i]);
+    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->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN];
-    s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2];
     s->edge_emu_buffer_alloc = NULL;
 
     s->above_blocks = NULL;
@@ -742,6 +725,8 @@ av_cold void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
         s->frbi = 0;
         s->srbi = 2;
     }
+
+    return 0;
 }
 
 av_cold int ff_vp56_free(AVCodecContext *avctx)
@@ -755,13 +740,12 @@ av_cold int ff_vp56_free_context(VP56Context *s)
     AVCodecContext *avctx = s->avctx;
     int i;
 
-    av_freep(&s->qscale_table);
     av_freep(&s->above_blocks);
     av_freep(&s->macroblocks);
     av_freep(&s->edge_emu_buffer_alloc);
-    for (i = 0; i < 4; ++i) {
-        if (s->frames[i].data[0])
-            avctx->release_buffer(avctx, &s->frames[i]);
-    }
+
+    for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+        av_frame_free(&s->frames[i]);
+
     return 0;
 }
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 14c130f43059dfefea3f4ca68921edebfa51627d..e9a53a1667f13a9a1c9b84e6f57e09f6160b740f 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -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;
@@ -121,7 +120,6 @@ struct vp56_context {
     int quantizer;
     uint16_t dequant_dc;
     uint16_t dequant_ac;
-    int8_t *qscale_table;
 
     /* DC predictors management */
     VP56RefDc *above_blocks;
@@ -183,8 +181,8 @@ struct vp56_context {
 };
 
 
-void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
-void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
+int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
+int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
                           int flip, int has_alpha);
 int ff_vp56_free(AVCodecContext *avctx);
 int ff_vp56_free_context(VP56Context *s);
diff --git a/libavcodec/vp56data.h b/libavcodec/vp56data.h
index f30732ed94aed6d7896a0eb44d391d33f6c4698e..3cafaaf018571f968f2e4e6b8f5e52fb9b50017b 100644
--- a/libavcodec/vp56data.h
+++ b/libavcodec/vp56data.h
@@ -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 {
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index f761aa7f29f514bdbf6fd8a5cdb788972820a09a..6fd1f507a4ae2bc57dba972312a453e115eee76f 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -53,10 +53,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];
                     }
 
@@ -594,9 +594,12 @@ static av_cold void vp6_decode_init_context(VP56Context *s);
 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);
     vp6_decode_init_context(s);
 
     if (s->has_alpha) {
@@ -606,8 +609,6 @@ static av_cold int vp6_decode_init(AVCodecContext *avctx)
         ff_vp56_init_context(avctx, s->alpha_context,
                              s->flip == -1, s->has_alpha);
         vp6_decode_init_context(s->alpha_context);
-        for (i = 0; i < 6; ++i)
-            s->alpha_context->framep[i] = s->framep[i];
     }
 
     return 0;
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index fc6fd3728f3e6e41744c52edea0a639af59e0399..9218dff2346256870e0f645d6223e2fff0d92091 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -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);
     }
@@ -1179,12 +1174,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)) {
 
@@ -1230,11 +1225,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];
@@ -1273,7 +1268,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)
@@ -1311,7 +1306,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
@@ -1331,7 +1326,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) {
@@ -1590,17 +1585,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;
@@ -1618,8 +1605,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;
         }
@@ -1673,13 +1661,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];
@@ -1698,7 +1686,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;
         }
@@ -1721,8 +1709,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);
 
@@ -1781,7 +1770,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] = {
@@ -1835,7 +1824,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) {
@@ -1850,7 +1839,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;
@@ -1862,9 +1851,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;
@@ -1886,12 +1873,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++)
@@ -1906,8 +1893,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
@@ -1920,10 +1907,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;
     }
@@ -1948,8 +1934,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++)
@@ -1974,7 +1960,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);
@@ -1994,7 +1980,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:
@@ -2004,7 +1990,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;
     }
 
@@ -2014,33 +2001,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;
 }
 
@@ -2050,11 +2066,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;
     }
@@ -2064,7 +2080,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]);
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 19763907d7f6ce45a582970f87ff2d6bf3117143..90109ad1546693fee83f12d794ea5e3017d01194 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -26,10 +26,13 @@
 #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
@@ -124,14 +127,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 */
@@ -253,17 +261,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.
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index 43b3aaf57cc323898408303357cefc4047f8d94d..6510582cd6e28ce655b03a382b70ce44e79e1ea0 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -94,7 +94,6 @@
 typedef struct VqaContext {
 
     AVCodecContext *avctx;
-    AVFrame frame;
     GetByteContext gb;
 
     uint32_t palette[PALETTE_COUNT];
@@ -191,9 +190,6 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx)
     }
     s->next_codebook_buffer_index = 0;
 
-    avcodec_get_frame_defaults(&s->frame);
-    s->frame.data[0] = NULL;
-
     return 0;
 fail:
     av_freep(&s->codebook);
@@ -307,7 +303,7 @@ static int decode_format80(VqaContext *s, 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;
@@ -476,7 +472,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 */
@@ -491,11 +487,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;
                 }
@@ -516,11 +512,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];
             }
         }
     }
@@ -599,26 +595,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, "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;
@@ -632,9 +625,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;
 }
 
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index b5663b45dfc5b9c41975da284e2764159ccd7f7d..c9a908f29a9cf6d8979dd92d9d121cc617e6d5fe 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -1216,7 +1216,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
 
     /* get output buffer */
     frame->nb_samples = s->samples + 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;
     }
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index cdd285002df3c474b333477e6364f4f5f9e43f87..2774dc9877230b775643e212ca03078af6a5a76e 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -837,7 +837,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;
     }
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index 331a027133efbbcb0f907abf499872c046eb0502..cccdbd05541fced81ce0574207267cdaaf690161 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -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");
@@ -1264,8 +1264,9 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,
         save_bits(s, gb, remaining_bits(s, gb), 0);
     }
 
-    *(AVFrame *)data = s->frame;
     *got_frame_ptr   = s->frame.nb_samples > 0;
+    av_frame_move_ref(data, &s->frame);
+
     s->packet_offset = get_bits_count(gb) & 7;
 
     return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index a772e7371a8ff99ee67bb15edbdfce5e8e24129c..08c156189405c481d96f83ff40a64e15f060a7fa 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -1373,7 +1373,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;
diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index a82ee946a5c67f5872b0e4bcf0d21ee707c88f4b..ecd5b4ae1daeca06ac04355626003d079e186c61 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -1799,7 +1799,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;
     }
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index fc7a1b3ede6b75995ba1bdfe8f5996612a93532c..fccb1bb335fa08442e0c4085d1f1393aa49576e7 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -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++)
diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c
index c59ceb7f1d5d971a0ada8545e5b48e04fb203cd4..dd729388306bdcb957db914e7d156ddfc651ec1c 100644
--- a/libavcodec/wnv1.c
+++ b/libavcodec/wnv1.c
@@ -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;
@@ -82,11 +81,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;
@@ -130,7 +125,6 @@ static int decode_frame(AVCodecContext *avctx,
 
 
     *got_frame      = 1;
-    *(AVFrame*)data = l->pic;
     av_free(rbuf);
 
     return buf_size;
@@ -143,7 +137,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     l->avctx       = avctx;
     avctx->pix_fmt = AV_PIX_FMT_YUV422P;
-    avcodec_get_frame_defaults(&l->pic);
 
     code_vlc.table           = code_table;
     code_vlc.table_allocated = 1 << CODE_VLC_BITS;
@@ -154,24 +147,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"),
diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c
index 24ebcebfe0e7f7118d68aaffa29959f15570c270..d4e866f4ef1e3cb1581a5d89681a08035d179bfa 100644
--- a/libavcodec/ws-snd1.c
+++ b/libavcodec/ws-snd1.c
@@ -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;
     }
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index 219eedd92dccc7a6101faacc9526d5eed7dfb5bf..3caa6c0069e44aab0a84a69f99bcca9df0183507 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -53,7 +53,6 @@ typedef struct XanContext {
 
     AVCodecContext *avctx;
     AVFrame last_frame;
-    AVFrame current_frame;
 
     const unsigned char *buf;
     int size;
@@ -92,7 +91,6 @@ static av_cold int xan_decode_init(AVCodecContext *avctx)
         return AVERROR(ENOMEM);
     }
     avcodec_get_frame_defaults(&s->last_frame);
-    avcodec_get_frame_defaults(&s->current_frame);
 
     return 0;
 }
@@ -189,7 +187,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;
@@ -199,8 +197,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;
@@ -219,7 +217,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)
 {
@@ -234,11 +233,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;
@@ -270,7 +269,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;
@@ -398,12 +398,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;
             }
@@ -418,7 +418,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;
         }
@@ -518,6 +518,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;
@@ -586,33 +587,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;
@@ -622,11 +618,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);
diff --git a/libavcodec/xbmdec.c b/libavcodec/xbmdec.c
index 8632db7b0f06e5fe62f0752508444d1d5573afe4..51f88a238b5e6068b02781bd77ae84a69d85a6a4 100644
--- a/libavcodec/xbmdec.c
+++ b/libavcodec/xbmdec.c
@@ -27,9 +27,6 @@
 
 static av_cold int xbm_decode_init(AVCodecContext *avctx)
 {
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -48,7 +45,7 @@ static int convert(uint8_t x)
 static int xbm_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *p = avctx->coded_frame;
+    AVFrame *p = data;
     const uint8_t *end, *ptr = avpkt->data;
     uint8_t *dst;
     int ret, linesize, i, j;
@@ -78,11 +75,7 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data,
 
     avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
 
-    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)
         return ret;
 
     // goto start of image data
@@ -112,17 +105,12 @@ static int xbm_decode_frame(AVCodecContext *avctx, void *data,
     p->pict_type = AV_PICTURE_TYPE_I;
 
     *got_frame       = 1;
-    *(AVFrame *)data = *p;
 
     return avpkt->size;
 }
 
 static av_cold int xbm_decode_close(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
 
     return 0;
 }
diff --git a/libavcodec/xfacedec.c b/libavcodec/xfacedec.c
index a2f8636caee0c3375fe799c6f93afc699a7c31f5..2711b129f08ed38949b1d65ef0e272c43a9a9721 100644
--- a/libavcodec/xfacedec.c
+++ b/libavcodec/xfacedec.c
@@ -87,7 +87,6 @@ static void decode_block(BigInt *b, char *bitmap, int w, int h, int level)
 }
 
 typedef struct XFaceContext {
-    AVFrame frame;
     uint8_t bitmap[XFACE_PIXELS]; ///< image used internally for decoding
 } XFaceContext;
 
@@ -95,8 +94,6 @@ static av_cold int xface_decode_init(AVCodecContext *avctx)
 {
     XFaceContext *xface = avctx->priv_data;
 
-    avcodec_get_frame_defaults(&xface->frame);
-
     if (avctx->width || avctx->height) {
         if (avctx->width != XFACE_WIDTH || avctx->height != XFACE_HEIGHT) {
             av_log(avctx, AV_LOG_ERROR,
@@ -117,9 +114,6 @@ static av_cold int xface_decode_close(AVCodecContext *avctx)
 {
     XFaceContext *xface = avctx->priv_data;
 
-    if (xface->frame.data[0])
-        avctx->release_buffer(avctx, &xface->frame);
-
     return 0;
 }
 
@@ -133,13 +127,10 @@ static int xface_decode_frame(AVCodecContext *avctx,
     BigInt b = {0};
     char *buf;
     int64_t c;
+    AVFrame *frame = data;
 
-    if (xface->frame.data[0])
-        avctx->release_buffer(avctx, &xface->frame);
-    xface->frame.data[0] = NULL;
-    if ((ret = ff_get_buffer(avctx, &xface->frame)) < 0)
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
         return ret;
-    xface->frame.reference = 0;
 
     for (i = 0, k = 0; avpkt->data[i] && i < avpkt->size; i++) {
         c = avpkt->data[i];
@@ -173,7 +164,7 @@ static int xface_decode_frame(AVCodecContext *avctx,
     ff_xface_generate_face(xface->bitmap, xface->bitmap);
 
     /* convert image from 1=black 0=white bitmap to MONOWHITE */
-    buf = xface->frame.data[0];
+    buf = frame->data[0];
     for (i = 0, j = 0, k = 0, byte = 0; i < XFACE_PIXELS; i++) {
         byte += xface->bitmap[i];
         if (k == 7) {
@@ -185,12 +176,11 @@ static int xface_decode_frame(AVCodecContext *avctx,
         }
         if (j == XFACE_WIDTH/8) {
             j = 0;
-            buf += xface->frame.linesize[0];
+            buf += frame->linesize[0];
         }
     }
 
     *got_frame = 1;
-    *(AVFrame*)data = xface->frame;
 
     return avpkt->size;
 }
diff --git a/libavcodec/xl.c b/libavcodec/xl.c
index e2701d68d24900a86ab01aa6c25d7d7d52039e42..d5d774d5fea4c9cf3cc3d7a3b9460a1a4fd24de2 100644
--- a/libavcodec/xl.c
+++ b/libavcodec/xl.c
@@ -29,11 +29,6 @@
 #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,
@@ -47,8 +42,7 @@ 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;
@@ -65,20 +59,16 @@ static int 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;
     }
     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;
 
@@ -123,45 +113,28 @@ 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;
-
-    avcodec_get_frame_defaults(&a->pic);
     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"),
diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c
index 9923cdc34367021c919b750028f9aabca5398645..03f7f40a2c0117b37b3f574b5d7808b277986f07 100644
--- a/libavcodec/xwddec.c
+++ b/libavcodec/xwddec.c
@@ -26,19 +26,10 @@
 #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;
@@ -208,11 +199,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;
     }
@@ -246,27 +233,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"),
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index 9168327caf689c0a144cfb0c31db9ddfaefe7860..8df097bdeec5b3ced3a9ab87167cb5ab8ca8f99c 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -26,6 +26,7 @@
 #include "bytestream.h"
 #define BITSTREAM_READER_LE
 #include "get_bits.h"
+#include "internal.h"
 
 typedef struct XanContext {
     AVCodecContext *avctx;
@@ -391,11 +392,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
     int ftype;
     int ret;
 
-    s->pic.reference = 3;
-    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;
     }
@@ -416,8 +413,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;
 }
@@ -426,8 +425,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);
diff --git a/libavcodec/y41pdec.c b/libavcodec/y41pdec.c
index 655a426143bf22caf6a323ecbae8a130dfdcaa5c..e53fe16966824978a125e7c7b12786c96f89e7a7 100644
--- a/libavcodec/y41pdec.c
+++ b/libavcodec/y41pdec.c
@@ -32,34 +32,23 @@ static av_cold int y41p_decode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_WARNING, "y41p requires width to be divisible by 8.\n");
     }
 
-    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 y41p_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     uint8_t *src = avpkt->data;
     uint8_t *y, *u, *v;
     int i, j;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < 1.5 * 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);
     }
@@ -90,17 +79,12 @@ static int y41p_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
 
 static av_cold int y41p_decode_close(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
 
     return 0;
 }
diff --git a/libavcodec/yop.c b/libavcodec/yop.c
index 234868abbfd41f6e2396a532189f13d131f741fd..092e84caa89907de16fe0da5596e676b91591d19 100644
--- a/libavcodec/yop.c
+++ b/libavcodec/yop.c
@@ -30,7 +30,6 @@
 #include "internal.h"
 
 typedef struct YopDecContext {
-    AVFrame frame;
     AVCodecContext *avctx;
 
     int num_pal_colors;
@@ -97,7 +96,6 @@ static av_cold int yop_decode_init(AVCodecContext *avctx)
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    avcodec_get_frame_defaults(&s->frame);
     s->num_pal_colors = avctx->extradata[0];
     s->first_color[0] = avctx->extradata[1];
     s->first_color[1] = avctx->extradata[2];
@@ -112,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];
@@ -146,22 +136,22 @@ 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, "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 +178,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,20 +188,17 @@ 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;
@@ -221,7 +209,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
         return AVERROR_INVALIDDATA;
     }
     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) |
@@ -231,7 +219,7 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                                    (palette[i + firstcolor] >> 6) & 0x30303;
     }
 
-    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) {
@@ -243,24 +231,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;
 }
 
@@ -270,7 +255,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"),
 };
diff --git a/libavcodec/yuv4dec.c b/libavcodec/yuv4dec.c
index 8eb72c2a5ee9b4cfb6594a544488bee74bc7dd7d..95cacbe8198b28d0db0f5402e705cc272bbbabc4 100644
--- a/libavcodec/yuv4dec.c
+++ b/libavcodec/yuv4dec.c
@@ -27,35 +27,23 @@ static av_cold int yuv4_decode_init(AVCodecContext *avctx)
 {
     avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
-    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 yuv4_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame, AVPacket *avpkt)
 {
-    AVFrame *pic = avctx->coded_frame;
+    AVFrame *pic = data;
     const uint8_t *src = avpkt->data;
     uint8_t *y, *u, *v;
     int i, j;
 
-    if (pic->data[0])
-        avctx->release_buffer(avctx, pic);
-
     if (avpkt->size < 6 * (avctx->width + 1 >> 1) * (avctx->height + 1 >> 1)) {
         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);
     }
@@ -83,17 +71,12 @@ static int yuv4_decode_frame(AVCodecContext *avctx, void *data,
     }
 
     *got_frame = 1;
-    *(AVFrame *)data = *pic;
 
     return avpkt->size;
 }
 
 static av_cold int yuv4_decode_close(AVCodecContext *avctx)
 {
-    if (avctx->coded_frame->data[0])
-        avctx->release_buffer(avctx, avctx->coded_frame);
-
-    av_freep(&avctx->coded_frame);
 
     return 0;
 }
diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c
index 8122cca3b2745bd53b76cd69e7eade93a6045b63..e503aa768912c116d1c7778ee86bbd2d24191bbc 100644
--- a/libavcodec/zerocodec.c
+++ b/libavcodec/zerocodec.c
@@ -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;
 }
 
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index 47b3468fe7cf107751cac60473a622d72e213973..38529335b246abaaa21bd4d80668f3704683132d 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -54,7 +54,6 @@ enum ZmbvFormat {
  */
 typedef struct ZmbvContext {
     AVCodecContext *avctx;
-    AVFrame pic;
 
     int bpp;
     unsigned int decomp_size;
@@ -401,6 +400,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,9 +408,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
     int len = buf_size;
     int hi_ver, lo_ver, ret;
 
-    if (c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
-
     /* parse header */
     c->flags = buf[0];
     buf++; len--;
@@ -511,9 +508,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         return AVERROR_INVALIDDATA;
     }
 
-    c->pic.reference = 3;
-    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;
     }
@@ -538,12 +533,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);
     }
@@ -553,12 +548,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
         uint8_t *out, *src;
         int j;
 
-        out = c->pic.data[0];
+        out = frame->data[0];
         src = c->cur;
         switch (c->fmt) {
         case ZMBV_FMT_8BPP:
             for (j = 0; j < 256; j++)
-                AV_WN32(&c->pic.data[1][j * 4], 0xFFU << 24 | AV_RB24(&c->pal[j * 3]));
+                AV_WN32(&frame->data[1][j * 4], 0xFFU << 24 | AV_RB24(&c->pal[j * 3]));
         case ZMBV_FMT_15BPP:
         case ZMBV_FMT_16BPP:
 #ifdef ZMBV_ENABLE_24BPP
@@ -568,7 +563,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
             for (j = 0; j < c->height; j++) {
                 memcpy(out, src, c->stride);
                 src += c->stride;
-                out += c->pic.linesize[0];
+                out += frame->linesize[0];
             }
             break;
         default:
@@ -577,7 +572,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;
@@ -592,7 +586,6 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     c->width = avctx->width;
     c->height = avctx->height;
-    avcodec_get_frame_defaults(&c->pic);
 
     c->bpp = avctx->bits_per_coded_sample;
 
@@ -628,8 +621,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);