diff --git a/libavcodec/d3d12va_mpeg2.c b/libavcodec/d3d12va_mpeg2.c
index c2cf78104c..86a7d97b34 100644
--- a/libavcodec/d3d12va_mpeg2.c
+++ b/libavcodec/d3d12va_mpeg2.c
@@ -44,7 +44,7 @@ static int d3d12va_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint
 {
     const MpegEncContext      *s       = avctx->priv_data;
     D3D12VADecodeContext      *ctx     = D3D12VA_DECODE_CONTEXT(avctx);
-    D3D12DecodePictureContext *ctx_pic = s->cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic = s->cur_pic.ptr->hwaccel_picture_private;
 
     if (!ctx)
         return -1;
@@ -69,7 +69,7 @@ static int d3d12va_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint
 static int d3d12va_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     const MpegEncContext      *s       = avctx->priv_data;
-    D3D12DecodePictureContext *ctx_pic = s->cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic = s->cur_pic.ptr->hwaccel_picture_private;
 
     if (ctx_pic->slice_count >= MAX_SLICES) {
         return AVERROR(ERANGE);
@@ -88,7 +88,7 @@ static int d3d12va_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buff
 static int update_input_arguments(AVCodecContext *avctx, D3D12_VIDEO_DECODE_INPUT_STREAM_ARGUMENTS *input_args, ID3D12Resource *buffer)
 {
     const MpegEncContext      *s            = avctx->priv_data;
-    D3D12DecodePictureContext *ctx_pic      = s->cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic      = s->cur_pic.ptr->hwaccel_picture_private;
 
     const int is_field = s->picture_structure != PICT_FRAME;
     const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
@@ -137,12 +137,12 @@ static int d3d12va_mpeg2_end_frame(AVCodecContext *avctx)
 {
     int ret;
     MpegEncContext            *s       = avctx->priv_data;
-    D3D12DecodePictureContext *ctx_pic = s->cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic = s->cur_pic.ptr->hwaccel_picture_private;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
 
-    ret = ff_d3d12va_common_end_frame(avctx, s->cur_pic_ptr->f, &ctx_pic->pp, sizeof(ctx_pic->pp),
+    ret = ff_d3d12va_common_end_frame(avctx, s->cur_pic.ptr->f, &ctx_pic->pp, sizeof(ctx_pic->pp),
                                       &ctx_pic->qm, sizeof(ctx_pic->qm), update_input_arguments);
     if (!ret)
         ff_mpeg_draw_horiz_band(s, 0, avctx->height);
diff --git a/libavcodec/d3d12va_vc1.c b/libavcodec/d3d12va_vc1.c
index c4ac67ca04..dccc0fbffa 100644
--- a/libavcodec/d3d12va_vc1.c
+++ b/libavcodec/d3d12va_vc1.c
@@ -45,7 +45,7 @@ static int d3d12va_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_
 {
     const VC1Context          *v       = avctx->priv_data;
     D3D12VADecodeContext      *ctx     = D3D12VA_DECODE_CONTEXT(avctx);
-    D3D12DecodePictureContext *ctx_pic = v->s.cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic = v->s.cur_pic.ptr->hwaccel_picture_private;
 
     if (!ctx)
         return -1;
@@ -67,7 +67,7 @@ static int d3d12va_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_
 static int d3d12va_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     const VC1Context          *v       = avctx->priv_data;
-    D3D12DecodePictureContext *ctx_pic = v->s.cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic = v->s.cur_pic.ptr->hwaccel_picture_private;
 
     if (ctx_pic->slice_count >= MAX_SLICES) {
         return AVERROR(ERANGE);
@@ -93,7 +93,7 @@ static int update_input_arguments(AVCodecContext *avctx, D3D12_VIDEO_DECODE_INPU
 {
     const VC1Context *v                     = avctx->priv_data;
     const MpegEncContext      *s            = &v->s;
-    D3D12DecodePictureContext *ctx_pic      = s->cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic      = s->cur_pic.ptr->hwaccel_picture_private;
     D3D12_VIDEO_DECODE_FRAME_ARGUMENT *args = &input_args->FrameArguments[input_args->NumFrameArguments++];
 
     const unsigned mb_count = s->mb_width * (s->mb_height >> v->field_mode);
@@ -151,12 +151,12 @@ static int update_input_arguments(AVCodecContext *avctx, D3D12_VIDEO_DECODE_INPU
 static int d3d12va_vc1_end_frame(AVCodecContext *avctx)
 {
     const VC1Context          *v       = avctx->priv_data;
-    D3D12DecodePictureContext *ctx_pic = v->s.cur_pic_ptr->hwaccel_picture_private;
+    D3D12DecodePictureContext *ctx_pic = v->s.cur_pic.ptr->hwaccel_picture_private;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
 
-    return ff_d3d12va_common_end_frame(avctx, v->s.cur_pic_ptr->f,
+    return ff_d3d12va_common_end_frame(avctx, v->s.cur_pic.ptr->f,
                                        &ctx_pic->pp, sizeof(ctx_pic->pp),
                                        NULL, 0,
                                        update_input_arguments);
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
index d29a5bb538..4b58466878 100644
--- a/libavcodec/dxva2_mpeg2.c
+++ b/libavcodec/dxva2_mpeg2.c
@@ -45,17 +45,17 @@ void ff_dxva2_mpeg2_fill_picture_parameters(AVCodecContext *avctx,
                                     DXVA_PictureParameters *pp)
 {
     const struct MpegEncContext *s = avctx->priv_data;
-    const MPVPicture *current_picture = s->cur_pic_ptr;
+    const MPVPicture *current_picture = s->cur_pic.ptr;
     int is_field = s->picture_structure != PICT_FRAME;
 
     memset(pp, 0, sizeof(*pp));
     pp->wDeblockedPictureIndex       = 0;
     if (s->pict_type != AV_PICTURE_TYPE_I)
-        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(avctx, ctx, s->last_pic.f, 0);
+        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(avctx, ctx, s->last_pic.ptr->f, 0);
     else
         pp->wForwardRefPictureIndex  = 0xffff;
     if (s->pict_type == AV_PICTURE_TYPE_B)
-        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_pic.f, 0);
+        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_pic.ptr->f, 0);
     else
         pp->wBackwardRefPictureIndex = 0xffff;
     pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(avctx, ctx, current_picture->f, 1);
@@ -157,7 +157,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
     const struct MpegEncContext *s = avctx->priv_data;
     AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
     struct dxva2_picture_context *ctx_pic =
-        s->cur_pic_ptr->hwaccel_picture_private;
+        s->cur_pic.ptr->hwaccel_picture_private;
     const int is_field = s->picture_structure != PICT_FRAME;
     const unsigned mb_count = s->mb_width * (s->mb_height >> is_field);
     void     *dxva_data_ptr;
@@ -260,7 +260,7 @@ static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
     const struct MpegEncContext *s = avctx->priv_data;
     AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
     struct dxva2_picture_context *ctx_pic =
-        s->cur_pic_ptr->hwaccel_picture_private;
+        s->cur_pic.ptr->hwaccel_picture_private;
 
     if (!DXVA_CONTEXT_VALID(avctx, ctx))
         return -1;
@@ -280,7 +280,7 @@ static int dxva2_mpeg2_decode_slice(AVCodecContext *avctx,
 {
     const struct MpegEncContext *s = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic =
-        s->cur_pic_ptr->hwaccel_picture_private;
+        s->cur_pic.ptr->hwaccel_picture_private;
     unsigned position;
 
     if (ctx_pic->slice_count >= MAX_SLICES) {
@@ -302,12 +302,12 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
 {
     struct MpegEncContext *s = avctx->priv_data;
     struct dxva2_picture_context *ctx_pic =
-        s->cur_pic_ptr->hwaccel_picture_private;
+        s->cur_pic.ptr->hwaccel_picture_private;
     int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
-    ret = ff_dxva2_common_end_frame(avctx, s->cur_pic_ptr->f,
+    ret = ff_dxva2_common_end_frame(avctx, s->cur_pic.ptr->f,
                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
                                     &ctx_pic->qm, sizeof(ctx_pic->qm),
                                     commit_bitstream_and_slice_buffer);
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
index f536da1008..6dc9cd8b5a 100644
--- a/libavcodec/dxva2_vc1.c
+++ b/libavcodec/dxva2_vc1.c
@@ -46,7 +46,7 @@ void ff_dxva2_vc1_fill_picture_parameters(AVCodecContext *avctx,
 {
     const VC1Context *v = avctx->priv_data;
     const MpegEncContext *s = &v->s;
-    const MPVPicture *current_picture = s->cur_pic_ptr;
+    const MPVPicture *current_picture = s->cur_pic.ptr;
     int intcomp = 0;
 
     // determine if intensity compensation is needed
@@ -58,12 +58,12 @@ void ff_dxva2_vc1_fill_picture_parameters(AVCodecContext *avctx,
     }
 
     memset(pp, 0, sizeof(*pp));
-    if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type)
-        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->last_pic.f, 0);
+    if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type && s->last_pic.ptr)
+        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->last_pic.ptr->f, 0);
     else
         pp->wForwardRefPictureIndex = 0xffff;
-    if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)
-        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_pic.f, 0);
+    if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type && s->next_pic.ptr)
+        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_pic.ptr->f, 0);
     else
         pp->wBackwardRefPictureIndex = 0xffff;
     pp->wDecodedPictureIndex    =
@@ -191,7 +191,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
     const VC1Context *v = avctx->priv_data;
     AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
     const MpegEncContext *s = &v->s;
-    struct dxva2_picture_context *ctx_pic = s->cur_pic_ptr->hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = s->cur_pic.ptr->hwaccel_picture_private;
 
     static const uint8_t start_code[] = { 0, 0, 1, 0x0d };
     const unsigned start_code_size = avctx->codec_id == AV_CODEC_ID_VC1 ? sizeof(start_code) : 0;
@@ -317,7 +317,7 @@ static int dxva2_vc1_start_frame(AVCodecContext *avctx,
 {
     const VC1Context *v = avctx->priv_data;
     AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
-    struct dxva2_picture_context *ctx_pic = v->s.cur_pic_ptr->hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = v->s.cur_pic.ptr->hwaccel_picture_private;
 
     if (!DXVA_CONTEXT_VALID(avctx, ctx))
         return -1;
@@ -336,7 +336,7 @@ static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
                                   uint32_t size)
 {
     const VC1Context *v = avctx->priv_data;
-    const MPVPicture *current_picture = v->s.cur_pic_ptr;
+    const MPVPicture *current_picture = v->s.cur_pic.ptr;
     struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
     unsigned position;
 
@@ -364,13 +364,13 @@ static int dxva2_vc1_decode_slice(AVCodecContext *avctx,
 static int dxva2_vc1_end_frame(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
-    struct dxva2_picture_context *ctx_pic = v->s.cur_pic_ptr->hwaccel_picture_private;
+    struct dxva2_picture_context *ctx_pic = v->s.cur_pic.ptr->hwaccel_picture_private;
     int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
 
-    ret = ff_dxva2_common_end_frame(avctx, v->s.cur_pic_ptr->f,
+    ret = ff_dxva2_common_end_frame(avctx, v->s.cur_pic.ptr->f,
                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
                                     NULL, 0,
                                     commit_bitstream_and_slice_buffer);
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 00edd7a7c2..9acfd984ee 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -649,12 +649,11 @@ static int h261_decode_frame(AVCodecContext *avctx, AVFrame *pict,
     }
     ff_mpv_frame_end(s);
 
-    av_assert0(s->cur_pic.f->pict_type == s->cur_pic_ptr->f->pict_type);
-    av_assert0(s->cur_pic.f->pict_type == s->pict_type);
+    av_assert0(s->pict_type == s->cur_pic.ptr->f->pict_type);
 
-    if ((ret = av_frame_ref(pict, s->cur_pic_ptr->f)) < 0)
+    if ((ret = av_frame_ref(pict, s->cur_pic.ptr->f)) < 0)
         return ret;
-    ff_print_debug_info(s, s->cur_pic_ptr, pict);
+    ff_print_debug_info(s, s->cur_pic.ptr, pict);
 
     *got_frame = 1;
 
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 6ae634fceb..4fe4a30000 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -432,22 +432,22 @@ int ff_h263_decode_frame(AVCodecContext *avctx, AVFrame *pict,
     /* no supplementary picture */
     if (buf_size == 0) {
         /* special case for last picture */
-        if (s->low_delay == 0 && s->next_pic_ptr) {
-            if ((ret = av_frame_ref(pict, s->next_pic_ptr->f)) < 0)
+        if (s->low_delay == 0 && s->next_pic.ptr) {
+            if ((ret = av_frame_ref(pict, s->next_pic.ptr->f)) < 0)
                 return ret;
-            s->next_pic_ptr = NULL;
+            s->next_pic.ptr = NULL;
 
             *got_frame = 1;
-        } else if (s->skipped_last_frame && s->cur_pic_ptr) {
+        } else if (s->skipped_last_frame && s->cur_pic.ptr) {
             /* Output the last picture we decoded again if the stream ended with
              * an NVOP */
-            if ((ret = av_frame_ref(pict, s->cur_pic_ptr->f)) < 0)
+            if ((ret = av_frame_ref(pict, s->cur_pic.ptr->f)) < 0)
                 return ret;
             /* Copy props from the last input packet. Otherwise, props from the last
              * returned picture would be reused */
             if ((ret = ff_decode_frame_props(avctx, pict)) < 0)
                 return ret;
-            s->cur_pic_ptr = NULL;
+            s->cur_pic.ptr = NULL;
 
             *got_frame = 1;
         }
@@ -561,7 +561,7 @@ retry:
         s->gob_index = H263_GOB_HEIGHT(s->height);
 
     /* skip B-frames if we don't have reference frames */
-    if (!s->last_pic_ptr &&
+    if (!s->last_pic.ptr &&
         (s->pict_type == AV_PICTURE_TYPE_B || s->droppable))
         return get_consumed_bytes(s, buf_size);
     if ((avctx->skip_frame >= AVDISCARD_NONREF &&
@@ -647,21 +647,20 @@ frame_end:
     if (!s->divx_packed && avctx->hwaccel)
         ff_thread_finish_setup(avctx);
 
-    av_assert1(s->cur_pic.f->pict_type == s->cur_pic_ptr->f->pict_type);
-    av_assert1(s->cur_pic.f->pict_type == s->pict_type);
+    av_assert1(s->pict_type == s->cur_pic.ptr->f->pict_type);
     if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-        if ((ret = av_frame_ref(pict, s->cur_pic_ptr->f)) < 0)
+        if ((ret = av_frame_ref(pict, s->cur_pic.ptr->f)) < 0)
             return ret;
-        ff_print_debug_info(s, s->cur_pic_ptr, pict);
-        ff_mpv_export_qp_table(s, pict, s->cur_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG1);
-    } else if (s->last_pic_ptr) {
-        if ((ret = av_frame_ref(pict, s->last_pic_ptr->f)) < 0)
+        ff_print_debug_info(s, s->cur_pic.ptr, pict);
+        ff_mpv_export_qp_table(s, pict, s->cur_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG1);
+    } else if (s->last_pic.ptr) {
+        if ((ret = av_frame_ref(pict, s->last_pic.ptr->f)) < 0)
             return ret;
-        ff_print_debug_info(s, s->last_pic_ptr, pict);
-        ff_mpv_export_qp_table(s, pict, s->last_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG1);
+        ff_print_debug_info(s, s->last_pic.ptr, pict);
+        ff_mpv_export_qp_table(s, pict, s->last_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG1);
     }
 
-    if (s->last_pic_ptr || s->low_delay) {
+    if (s->last_pic.ptr || s->low_delay) {
         if (   pict->format == AV_PIX_FMT_YUV420P
             && (s->codec_tag == AV_RL32("GEOV") || s->codec_tag == AV_RL32("GEOX"))) {
             for (int p = 0; p < 3; p++) {
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index 2e4d74adc8..0809048362 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -750,12 +750,12 @@ static inline void set_one_direct_mv(MpegEncContext *s, const MPVPicture *p, int
 static int set_direct_mv(MpegEncContext *s)
 {
     const int mb_index = s->mb_x + s->mb_y * s->mb_stride;
-    const MPVPicture *p = &s->next_pic;
+    const MPVPicture *p = s->next_pic.ptr;
     int colocated_mb_type = p->mb_type[mb_index];
     int i;
 
     if (s->codec_tag == AV_RL32("U263") && p->f->pict_type == AV_PICTURE_TYPE_I) {
-        p = &s->last_pic;
+        p = s->last_pic.ptr;
         colocated_mb_type = p->mb_type[mb_index];
     }
 
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 6877b9ef4a..e3f2dd8af7 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -1292,7 +1292,7 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
             return ret;
 
         if (s->picture_structure != PICT_FRAME) {
-            s->cur_pic_ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST *
+            s->cur_pic.ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST *
                                         (s->picture_structure == PICT_TOP_FIELD);
 
             for (int i = 0; i < 3; i++) {
@@ -1309,19 +1309,19 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
         ff_mpeg_er_frame_start(s);
 
         /* first check if we must repeat the frame */
-        s->cur_pic_ptr->f->repeat_pict = 0;
+        s->cur_pic.ptr->f->repeat_pict = 0;
         if (s->repeat_first_field) {
             if (s->progressive_sequence) {
                 if (s->top_field_first)
-                    s->cur_pic_ptr->f->repeat_pict = 4;
+                    s->cur_pic.ptr->f->repeat_pict = 4;
                 else
-                    s->cur_pic_ptr->f->repeat_pict = 2;
+                    s->cur_pic.ptr->f->repeat_pict = 2;
             } else if (s->progressive_frame) {
-                s->cur_pic_ptr->f->repeat_pict = 1;
+                s->cur_pic.ptr->f->repeat_pict = 1;
             }
         }
 
-        ret = ff_frame_new_side_data(s->avctx, s->cur_pic_ptr->f,
+        ret = ff_frame_new_side_data(s->avctx, s->cur_pic.ptr->f,
                                      AV_FRAME_DATA_PANSCAN, sizeof(s1->pan_scan),
                                      &pan_scan);
         if (ret < 0)
@@ -1331,14 +1331,14 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
 
         if (s1->a53_buf_ref) {
             ret = ff_frame_new_side_data_from_buf(
-                s->avctx, s->cur_pic_ptr->f, AV_FRAME_DATA_A53_CC,
+                s->avctx, s->cur_pic.ptr->f, AV_FRAME_DATA_A53_CC,
                 &s1->a53_buf_ref, NULL);
             if (ret < 0)
                 return ret;
         }
 
         if (s1->has_stereo3d) {
-            AVStereo3D *stereo = av_stereo3d_create_side_data(s->cur_pic_ptr->f);
+            AVStereo3D *stereo = av_stereo3d_create_side_data(s->cur_pic.ptr->f);
             if (!stereo)
                 return AVERROR(ENOMEM);
 
@@ -1348,7 +1348,7 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
 
         if (s1->has_afd) {
             AVFrameSideData *sd;
-            ret = ff_frame_new_side_data(s->avctx, s->cur_pic_ptr->f,
+            ret = ff_frame_new_side_data(s->avctx, s->cur_pic.ptr->f,
                                          AV_FRAME_DATA_AFD, 1, &sd);
             if (ret < 0)
                 return ret;
@@ -1360,7 +1360,7 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
         if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
             ff_thread_finish_setup(avctx);
     } else { // second field
-        if (!s->cur_pic_ptr) {
+        if (!s->cur_pic.ptr) {
             av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");
             return AVERROR_INVALIDDATA;
         }
@@ -1377,10 +1377,10 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
             return ret;
 
         for (int i = 0; i < 3; i++) {
-            s->cur_pic.data[i] = s->cur_pic_ptr->f->data[i];
+            s->cur_pic.data[i] = s->cur_pic.ptr->f->data[i];
             if (s->picture_structure == PICT_BOTTOM_FIELD)
                 s->cur_pic.data[i] +=
-                    s->cur_pic_ptr->f->linesize[i];
+                    s->cur_pic.ptr->f->linesize[i];
         }
     }
 
@@ -1735,7 +1735,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
     Mpeg1Context *s1  = avctx->priv_data;
     MpegEncContext *s = &s1->mpeg_enc_ctx;
 
-    if (!s->context_initialized || !s->cur_pic_ptr)
+    if (!s->context_initialized || !s->cur_pic.ptr)
         return 0;
 
     if (s->avctx->hwaccel) {
@@ -1756,20 +1756,20 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict, int *got_output)
         ff_mpv_frame_end(s);
 
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            int ret = av_frame_ref(pict, s->cur_pic_ptr->f);
+            int ret = av_frame_ref(pict, s->cur_pic.ptr->f);
             if (ret < 0)
                 return ret;
-            ff_print_debug_info(s, s->cur_pic_ptr, pict);
-            ff_mpv_export_qp_table(s, pict, s->cur_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG2);
+            ff_print_debug_info(s, s->cur_pic.ptr, pict);
+            ff_mpv_export_qp_table(s, pict, s->cur_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG2);
             *got_output = 1;
         } else {
             /* latency of 1 frame for I- and P-frames */
-            if (s->last_pic_ptr && !s->last_pic_ptr->dummy) {
-                int ret = av_frame_ref(pict, s->last_pic_ptr->f);
+            if (s->last_pic.ptr && !s->last_pic.ptr->dummy) {
+                int ret = av_frame_ref(pict, s->last_pic.ptr->f);
                 if (ret < 0)
                     return ret;
-                ff_print_debug_info(s, s->last_pic_ptr, pict);
-                ff_mpv_export_qp_table(s, pict, s->last_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG2);
+                ff_print_debug_info(s, s->last_pic.ptr, pict);
+                ff_mpv_export_qp_table(s, pict, s->last_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG2);
                 *got_output = 1;
             }
         }
@@ -2405,7 +2405,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
                     return AVERROR_INVALIDDATA;
                 }
 
-                if (!s2->last_pic_ptr) {
+                if (!s2->last_pic.ptr) {
                     /* Skip B-frames if we do not have reference frames and
                      * GOP is not closed. */
                     if (s2->pict_type == AV_PICTURE_TYPE_B) {
@@ -2419,7 +2419,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
                 }
                 if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL))
                     s->sync = 1;
-                if (!s2->next_pic_ptr) {
+                if (!s2->next_pic.ptr) {
                     /* Skip P-frames if we do not have a reference frame or
                      * we have an invalid header. */
                     if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) {
@@ -2460,7 +2460,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
                     if ((ret = mpeg_field_start(s2, buf, buf_size)) < 0)
                         return ret;
                 }
-                if (!s2->cur_pic_ptr) {
+                if (!s2->cur_pic.ptr) {
                     av_log(avctx, AV_LOG_ERROR,
                            "current_picture not initialized\n");
                     return AVERROR_INVALIDDATA;
@@ -2524,12 +2524,12 @@ static int mpeg_decode_frame(AVCodecContext *avctx, AVFrame *picture,
 
     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_pic_ptr) {
-            int ret = av_frame_ref(picture, s2->next_pic_ptr->f);
+        if (s2->low_delay == 0 && s2->next_pic.ptr) {
+            int ret = av_frame_ref(picture, s2->next_pic.ptr->f);
             if (ret < 0)
                 return ret;
 
-            s2->next_pic_ptr = NULL;
+            s2->next_pic.ptr = NULL;
 
             *got_output = 1;
         }
@@ -2552,14 +2552,14 @@ static int mpeg_decode_frame(AVCodecContext *avctx, AVFrame *picture,
         }
         s->extradata_decoded = 1;
         if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) {
-            s2->cur_pic_ptr = NULL;
+            s2->cur_pic.ptr = NULL;
             return ret;
         }
     }
 
     ret = decode_chunks(avctx, picture, got_output, buf, buf_size);
     if (ret<0 || *got_output) {
-        s2->cur_pic_ptr = NULL;
+        s2->cur_pic.ptr = NULL;
 
         if (s->timecode_frame_start != -1 && *got_output) {
             char tcbuf[AV_TIMECODE_STR_SIZE];
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 326c0079df..ea193e007a 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -290,7 +290,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
     AVRational aspect_ratio = s->avctx->sample_aspect_ratio;
     int aspect_ratio_info;
 
-    if (!(s->cur_pic.f->flags & AV_FRAME_FLAG_KEY))
+    if (!(s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY))
         return;
 
     if (aspect_ratio.num == 0 || aspect_ratio.den == 0)
@@ -382,7 +382,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
         put_bits(&s->pb, 2, mpeg12->frame_rate_ext.num-1); // frame_rate_ext_n
         put_bits(&s->pb, 5, mpeg12->frame_rate_ext.den-1); // frame_rate_ext_d
 
-        side_data = av_frame_get_side_data(s->cur_pic_ptr->f, AV_FRAME_DATA_PANSCAN);
+        side_data = av_frame_get_side_data(s->cur_pic.ptr->f, AV_FRAME_DATA_PANSCAN);
         if (side_data) {
             const AVPanScan *pan_scan = (AVPanScan *)side_data->data;
             if (pan_scan->width && pan_scan->height) {
@@ -419,10 +419,10 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s)
     /* time code: we must convert from the real frame rate to a
      * fake MPEG frame rate in case of low frame rate */
     fps       = (framerate.num + framerate.den / 2) / framerate.den;
-    time_code = s->cur_pic_ptr->coded_picture_number +
+    time_code = s->cur_pic.ptr->coded_picture_number +
                 mpeg12->timecode_frame_start;
 
-    mpeg12->gop_picture_number = s->cur_pic_ptr->coded_picture_number;
+    mpeg12->gop_picture_number = s->cur_pic.ptr->coded_picture_number;
 
     av_assert0(mpeg12->drop_frame_timecode == !!(mpeg12->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
     if (mpeg12->drop_frame_timecode)
@@ -530,7 +530,7 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
         if (s->progressive_sequence)
             put_bits(&s->pb, 1, 0);             /* no repeat */
         else
-            put_bits(&s->pb, 1, !!(s->cur_pic_ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
+            put_bits(&s->pb, 1, !!(s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
         /* XXX: optimize the generation of this flag with entropy measures */
         s->frame_pred_frame_dct = s->progressive_sequence;
 
@@ -554,7 +554,7 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
         for (i = 0; i < sizeof(svcd_scan_offset_placeholder); i++)
             put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]);
     }
-    side_data = av_frame_get_side_data(s->cur_pic_ptr->f,
+    side_data = av_frame_get_side_data(s->cur_pic.ptr->f,
                                        AV_FRAME_DATA_STEREO3D);
     if (side_data) {
         const AVStereo3D *stereo = (AVStereo3D *)side_data->data;
@@ -594,7 +594,7 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s)
     }
 
     if (CONFIG_MPEG2VIDEO_ENCODER && mpeg12->a53_cc) {
-        side_data = av_frame_get_side_data(s->cur_pic_ptr->f,
+        side_data = av_frame_get_side_data(s->cur_pic.ptr->f,
             AV_FRAME_DATA_A53_CC);
         if (side_data) {
             if (side_data->size <= A53_MAX_CC_COUNT * 3 && side_data->size % 3 == 0) {
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index 1fda3053f0..b138c94df9 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -1807,7 +1807,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64])
                 s->last_mv[i][1][1] = 0;
             }
 
-            ff_thread_await_progress(&s->next_pic_ptr->tf, s->mb_y, 0);
+            ff_thread_await_progress(&s->next_pic.ptr->tf, s->mb_y, 0);
         }
 
         /* if we skipped it in the future P-frame than skip it now too */
@@ -2012,7 +2012,7 @@ 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_pic_ptr->tf,
+            ff_thread_await_progress(&s->next_pic.ptr->tf,
                                         (s->mb_x + delta >= s->mb_width)
                                         ? FFMIN(s->mb_y + 1, s->mb_height - 1)
                                         : s->mb_y, 0);
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index 6c743b8641..e853282b4b 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -891,7 +891,7 @@ static void mpeg4_encode_gop_header(MpegEncContext *s)
     put_bits(&s->pb, 16, 0);
     put_bits(&s->pb, 16, GOP_STARTCODE);
 
-    time = s->cur_pic_ptr->f->pts;
+    time = s->cur_pic.ptr->f->pts;
     if (s->reordered_input_picture[1])
         time = FFMIN(time, s->reordered_input_picture[1]->f->pts);
     time = time * s->avctx->time_base.num;
@@ -1103,7 +1103,7 @@ int ff_mpeg4_encode_picture_header(MpegEncContext *s)
     }
     put_bits(&s->pb, 3, 0);     /* intra dc VLC threshold */
     if (!s->progressive_sequence) {
-        put_bits(&s->pb, 1, !!(s->cur_pic_ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
+        put_bits(&s->pb, 1, !!(s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST));
         put_bits(&s->pb, 1, s->alternate_scan);
     }
     // FIXME sprite stuff
diff --git a/libavcodec/mpeg_er.c b/libavcodec/mpeg_er.c
index 21fe7d6f71..f9421ec91f 100644
--- a/libavcodec/mpeg_er.c
+++ b/libavcodec/mpeg_er.c
@@ -49,9 +49,9 @@ void ff_mpeg_er_frame_start(MpegEncContext *s)
 {
     ERContext *er = &s->er;
 
-    set_erpic(&er->cur_pic,  s->cur_pic_ptr);
-    set_erpic(&er->next_pic, s->next_pic_ptr);
-    set_erpic(&er->last_pic, s->last_pic_ptr);
+    set_erpic(&er->cur_pic,  s->cur_pic.ptr);
+    set_erpic(&er->next_pic, s->next_pic.ptr);
+    set_erpic(&er->last_pic, s->last_pic.ptr);
 
     er->pp_time           = s->pp_time;
     er->pb_time           = s->pb_time;
diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c
index 644097f2cb..84d9209c4c 100644
--- a/libavcodec/mpegpicture.c
+++ b/libavcodec/mpegpicture.c
@@ -45,6 +45,45 @@ static void av_noinline free_picture_tables(MPVPicture *pic)
     pic->mb_height = 0;
 }
 
+void ff_mpv_unref_picture(MPVWorkPicture *pic)
+{
+    if (pic->ptr)
+        ff_mpeg_unref_picture(pic->ptr);
+    memset(pic, 0, sizeof(*pic));
+}
+
+static void set_workpic_from_pic(MPVWorkPicture *wpic, const MPVPicture *pic)
+{
+    for (int i = 0; i < MPV_MAX_PLANES; i++) {
+        wpic->data[i]     = pic->f->data[i];
+        wpic->linesize[i] = pic->f->linesize[i];
+    }
+    wpic->qscale_table = pic->qscale_table;
+    wpic->mb_type      = pic->mb_type;
+    wpic->mbskip_table = pic->mbskip_table;
+
+    for (int i = 0; i < 2; i++) {
+        wpic->motion_val[i] = pic->motion_val[i];
+        wpic->ref_index[i]  = pic->ref_index[i];
+    }
+    wpic->reference  = pic->reference;
+}
+
+void ff_mpv_replace_picture(MPVWorkPicture *dst, const MPVWorkPicture *src)
+{
+    memcpy(dst, src, sizeof(*dst));
+}
+
+void ff_mpv_workpic_from_pic(MPVWorkPicture *wpic, MPVPicture *pic)
+{
+    if (!pic) {
+        memset(wpic, 0, sizeof(*wpic));
+        return;
+    }
+    wpic->ptr = pic;
+    set_workpic_from_pic(wpic, pic);
+}
+
 int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
                             ScratchpadContext *sc, int linesize)
 {
@@ -142,17 +181,13 @@ static int alloc_picture_tables(BufferPoolContext *pools, MPVPicture *pic,
     return 0;
 }
 
-int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, MPVPicture *pic,
+int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, MPVWorkPicture *wpic,
                                  MotionEstContext *me, ScratchpadContext *sc,
                                  BufferPoolContext *pools, int mb_height)
 {
+    MPVPicture *pic = wpic->ptr;
     int ret;
 
-    for (int i = 0; i < MPV_MAX_PLANES; i++) {
-        pic->data[i]     = pic->f->data[i];
-        pic->linesize[i] = pic->f->linesize[i];
-    }
-
     ret = ff_mpeg_framesize_alloc(avctx, me, sc,
                                   pic->f->linesize[0]);
     if (ret < 0)
@@ -169,6 +204,7 @@ int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, MPVPicture *pic,
         for (int i = 0; i < 2; i++)
             pic->motion_val[i] = pic->motion_val_base[i] + 4;
     }
+    set_workpic_from_pic(wpic, pic);
 
     return 0;
 fail:
@@ -189,12 +225,10 @@ void ff_mpeg_unref_picture(MPVPicture *pic)
 
     free_picture_tables(pic);
 
-    memset(pic->data,     0, sizeof(pic->data));
-    memset(pic->linesize, 0, sizeof(pic->linesize));
-
     pic->dummy         = 0;
 
     pic->field_picture = 0;
+    pic->interlaced    = 0;
     pic->b_frame_score = 0;
     pic->reference     = 0;
     pic->shared        = 0;
@@ -235,11 +269,6 @@ int ff_mpeg_ref_picture(MPVPicture *dst, MPVPicture *src)
     if (ret < 0)
         goto fail;
 
-    for (int i = 0; i < MPV_MAX_PLANES; i++) {
-        dst->data[i]     = src->data[i];
-        dst->linesize[i] = src->linesize[i];
-    }
-
     update_picture_tables(dst, src);
 
     ff_refstruct_replace(&dst->hwaccel_picture_private,
@@ -252,6 +281,7 @@ int ff_mpeg_ref_picture(MPVPicture *dst, MPVPicture *src)
     dst->shared                  = src->shared;
     dst->display_picture_number  = src->display_picture_number;
     dst->coded_picture_number    = src->coded_picture_number;
+    dst->interlaced              = src->interlaced;
 
     return 0;
 fail:
diff --git a/libavcodec/mpegpicture.h b/libavcodec/mpegpicture.h
index f0837b158a..774c5c8841 100644
--- a/libavcodec/mpegpicture.h
+++ b/libavcodec/mpegpicture.h
@@ -58,9 +58,6 @@ typedef struct MPVPicture {
     struct AVFrame *f;
     ThreadFrame tf;
 
-    uint8_t  *data[MPV_MAX_PLANES];
-    ptrdiff_t linesize[MPV_MAX_PLANES];
-
     int8_t *qscale_table_base;
     int8_t *qscale_table;
 
@@ -83,6 +80,7 @@ typedef struct MPVPicture {
 
     int dummy;                  ///< Picture is a dummy and should not be output
     int field_picture;          ///< whether or not the picture was encoded in separate fields
+    int interlaced;
 
     int b_frame_score;
 
@@ -93,10 +91,30 @@ typedef struct MPVPicture {
     int coded_picture_number;
 } MPVPicture;
 
+typedef struct MPVWorkPicture {
+    uint8_t  *data[MPV_MAX_PLANES];
+    ptrdiff_t linesize[MPV_MAX_PLANES];
+
+    MPVPicture *ptr;
+
+    int8_t *qscale_table;
+
+    int16_t (*motion_val[2])[2];
+
+    uint32_t *mb_type;          ///< types and macros are defined in mpegutils.h
+
+    uint8_t *mbskip_table;
+
+    int8_t *ref_index[2];
+
+    int reference;
+} MPVWorkPicture;
+
 /**
- * Allocate an MPVPicture's accessories, but not the AVFrame's buffer itself.
+ * Allocate an MPVPicture's accessories (but not the AVFrame's buffer itself)
+ * and set the MPVWorkPicture's fields.
  */
-int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, MPVPicture *pic,
+int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, MPVWorkPicture *pic,
                                  MotionEstContext *me, ScratchpadContext *sc,
                                  BufferPoolContext *pools, int mb_height);
 
@@ -113,6 +131,9 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
                             ScratchpadContext *sc, int linesize);
 
 int ff_mpeg_ref_picture(MPVPicture *dst, MPVPicture *src);
+void ff_mpv_unref_picture(MPVWorkPicture *pic);
+void ff_mpv_workpic_from_pic(MPVWorkPicture *wpic, MPVPicture *pic);
+void ff_mpv_replace_picture(MPVWorkPicture *dst, const MPVWorkPicture *src);
 void ff_mpeg_unref_picture(MPVPicture *picture);
 
 void ff_mpv_picture_free(MPVPicture *pic);
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 34f412a6b7..a4bea7273a 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -760,11 +760,6 @@ av_cold int ff_mpv_common_init(MpegEncContext *s)
             goto fail_nomem;
     }
 
-    if (!(s->next_pic.f = av_frame_alloc()) ||
-        !(s->last_pic.f = av_frame_alloc()) ||
-        !(s->cur_pic.f  = av_frame_alloc()))
-        goto fail_nomem;
-
     if ((ret = ff_mpv_init_context_frame(s)))
         goto fail;
 
@@ -837,15 +832,9 @@ void ff_mpv_common_end(MpegEncContext *s)
             ff_mpv_picture_free(&s->picture[i]);
     }
     av_freep(&s->picture);
-    ff_mpv_picture_free(&s->last_pic);
-    ff_mpv_picture_free(&s->cur_pic);
-    ff_mpv_picture_free(&s->next_pic);
 
     s->context_initialized      = 0;
     s->context_reinit           = 0;
-    s->last_pic_ptr =
-    s->next_pic_ptr =
-    s->cur_pic_ptr  = NULL;
     s->linesize = s->uvlinesize = 0;
 }
 
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index b476b54295..75120f2082 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -156,13 +156,13 @@ typedef struct MpegEncContext {
      * copy of the previous picture structure.
      * note, linesize & data, might not match the previous picture (for field pictures)
      */
-    MPVPicture last_pic;
+    MPVWorkPicture last_pic;
 
     /**
      * copy of the next picture structure.
      * note, linesize & data, might not match the next picture (for field pictures)
      */
-    MPVPicture next_pic;
+    MPVWorkPicture next_pic;
 
     /**
      * Reference to the source picture for encoding.
@@ -174,11 +174,8 @@ typedef struct MpegEncContext {
      * copy of the current picture structure.
      * note, linesize & data, might not match the current picture (for field pictures)
      */
-    MPVPicture cur_pic;
+    MPVWorkPicture cur_pic;
 
-    MPVPicture *last_pic_ptr;      ///< pointer to the previous picture.
-    MPVPicture *next_pic_ptr;      ///< pointer to the next picture (for bidir pred)
-    MPVPicture *cur_pic_ptr;       ///< pointer to the current picture
     int skipped_last_frame;
     int last_dc[3];                ///< last DC values for MPEG-1
     int16_t *dc_val_base;
diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c
index 97efd4fe81..71a6c0ad67 100644
--- a/libavcodec/mpegvideo_dec.c
+++ b/libavcodec/mpegvideo_dec.c
@@ -114,12 +114,10 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
 
 #define UPDATE_PICTURE(pic)\
 do {\
-    ff_mpeg_unref_picture(&s->pic);\
-    if (s1->pic.f && s1->pic.f->buf[0]) {\
-        ret = ff_mpeg_ref_picture(&s->pic, &s1->pic);\
-        if (ret < 0)\
-            return ret;\
-    }\
+    if (s->picture && s1->picture && s1->pic.ptr && s1->pic.ptr->f->buf[0]) {\
+        ff_mpv_workpic_from_pic(&s->pic, &s->picture[s1->pic.ptr - s1->picture]);\
+    } else\
+        ff_mpv_unref_picture(&s->pic);\
 } while (0)
 
     UPDATE_PICTURE(cur_pic);
@@ -129,15 +127,6 @@ do {\
     s->linesize   = s1->linesize;
     s->uvlinesize = s1->uvlinesize;
 
-#define REBASE_PICTURE(pic, new_ctx, old_ctx)                                 \
-    ((pic && pic >= old_ctx->picture &&                                       \
-      pic < old_ctx->picture + MAX_PICTURE_COUNT) ?                           \
-        &new_ctx->picture[pic - old_ctx->picture] : NULL)
-
-    s->last_pic_ptr = REBASE_PICTURE(s1->last_pic_ptr, s, s1);
-    s->cur_pic_ptr  = REBASE_PICTURE(s1->cur_pic_ptr,  s, s1);
-    s->next_pic_ptr = REBASE_PICTURE(s1->next_pic_ptr, s, s1);
-
     // Error/bug resilience
     s->workaround_bugs      = s1->workaround_bugs;
     s->padding_bug_score    = s1->padding_bug_score;
@@ -193,9 +182,9 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
 
     ff_mpv_free_context_frame(s);
 
-    s->last_pic_ptr =
-    s->next_pic_ptr =
-    s->cur_pic_ptr  = NULL;
+    s->last_pic.ptr =
+    s->next_pic.ptr =
+    s->cur_pic.ptr  = NULL;
 
     if ((s->width || s->height) &&
         (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0)
@@ -228,7 +217,7 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s)
     return err;
 }
 
-static int alloc_picture(MpegEncContext *s, MPVPicture **picp, int reference)
+static int alloc_picture(MpegEncContext *s, MPVWorkPicture *dst, int reference)
 {
     AVCodecContext *avctx = s->avctx;
     int idx = ff_find_unused_picture(s->avctx, s->picture, 0);
@@ -239,6 +228,7 @@ static int alloc_picture(MpegEncContext *s, MPVPicture **picp, int reference)
         return idx;
 
     pic = &s->picture[idx];
+    dst->ptr = pic;
 
     pic->tf.f = pic->f;
     pic->reference = reference;
@@ -271,36 +261,27 @@ static int alloc_picture(MpegEncContext *s, MPVPicture **picp, int reference)
     av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height ||
                FFALIGN(s->mb_height, 2) == s->buffer_pools.alloc_mb_height);
     av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride);
-    ret = ff_mpv_alloc_pic_accessories(s->avctx, pic, &s->me, &s->sc,
+    ret = ff_mpv_alloc_pic_accessories(s->avctx, dst, &s->me, &s->sc,
                                        &s->buffer_pools, s->mb_height);
     if (ret < 0)
         goto fail;
-    *picp = pic;
 
     return 0;
 fail:
-    ff_mpeg_unref_picture(pic);
+    ff_mpv_unref_picture(dst);
     return ret;
 }
 
-static int av_cold alloc_dummy_frame(MpegEncContext *s, MPVPicture **picp, MPVPicture *wpic)
+static int av_cold alloc_dummy_frame(MpegEncContext *s, MPVWorkPicture *dst)
 {
     MPVPicture *pic;
-    int ret = alloc_picture(s, &pic, 1);
+    int ret = alloc_picture(s, dst, 1);
     if (ret < 0)
         return ret;
 
+    pic = dst->ptr;
     pic->dummy = 1;
 
-    ff_mpeg_unref_picture(wpic);
-    ret = ff_mpeg_ref_picture(wpic, pic);
-    if (ret < 0) {
-        ff_mpeg_unref_picture(pic);
-        return ret;
-    }
-
-    *picp = pic;
-
     ff_thread_report_progress(&pic->tf, INT_MAX, 0);
     ff_thread_report_progress(&pic->tf, INT_MAX, 1);
 
@@ -330,9 +311,9 @@ int ff_mpv_alloc_dummy_frames(MpegEncContext *s)
     AVCodecContext *avctx = s->avctx;
     int ret;
 
-    if ((!s->last_pic_ptr || !s->last_pic_ptr->f->buf[0]) &&
+    if ((!s->last_pic.ptr || !s->last_pic.ptr->f->buf[0]) &&
         (s->pict_type != AV_PICTURE_TYPE_I)) {
-        if (s->pict_type == AV_PICTURE_TYPE_B && s->next_pic_ptr && s->next_pic_ptr->f->buf[0])
+        if (s->pict_type == AV_PICTURE_TYPE_B && s->next_pic.ptr && s->next_pic.ptr->f->buf[0])
             av_log(avctx, AV_LOG_DEBUG,
                    "allocating dummy last picture for B frame\n");
         else if (s->codec_id != AV_CODEC_ID_H261 /* H.261 has no keyframes */ &&
@@ -341,25 +322,25 @@ int ff_mpv_alloc_dummy_frames(MpegEncContext *s)
                    "warning: first frame is no keyframe\n");
 
         /* Allocate a dummy frame */
-        ret = alloc_dummy_frame(s, &s->last_pic_ptr, &s->last_pic);
+        ret = alloc_dummy_frame(s, &s->last_pic);
         if (ret < 0)
             return ret;
 
         if (!avctx->hwaccel) {
             int luma_val = s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263 ? 16 : 0x80;
-            color_frame(s->last_pic_ptr->f, luma_val);
+            color_frame(s->last_pic.ptr->f, luma_val);
         }
     }
-    if ((!s->next_pic_ptr || !s->next_pic_ptr->f->buf[0]) &&
+    if ((!s->next_pic.ptr || !s->next_pic.ptr->f->buf[0]) &&
         s->pict_type == AV_PICTURE_TYPE_B) {
         /* Allocate a dummy frame */
-        ret = alloc_dummy_frame(s, &s->next_pic_ptr, &s->next_pic);
+        ret = alloc_dummy_frame(s, &s->next_pic);
         if (ret < 0)
             return ret;
     }
 
-    av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_pic_ptr &&
-                                                 s->last_pic_ptr->f->buf[0]));
+    av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_pic.ptr &&
+                                                 s->last_pic.ptr->f->buf[0]));
 
     return 0;
 }
@@ -380,68 +361,49 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     }
 
     /* mark & release old frames */
-    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_pic_ptr &&
-        s->last_pic_ptr != s->next_pic_ptr &&
-        s->last_pic_ptr->f->buf[0]) {
-        ff_mpeg_unref_picture(s->last_pic_ptr);
+    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_pic.ptr &&
+        s->last_pic.ptr != s->next_pic.ptr &&
+        s->last_pic.ptr->f->buf[0]) {
+        ff_mpeg_unref_picture(s->last_pic.ptr);
     }
 
     /* release non reference/forgotten frames */
     for (int i = 0; i < MAX_PICTURE_COUNT; i++) {
         if (!s->picture[i].reference ||
-            (&s->picture[i] != s->last_pic_ptr &&
-             &s->picture[i] != s->next_pic_ptr)) {
+            (&s->picture[i] != s->last_pic.ptr &&
+             &s->picture[i] != s->next_pic.ptr)) {
             ff_mpeg_unref_picture(&s->picture[i]);
         }
     }
 
-    ff_mpeg_unref_picture(&s->cur_pic);
-    ff_mpeg_unref_picture(&s->last_pic);
-    ff_mpeg_unref_picture(&s->next_pic);
-
-    ret = alloc_picture(s, &s->cur_pic_ptr,
+    ret = alloc_picture(s, &s->cur_pic,
                         s->pict_type != AV_PICTURE_TYPE_B && !s->droppable);
     if (ret < 0)
         return ret;
 
-    s->cur_pic_ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!s->top_field_first;
-    s->cur_pic_ptr->f->flags |= AV_FRAME_FLAG_INTERLACED *
+    s->cur_pic.ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!s->top_field_first;
+    s->cur_pic.ptr->f->flags |= AV_FRAME_FLAG_INTERLACED *
                                 (!s->progressive_frame && !s->progressive_sequence);
-    s->cur_pic_ptr->field_picture = s->picture_structure != PICT_FRAME;
+    s->cur_pic.ptr->field_picture = s->picture_structure != PICT_FRAME;
 
-    s->cur_pic_ptr->f->pict_type = s->pict_type;
+    s->cur_pic.ptr->f->pict_type = s->pict_type;
     if (s->pict_type == AV_PICTURE_TYPE_I)
-        s->cur_pic_ptr->f->flags |= AV_FRAME_FLAG_KEY;
+        s->cur_pic.ptr->f->flags |= AV_FRAME_FLAG_KEY;
     else
-        s->cur_pic_ptr->f->flags &= ~AV_FRAME_FLAG_KEY;
-
-    if ((ret = ff_mpeg_ref_picture(&s->cur_pic, s->cur_pic_ptr)) < 0)
-        return ret;
+        s->cur_pic.ptr->f->flags &= ~AV_FRAME_FLAG_KEY;
 
     if (s->pict_type != AV_PICTURE_TYPE_B) {
-        s->last_pic_ptr = s->next_pic_ptr;
+        ff_mpv_workpic_from_pic(&s->last_pic, s->next_pic.ptr);
         if (!s->droppable)
-            s->next_pic_ptr = s->cur_pic_ptr;
+            ff_mpv_workpic_from_pic(&s->next_pic, s->cur_pic.ptr);
     }
     ff_dlog(s->avctx, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n",
-            s->last_pic_ptr, s->next_pic_ptr, s->cur_pic_ptr,
-            s->last_pic_ptr ? s->last_pic_ptr->f->data[0] : NULL,
-            s->next_pic_ptr ? s->next_pic_ptr->f->data[0] : NULL,
-            s->cur_pic_ptr  ? s->cur_pic_ptr->f->data[0]  : NULL,
+            (void*)s->last_pic.ptr, (void*)s->next_pic.ptr, (void*)s->cur_pic.ptr,
+            s->last_pic.ptr ? s->last_pic.ptr->f->data[0] : NULL,
+            s->next_pic.ptr ? s->next_pic.ptr->f->data[0] : NULL,
+            s->cur_pic.ptr  ? s->cur_pic.ptr->f->data[0]  : NULL,
             s->pict_type, s->droppable);
 
-    if (s->last_pic_ptr) {
-        if (s->last_pic_ptr->f->buf[0] &&
-            (ret = ff_mpeg_ref_picture(&s->last_pic,
-                                       s->last_pic_ptr)) < 0)
-            return ret;
-    }
-    if (s->next_pic_ptr) {
-        if (s->next_pic_ptr->f->buf[0] &&
-            (ret = ff_mpeg_ref_picture(&s->next_pic, s->next_pic_ptr)) < 0)
-            return ret;
-    }
-
     ret = ff_mpv_alloc_dummy_frames(s);
     if (ret < 0)
         return ret;
@@ -461,7 +423,7 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx)
     }
 
     if (s->avctx->debug & FF_DEBUG_NOMC)
-        color_frame(s->cur_pic_ptr->f, 0x80);
+        color_frame(s->cur_pic.ptr->f, 0x80);
 
     return 0;
 }
@@ -472,7 +434,7 @@ void ff_mpv_frame_end(MpegEncContext *s)
     emms_c();
 
     if (s->cur_pic.reference)
-        ff_thread_report_progress(&s->cur_pic_ptr->tf, INT_MAX, 0);
+        ff_thread_report_progress(&s->cur_pic.ptr->tf, INT_MAX, 0);
 }
 
 void ff_print_debug_info(const MpegEncContext *s, const MPVPicture *p, AVFrame *pict)
@@ -515,8 +477,8 @@ int ff_mpv_export_qp_table(const MpegEncContext *s, AVFrame *f,
 
 void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h)
 {
-    ff_draw_horiz_band(s->avctx, s->cur_pic_ptr->f,
-                       s->last_pic_ptr ? s->last_pic_ptr->f : NULL,
+    ff_draw_horiz_band(s->avctx, s->cur_pic.ptr->f,
+                       s->last_pic.ptr ? s->last_pic.ptr->f : NULL,
                        y, h, s->picture_structure,
                        s->first_field, s->low_delay);
 }
@@ -530,11 +492,10 @@ void ff_mpeg_flush(AVCodecContext *avctx)
 
     for (int i = 0; i < MAX_PICTURE_COUNT; i++)
         ff_mpeg_unref_picture(&s->picture[i]);
-    s->cur_pic_ptr = s->last_pic_ptr = s->next_pic_ptr = NULL;
 
-    ff_mpeg_unref_picture(&s->cur_pic);
-    ff_mpeg_unref_picture(&s->last_pic);
-    ff_mpeg_unref_picture(&s->next_pic);
+    ff_mpv_unref_picture(&s->cur_pic);
+    ff_mpv_unref_picture(&s->last_pic);
+    ff_mpv_unref_picture(&s->next_pic);
 
     s->mb_x = s->mb_y = 0;
 
@@ -545,7 +506,7 @@ void ff_mpeg_flush(AVCodecContext *avctx)
 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->cur_pic_ptr->tf, s->mb_y, 0);
+        ff_thread_report_progress(&s->cur_pic.ptr->tf, s->mb_y, 0);
 }
 
 
@@ -864,7 +825,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s,
         } else {
             if (s->picture_structure != s->field_select[dir][0] + 1 &&
                 s->pict_type != AV_PICTURE_TYPE_B && !s->first_field) {
-                ref_picture = s->cur_pic_ptr->f->data;
+                ref_picture = s->cur_pic.ptr->f->data;
             }
             mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
                                0, 0, s->field_select[dir][0],
@@ -881,7 +842,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s,
                 s->pict_type == AV_PICTURE_TYPE_B || s->first_field) {
                 ref2picture = ref_picture;
             } else {
-                ref2picture = s->cur_pic_ptr->f->data;
+                ref2picture = s->cur_pic.ptr->f->data;
             }
 
             mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
@@ -922,7 +883,7 @@ static inline void MPV_motion_lowres(MpegEncContext *s,
                 // opposite parity is always in the same
                 // frame if this is second field
                 if (!s->first_field) {
-                    ref_picture = s->cur_pic_ptr->f->data;
+                    ref_picture = s->cur_pic.ptr->f->data;
                 }
             }
         }
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index ad4502f3db..066dca9ac5 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1356,7 +1356,7 @@ static int estimate_best_b_count(MpegEncContext *s)
 
     for (i = 0; i < s->max_b_frames + 2; i++) {
         const MPVPicture *pre_input_ptr = i ? s->input_picture[i - 1] :
-                                           s->next_pic_ptr;
+                                           s->next_pic.ptr;
 
         if (pre_input_ptr) {
             const uint8_t *data[4];
@@ -1484,8 +1484,8 @@ static int select_input_picture(MpegEncContext *s)
     if (!s->reordered_input_picture[0] && s->input_picture[0]) {
         if (s->frame_skip_threshold || s->frame_skip_factor) {
             if (s->picture_in_gop_number < s->gop_size &&
-                s->next_pic_ptr &&
-                skip_check(s, s->input_picture[0], s->next_pic_ptr)) {
+                s->next_pic.ptr &&
+                skip_check(s, s->input_picture[0], s->next_pic.ptr)) {
                 // FIXME check that the gop check above is +-1 correct
                 ff_mpeg_unref_picture(s->input_picture[0]);
 
@@ -1496,7 +1496,7 @@ static int select_input_picture(MpegEncContext *s)
         }
 
         if (/*s->picture_in_gop_number >= s->gop_size ||*/
-            !s->next_pic_ptr || s->intra_only) {
+            !s->next_pic.ptr || s->intra_only) {
             s->reordered_input_picture[0] = s->input_picture[0];
             s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I;
             s->reordered_input_picture[0]->coded_picture_number =
@@ -1624,17 +1624,17 @@ no_output_pic:
                     s->new_pic->data[i] += INPLACE_OFFSET;
             }
         }
-        s->cur_pic_ptr = s->reordered_input_picture[0];
+        s->cur_pic.ptr = s->reordered_input_picture[0];
         av_assert1(s->mb_width  == s->buffer_pools.alloc_mb_width);
         av_assert1(s->mb_height == s->buffer_pools.alloc_mb_height);
         av_assert1(s->mb_stride == s->buffer_pools.alloc_mb_stride);
-        ret = ff_mpv_alloc_pic_accessories(s->avctx, s->cur_pic_ptr, &s->me,
+        ret = ff_mpv_alloc_pic_accessories(s->avctx, &s->cur_pic, &s->me,
                                            &s->sc, &s->buffer_pools, s->mb_height);
         if (ret < 0) {
-            ff_mpeg_unref_picture(s->cur_pic_ptr);
+            ff_mpv_unref_picture(&s->cur_pic);
             return ret;
         }
-        s->picture_number = s->cur_pic_ptr->display_picture_number;
+        s->picture_number = s->cur_pic.ptr->display_picture_number;
 
     }
     return 0;
@@ -1674,7 +1674,7 @@ static void frame_end(MpegEncContext *s)
     emms_c();
 
     s->last_pict_type                 = s->pict_type;
-    s->last_lambda_for [s->pict_type] = s->cur_pic_ptr->f->quality;
+    s->last_lambda_for [s->pict_type] = s->cur_pic.ptr->f->quality;
     if (s->pict_type!= AV_PICTURE_TYPE_B)
         s->last_non_b_pict_type = s->pict_type;
 }
@@ -1700,47 +1700,26 @@ static void update_noise_reduction(MpegEncContext *s)
     }
 }
 
-static int frame_start(MpegEncContext *s)
+static void frame_start(MpegEncContext *s)
 {
-    int ret;
-
     /* mark & release old frames */
-    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_pic_ptr &&
-        s->last_pic_ptr != s->next_pic_ptr &&
-        s->last_pic_ptr->f->buf[0]) {
-        ff_mpeg_unref_picture(s->last_pic_ptr);
+    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_pic.ptr &&
+        s->last_pic.ptr != s->next_pic.ptr &&
+        s->last_pic.ptr->f->buf[0]) {
+        ff_mpv_unref_picture(&s->last_pic);
     }
 
-    s->cur_pic_ptr->f->pict_type = s->pict_type;
-
-    ff_mpeg_unref_picture(&s->cur_pic);
-    if ((ret = ff_mpeg_ref_picture(&s->cur_pic, s->cur_pic_ptr)) < 0)
-        return ret;
+    s->cur_pic.ptr->f->pict_type = s->pict_type;
 
     if (s->pict_type != AV_PICTURE_TYPE_B) {
-        s->last_pic_ptr = s->next_pic_ptr;
-        s->next_pic_ptr = s->cur_pic_ptr;
-    }
-
-    if (s->last_pic_ptr) {
-        ff_mpeg_unref_picture(&s->last_pic);
-        if (s->last_pic_ptr->f->buf[0] &&
-            (ret = ff_mpeg_ref_picture(&s->last_pic, s->last_pic_ptr)) < 0)
-            return ret;
-    }
-    if (s->next_pic_ptr) {
-        ff_mpeg_unref_picture(&s->next_pic);
-        if (s->next_pic_ptr->f->buf[0] &&
-            (ret = ff_mpeg_ref_picture(&s->next_pic, s->next_pic_ptr)) < 0)
-            return ret;
+        ff_mpv_replace_picture(&s->last_pic, &s->next_pic);
+        ff_mpv_replace_picture(&s->next_pic, &s->cur_pic);
     }
 
     if (s->dct_error_sum) {
         av_assert2(s->noise_reduction && s->encoding);
         update_noise_reduction(s);
     }
-
-    return 0;
 }
 
 int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
@@ -1793,9 +1772,7 @@ int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
 
         s->pict_type = s->new_pic->pict_type;
         //emms_c();
-        ret = frame_start(s);
-        if (ret < 0)
-            return ret;
+        frame_start(s);
 vbv_retry:
         ret = encode_picture(s);
         if (growing_buffer) {
@@ -1858,7 +1835,7 @@ vbv_retry:
 
         for (int i = 0; i < MPV_MAX_PLANES; i++)
             avctx->error[i] += s->encoding_error[i];
-        ff_side_data_set_encoder_stats(pkt, s->cur_pic.f->quality,
+        ff_side_data_set_encoder_stats(pkt, s->cur_pic.ptr->f->quality,
                                        s->encoding_error,
                                        (avctx->flags&AV_CODEC_FLAG_PSNR) ? MPV_MAX_PLANES : 0,
                                        s->pict_type);
@@ -1952,10 +1929,10 @@ vbv_retry:
         }
         s->total_bits     += s->frame_bits;
 
-        pkt->pts = s->cur_pic.f->pts;
-        pkt->duration = s->cur_pic.f->duration;
+        pkt->pts = s->cur_pic.ptr->f->pts;
+        pkt->duration = s->cur_pic.ptr->f->duration;
         if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) {
-            if (!s->cur_pic.coded_picture_number)
+            if (!s->cur_pic.ptr->coded_picture_number)
                 pkt->dts = pkt->pts - s->dts_delta;
             else
                 pkt->dts = s->reordered_pts;
@@ -1965,12 +1942,12 @@ vbv_retry:
 
         // the no-delay case is handled in generic code
         if (avctx->codec->capabilities & AV_CODEC_CAP_DELAY) {
-            ret = ff_encode_reordered_opaque(avctx, pkt, s->cur_pic.f);
+            ret = ff_encode_reordered_opaque(avctx, pkt, s->cur_pic.ptr->f);
             if (ret < 0)
                 return ret;
         }
 
-        if (s->cur_pic.f->flags & AV_FRAME_FLAG_KEY)
+        if (s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY)
             pkt->flags |= AV_PKT_FLAG_KEY;
         if (s->mb_info)
             av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);
@@ -3516,14 +3493,12 @@ static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src)
 
 static int estimate_qp(MpegEncContext *s, int dry_run){
     if (s->next_lambda){
-        s->cur_pic_ptr->f->quality =
-        s->cur_pic.f->quality = s->next_lambda;
+        s->cur_pic.ptr->f->quality = s->next_lambda;
         if(!dry_run) s->next_lambda= 0;
     } else if (!s->fixed_qscale) {
         int quality = ff_rate_estimate_qscale(s, dry_run);
-        s->cur_pic_ptr->f->quality =
-        s->cur_pic.f->quality = quality;
-        if (s->cur_pic.f->quality < 0)
+        s->cur_pic.ptr->f->quality = quality;
+        if (s->cur_pic.ptr->f->quality < 0)
             return -1;
     }
 
@@ -3546,15 +3521,15 @@ static int estimate_qp(MpegEncContext *s, int dry_run){
         s->lambda= s->lambda_table[0];
         //FIXME broken
     }else
-        s->lambda = s->cur_pic.f->quality;
+        s->lambda = s->cur_pic.ptr->f->quality;
     update_qscale(s);
     return 0;
 }
 
 /* must be called before writing the header */
 static void set_frame_distances(MpegEncContext * s){
-    av_assert1(s->cur_pic_ptr->f->pts != AV_NOPTS_VALUE);
-    s->time = s->cur_pic_ptr->f->pts * s->avctx->time_base.num;
+    av_assert1(s->cur_pic.ptr->f->pts != AV_NOPTS_VALUE);
+    s->time = s->cur_pic.ptr->f->pts * s->avctx->time_base.num;
 
     if(s->pict_type==AV_PICTURE_TYPE_B){
         s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
@@ -3585,7 +3560,7 @@ static int encode_picture(MpegEncContext *s)
 
     s->me.scene_change_score=0;
 
-//    s->lambda= s->cur_pic_ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
+//    s->lambda= s->cur_pic.ptr->quality; //FIXME qscale / ... stuff for ME rate distortion
 
     if(s->pict_type==AV_PICTURE_TYPE_I){
         if(s->msmpeg4_version >= 3) s->no_rounding=1;
@@ -3773,18 +3748,14 @@ static int encode_picture(MpegEncContext *s)
         }
     }
 
-    //FIXME var duplication
     if (s->pict_type == AV_PICTURE_TYPE_I) {
-        s->cur_pic_ptr->f->flags |= AV_FRAME_FLAG_KEY; //FIXME pic_ptr
-        s->cur_pic.f->flags |= AV_FRAME_FLAG_KEY;
+        s->cur_pic.ptr->f->flags |= AV_FRAME_FLAG_KEY;
     } else {
-        s->cur_pic_ptr->f->flags &= ~AV_FRAME_FLAG_KEY; //FIXME pic_ptr
-        s->cur_pic.f->flags &= ~AV_FRAME_FLAG_KEY;
+        s->cur_pic.ptr->f->flags &= ~AV_FRAME_FLAG_KEY;
     }
-    s->cur_pic_ptr->f->pict_type =
-    s->cur_pic.f->pict_type = s->pict_type;
+    s->cur_pic.ptr->f->pict_type = s->pict_type;
 
-    if (s->cur_pic.f->flags & AV_FRAME_FLAG_KEY)
+    if (s->cur_pic.ptr->f->flags & AV_FRAME_FLAG_KEY)
         s->picture_in_gop_number=0;
 
     s->mb_x = s->mb_y = 0;
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index a757357316..88c0566558 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -514,7 +514,7 @@ static inline void apply_obmc(MpegEncContext *s,
                               op_pixels_func (*pix_op)[4])
 {
     LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
-    const MPVPicture *cur_frame = &s->cur_pic;
+    const MPVWorkPicture *cur_frame = &s->cur_pic;
     int mb_x = s->mb_x;
     int mb_y = s->mb_y;
     const int xy         = mb_x + mb_y * s->mb_stride;
@@ -749,7 +749,7 @@ static av_always_inline void mpv_motion_internal(MpegEncContext *s,
             av_assert2(s->out_format == FMT_MPEG1);
             if (s->picture_structure != s->field_select[dir][0] + 1 &&
                 s->pict_type != AV_PICTURE_TYPE_B && !s->first_field) {
-                ref_picture = s->cur_pic_ptr->f->data;
+                ref_picture = s->cur_pic.ptr->f->data;
             }
 
             mpeg_motion(s, dest_y, dest_cb, dest_cr,
@@ -767,7 +767,7 @@ static av_always_inline void mpv_motion_internal(MpegEncContext *s,
                     s->pict_type == AV_PICTURE_TYPE_B || s->first_field) {
                     ref2picture = ref_picture;
                 } else {
-                    ref2picture = s->cur_pic_ptr->f->data;
+                    ref2picture = s->cur_pic.ptr->f->data;
                 }
 
                 mpeg_motion(s, dest_y, dest_cb, dest_cr,
@@ -807,7 +807,7 @@ static av_always_inline void mpv_motion_internal(MpegEncContext *s,
                     /* opposite parity is always in the same frame if this is
                      * second field */
                     if (!s->first_field)
-                        ref_picture = s->cur_pic_ptr->f->data;
+                        ref_picture = s->cur_pic.ptr->f->data;
                 }
             }
             break;
diff --git a/libavcodec/mpv_reconstruct_mb_template.c b/libavcodec/mpv_reconstruct_mb_template.c
index 70dab76f73..0b7a6a6d31 100644
--- a/libavcodec/mpv_reconstruct_mb_template.c
+++ b/libavcodec/mpv_reconstruct_mb_template.c
@@ -124,11 +124,11 @@ void mpv_reconstruct_mb_internal(MpegEncContext *s, int16_t block[12][64],
             if (HAVE_THREADS && is_mpeg12 != DEFINITELY_MPEG12 &&
                 s->avctx->active_thread_type & FF_THREAD_FRAME) {
                 if (s->mv_dir & MV_DIR_FORWARD) {
-                    ff_thread_await_progress(&s->last_pic_ptr->tf,
+                    ff_thread_await_progress(&s->last_pic.ptr->tf,
                                              lowest_referenced_row(s, 0), 0);
                 }
                 if (s->mv_dir & MV_DIR_BACKWARD) {
-                    ff_thread_await_progress(&s->next_pic_ptr->tf,
+                    ff_thread_await_progress(&s->next_pic.ptr->tf,
                                              lowest_referenced_row(s, 1), 0);
                 }
             }
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index 05319436b6..1888053eb2 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -382,7 +382,7 @@ static int decode_wmv9(AVCodecContext *avctx, const uint8_t *buf, int buf_size,
     MSS12Context *c   = &ctx->c;
     VC1Context *v     = avctx->priv_data;
     MpegEncContext *s = &v->s;
-    MPVPicture *f;
+    MPVWorkPicture *f;
     int ret;
 
     ff_mpeg_flush(avctx);
diff --git a/libavcodec/nvdec_mpeg12.c b/libavcodec/nvdec_mpeg12.c
index 76ef81ea4d..99b2b14f1f 100644
--- a/libavcodec/nvdec_mpeg12.c
+++ b/libavcodec/nvdec_mpeg12.c
@@ -39,7 +39,7 @@ static int nvdec_mpeg12_start_frame(AVCodecContext *avctx, const uint8_t *buffer
     CUVIDMPEG2PICPARAMS *ppc = &pp->CodecSpecific.mpeg2;
     FrameDecodeData *fdd;
     NVDECFrame *cf;
-    AVFrame *cur_frame = s->cur_pic.f;
+    AVFrame *cur_frame = s->cur_pic.ptr->f;
 
     int ret, i;
 
@@ -64,8 +64,8 @@ static int nvdec_mpeg12_start_frame(AVCodecContext *avctx, const uint8_t *buffer
                              s->pict_type == AV_PICTURE_TYPE_P,
 
         .CodecSpecific.mpeg2 = {
-            .ForwardRefIdx     = ff_nvdec_get_ref_idx(s->last_pic.f),
-            .BackwardRefIdx    = ff_nvdec_get_ref_idx(s->next_pic.f),
+            .ForwardRefIdx     = ff_nvdec_get_ref_idx(s->last_pic.ptr ? s->last_pic.ptr->f : NULL),
+            .BackwardRefIdx    = ff_nvdec_get_ref_idx(s->next_pic.ptr ? s->next_pic.ptr->f : NULL),
 
             .picture_coding_type        = s->pict_type,
             .full_pel_forward_vector    = s->full_pel[0],
diff --git a/libavcodec/nvdec_mpeg4.c b/libavcodec/nvdec_mpeg4.c
index 468002d1c5..80da11b5b1 100644
--- a/libavcodec/nvdec_mpeg4.c
+++ b/libavcodec/nvdec_mpeg4.c
@@ -38,7 +38,7 @@ static int nvdec_mpeg4_start_frame(AVCodecContext *avctx, const uint8_t *buffer,
     CUVIDMPEG4PICPARAMS *ppc = &pp->CodecSpecific.mpeg4;
     FrameDecodeData *fdd;
     NVDECFrame *cf;
-    AVFrame *cur_frame = s->cur_pic.f;
+    AVFrame *cur_frame = s->cur_pic.ptr->f;
 
     int ret, i;
 
@@ -60,8 +60,8 @@ static int nvdec_mpeg4_start_frame(AVCodecContext *avctx, const uint8_t *buffer,
                              s->pict_type == AV_PICTURE_TYPE_S,
 
         .CodecSpecific.mpeg4 = {
-            .ForwardRefIdx                = ff_nvdec_get_ref_idx(s->last_pic.f),
-            .BackwardRefIdx               = ff_nvdec_get_ref_idx(s->next_pic.f),
+            .ForwardRefIdx                = ff_nvdec_get_ref_idx(s->last_pic.ptr ? s->last_pic.ptr->f : NULL),
+            .BackwardRefIdx               = ff_nvdec_get_ref_idx(s->next_pic.ptr ? s->next_pic.ptr->f : NULL),
 
             .video_object_layer_width     = s->width,
             .video_object_layer_height    = s->height,
diff --git a/libavcodec/nvdec_vc1.c b/libavcodec/nvdec_vc1.c
index 40cd18a8e7..0668863cb4 100644
--- a/libavcodec/nvdec_vc1.c
+++ b/libavcodec/nvdec_vc1.c
@@ -38,7 +38,7 @@ static int nvdec_vc1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
     CUVIDPICPARAMS     *pp = &ctx->pic_params;
     FrameDecodeData *fdd;
     NVDECFrame *cf;
-    AVFrame *cur_frame = s->cur_pic.f;
+    AVFrame *cur_frame = s->cur_pic.ptr->f;
 
     int ret;
 
@@ -63,8 +63,8 @@ static int nvdec_vc1_start_frame(AVCodecContext *avctx, const uint8_t *buffer, u
                              s->pict_type == AV_PICTURE_TYPE_P,
 
         .CodecSpecific.vc1 = {
-            .ForwardRefIdx     = ff_nvdec_get_ref_idx(s->last_pic.f),
-            .BackwardRefIdx    = ff_nvdec_get_ref_idx(s->next_pic.f),
+            .ForwardRefIdx     = ff_nvdec_get_ref_idx(s->last_pic.ptr ? s->last_pic.ptr->f : NULL),
+            .BackwardRefIdx    = ff_nvdec_get_ref_idx(s->next_pic.ptr ? s->next_pic.ptr->f : NULL),
             .FrameWidth        = cur_frame->width,
             .FrameHeight       = cur_frame->height,
 
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 3397fffcab..193e9452bd 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -40,10 +40,10 @@ void ff_write_pass1_stats(MpegEncContext *s)
     snprintf(s->avctx->stats_out, 256,
              "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d "
              "fcode:%d bcode:%d mc-var:%"PRId64" var:%"PRId64" icount:%d skipcount:%d hbits:%d;\n",
-             s->cur_pic_ptr->display_picture_number,
-             s->cur_pic_ptr->coded_picture_number,
+             s->cur_pic.ptr->display_picture_number,
+             s->cur_pic.ptr->coded_picture_number,
              s->pict_type,
-             s->cur_pic.f->quality,
+             s->cur_pic.ptr->f->quality,
              s->i_tex_bits,
              s->p_tex_bits,
              s->mv_bits,
@@ -933,9 +933,9 @@ float ff_rate_estimate_qscale(MpegEncContext *s, int dry_run)
          * here instead of reordering but the reordering is simpler for now
          * until H.264 B-pyramid must be handled. */
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay)
-            dts_pic = s->cur_pic_ptr;
+            dts_pic = s->cur_pic.ptr;
         else
-            dts_pic = s->last_pic_ptr;
+            dts_pic = s->last_pic.ptr;
 
         if (!dts_pic || dts_pic->f->pts == AV_NOPTS_VALUE)
             wanted_bits = (uint64_t)(s->bit_rate * (double)picture_number / fps);
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index aea42dd314..201e7ed6d0 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -170,7 +170,7 @@ static int rv20_decode_picture_header(RVDecContext *rv, int whole_size)
         av_log(s->avctx, AV_LOG_ERROR, "low delay B\n");
         return -1;
     }
-    if (!s->last_pic_ptr && s->pict_type == AV_PICTURE_TYPE_B) {
+    if (!s->last_pic.ptr && s->pict_type == AV_PICTURE_TYPE_B) {
         av_log(s->avctx, AV_LOG_ERROR, "early B-frame\n");
         return AVERROR_INVALIDDATA;
     }
@@ -458,9 +458,9 @@ static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf,
     if (whole_size < s->mb_width * s->mb_height / 8)
         return AVERROR_INVALIDDATA;
 
-    if ((s->mb_x == 0 && s->mb_y == 0) || !s->cur_pic_ptr) {
+    if ((s->mb_x == 0 && s->mb_y == 0) || !s->cur_pic.ptr) {
         // FIXME write parser so we always have complete frames?
-        if (s->cur_pic_ptr) {
+        if (s->cur_pic.ptr) {
             ff_er_frame_end(&s->er, NULL);
             ff_mpv_frame_end(s);
             s->mb_x = s->mb_y = s->resync_mb_x = s->resync_mb_y = 0;
@@ -469,7 +469,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf,
             return ret;
         ff_mpeg_er_frame_start(s);
     } else {
-        if (s->cur_pic_ptr->f->pict_type != s->pict_type) {
+        if (s->cur_pic.ptr->f->pict_type != s->pict_type) {
             av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
             return AVERROR_INVALIDDATA;
         }
@@ -632,28 +632,28 @@ static int rv10_decode_frame(AVCodecContext *avctx, AVFrame *pict,
             i++;
     }
 
-    if (s->cur_pic_ptr && s->mb_y >= s->mb_height) {
+    if (s->cur_pic.ptr && s->mb_y >= s->mb_height) {
         ff_er_frame_end(&s->er, NULL);
         ff_mpv_frame_end(s);
 
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            if ((ret = av_frame_ref(pict, s->cur_pic_ptr->f)) < 0)
+            if ((ret = av_frame_ref(pict, s->cur_pic.ptr->f)) < 0)
                 return ret;
-            ff_print_debug_info(s, s->cur_pic_ptr, pict);
-            ff_mpv_export_qp_table(s, pict, s->cur_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG1);
-        } else if (s->last_pic_ptr) {
-            if ((ret = av_frame_ref(pict, s->last_pic_ptr->f)) < 0)
+            ff_print_debug_info(s, s->cur_pic.ptr, pict);
+            ff_mpv_export_qp_table(s, pict, s->cur_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG1);
+        } else if (s->last_pic.ptr) {
+            if ((ret = av_frame_ref(pict, s->last_pic.ptr->f)) < 0)
                 return ret;
-            ff_print_debug_info(s, s->last_pic_ptr, pict);
-            ff_mpv_export_qp_table(s, pict,s->last_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG1);
+            ff_print_debug_info(s, s->last_pic.ptr, pict);
+            ff_mpv_export_qp_table(s, pict,s->last_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG1);
         }
 
-        if (s->last_pic_ptr || s->low_delay) {
+        if (s->last_pic.ptr || s->low_delay) {
             *got_frame = 1;
         }
 
         // so we can detect if frame_end was not called (find some nicer solution...)
-        s->cur_pic_ptr = NULL;
+        s->cur_pic.ptr = NULL;
     }
 
     return avpkt->size;
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index 284de14e8c..d935c261b5 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -565,7 +565,7 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
     int has_A = 0, has_B = 0, has_C = 0;
     int mx, my;
     int i, j;
-    MPVPicture *cur_pic = &s->cur_pic;
+    MPVWorkPicture *cur_pic = &s->cur_pic;
     const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
     int type = cur_pic->mb_type[mb_pos];
 
@@ -719,7 +719,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);
-        const ThreadFrame *f = dir ? &s->next_pic_ptr->tf : &s->last_pic_ptr->tf;
+        const ThreadFrame *f = dir ? &s->next_pic.ptr->tf : &s->last_pic.ptr->tf;
         ff_thread_await_progress(f, mb_row, 0);
     }
 
@@ -899,7 +899,7 @@ 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_pic_ptr->tf, FFMAX(0, s->mb_y-1), 0);
+            ff_thread_await_progress(&s->next_pic.ptr->tf, FFMAX(0, s->mb_y-1), 0);
 
         next_bt = s->next_pic.mb_type[s->mb_x + s->mb_y * s->mb_stride];
         if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
@@ -1483,7 +1483,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->cur_pic_ptr->tf,
+                ff_thread_report_progress(&s->cur_pic.ptr->tf,
                                           s->mb_y - 2, 0);
 
         }
@@ -1581,19 +1581,19 @@ static int finish_frame(AVCodecContext *avctx, AVFrame *pict)
     s->mb_num_left = 0;
 
     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
-        ff_thread_report_progress(&s->cur_pic_ptr->tf, INT_MAX, 0);
+        ff_thread_report_progress(&s->cur_pic.ptr->tf, INT_MAX, 0);
 
     if (s->pict_type == AV_PICTURE_TYPE_B) {
-        if ((ret = av_frame_ref(pict, s->cur_pic_ptr->f)) < 0)
+        if ((ret = av_frame_ref(pict, s->cur_pic.ptr->f)) < 0)
             return ret;
-        ff_print_debug_info(s, s->cur_pic_ptr, pict);
-        ff_mpv_export_qp_table(s, pict, s->cur_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG1);
+        ff_print_debug_info(s, s->cur_pic.ptr, pict);
+        ff_mpv_export_qp_table(s, pict, s->cur_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG1);
         got_picture = 1;
-    } else if (s->last_pic_ptr) {
-        if ((ret = av_frame_ref(pict, s->last_pic_ptr->f)) < 0)
+    } else if (s->last_pic.ptr) {
+        if ((ret = av_frame_ref(pict, s->last_pic.ptr->f)) < 0)
             return ret;
-        ff_print_debug_info(s, s->last_pic_ptr, pict);
-        ff_mpv_export_qp_table(s, pict, s->last_pic_ptr, FF_MPV_QSCALE_TYPE_MPEG1);
+        ff_print_debug_info(s, s->last_pic.ptr, pict);
+        ff_mpv_export_qp_table(s, pict, s->last_pic.ptr, FF_MPV_QSCALE_TYPE_MPEG1);
         got_picture = 1;
     }
 
@@ -1628,10 +1628,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict,
     /* no supplementary picture */
     if (buf_size == 0) {
         /* special case for last picture */
-        if (s->next_pic_ptr) {
-            if ((ret = av_frame_ref(pict, s->next_pic_ptr->f)) < 0)
+        if (s->next_pic.ptr) {
+            if ((ret = av_frame_ref(pict, s->next_pic.ptr->f)) < 0)
                 return ret;
-            s->next_pic_ptr = NULL;
+            s->next_pic.ptr = NULL;
 
             *got_picture_ptr = 1;
         }
@@ -1654,7 +1654,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict,
         av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
         return AVERROR_INVALIDDATA;
     }
-    if ((!s->last_pic_ptr || !s->last_pic_ptr->f->data[0]) &&
+    if ((!s->last_pic.ptr || !s->last_pic.ptr->f->data[0]) &&
         si.type == AV_PICTURE_TYPE_B) {
         av_log(avctx, AV_LOG_ERROR, "Invalid decoder state: B-frame without "
                "reference data.\n");
@@ -1667,7 +1667,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict,
 
     /* first slice */
     if (si.start == 0) {
-        if (s->mb_num_left > 0 && s->cur_pic_ptr) {
+        if (s->mb_num_left > 0 && s->cur_pic.ptr) {
             av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n",
                    s->mb_num_left);
             if (!s->context_reinit)
@@ -1792,7 +1792,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict,
             break;
     }
 
-    if (s->cur_pic_ptr) {
+    if (s->cur_pic.ptr) {
         if (last) {
             if(r->loop_filter)
                 r->loop_filter(r, s->mb_height - 1);
@@ -1809,7 +1809,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict,
             ff_er_frame_end(&s->er, NULL);
             ff_mpv_frame_end(s);
             s->mb_num_left = 0;
-            ff_thread_report_progress(&s->cur_pic_ptr->tf, INT_MAX, 0);
+            ff_thread_report_progress(&s->cur_pic.ptr->tf, INT_MAX, 0);
             return AVERROR_INVALIDDATA;
         }
     }
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 49e7a10321..e7a870d783 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -62,6 +62,7 @@ typedef struct SnowEncContext {
 
     MECmpContext mecc;
     MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
+    MPVPicture cur_pic, last_pic;
 #define ME_CACHE_SIZE 1024
     unsigned me_cache[ME_CACHE_SIZE];
     unsigned me_cache_generation;
@@ -1834,9 +1835,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
     if (ret < 0)
         return ret;
 
-    mpv->cur_pic_ptr    = &mpv->cur_pic;
-    mpv->cur_pic.f      = s->current_picture;
-    mpv->cur_pic.f->pts = pict->pts;
+    mpv->cur_pic.ptr         = &enc->cur_pic;
+    mpv->cur_pic.ptr->f      = s->current_picture;
+    mpv->cur_pic.ptr->f->pts = pict->pts;
     if(pic->pict_type == AV_PICTURE_TYPE_P){
         int block_width = (width +15)>>4;
         int block_height= (height+15)>>4;
@@ -1846,9 +1847,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
         av_assert0(s->last_picture[0]->data[0]);
 
         mpv->avctx = s->avctx;
-        mpv->last_pic.f   = s->last_picture[0];
+        mpv->last_pic.ptr    = &enc->last_pic;
+        mpv->last_pic.ptr->f = s->last_picture[0];
         mpv-> new_pic     = s->input_picture;
-        mpv->last_pic_ptr = &mpv->last_pic;
         mpv->linesize   = stride;
         mpv->uvlinesize = s->current_picture->linesize[1];
         mpv->width      = width;
@@ -2043,9 +2044,9 @@ redo_frame:
     mpv->frame_bits = 8 * (s->c.bytestream - s->c.bytestream_start);
     mpv->p_tex_bits = mpv->frame_bits - mpv->misc_bits - mpv->mv_bits;
     mpv->total_bits += 8*(s->c.bytestream - s->c.bytestream_start);
-    mpv->cur_pic.display_picture_number =
-    mpv->cur_pic.coded_picture_number   = avctx->frame_num;
-    mpv->cur_pic.f->quality             = pic->quality;
+    enc->cur_pic.display_picture_number =
+    enc->cur_pic.coded_picture_number   = avctx->frame_num;
+    enc->cur_pic.f->quality             = pic->quality;
     if (enc->pass1_rc)
         if (ff_rate_estimate_qscale(mpv, 0) < 0)
             return -1;
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index c75ab1800a..9631fa243d 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -60,6 +60,7 @@ typedef struct SVQ1EncContext {
      * else, the idea is to make the motion estimation eventually independent
      * of MpegEncContext, so this will be removed then. */
     MpegEncContext m;
+    MPVPicture cur_pic, last_pic;
     AVCodecContext *avctx;
     MECmpContext mecc;
     HpelDSPContext hdsp;
@@ -326,8 +327,8 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane,
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
         s->m.avctx                         = s->avctx;
-        s->m.cur_pic_ptr                   = &s->m.cur_pic;
-        s->m.last_pic_ptr              = &s->m.last_pic;
+        s->m.cur_pic.ptr                   = &s->cur_pic;
+        s->m.last_pic.ptr                  = &s->last_pic;
         s->m.last_pic.data[0]        = ref_plane;
         s->m.linesize                      =
         s->m.last_pic.linesize[0]    =
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index 389540fd0c..328a2f7db3 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -42,12 +42,12 @@ static inline int mpeg2_get_is_frame_start(const MpegEncContext *s)
 static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
 {
     const MpegEncContext *s = avctx->priv_data;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     VAPictureParameterBufferMPEG2 pic_param;
     VAIQMatrixBufferMPEG2 iq_matrix;
     int i, err;
 
-    pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic_ptr->f);
+    pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic.ptr->f);
 
     pic_param = (VAPictureParameterBufferMPEG2) {
         .horizontal_size                 = s->width,
@@ -73,10 +73,10 @@ static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_
 
     switch (s->pict_type) {
     case AV_PICTURE_TYPE_B:
-        pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.f);
+        pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.ptr->f);
         // fall-through
     case AV_PICTURE_TYPE_P:
-        pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_pic.f);
+        pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_pic.ptr->f);
         break;
     }
 
@@ -115,7 +115,7 @@ fail:
 static int vaapi_mpeg2_end_frame(AVCodecContext *avctx)
 {
     MpegEncContext     *s   = avctx->priv_data;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     int ret;
 
     ret = ff_vaapi_decode_issue(avctx, pic);
@@ -131,7 +131,7 @@ fail:
 static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     const MpegEncContext *s = avctx->priv_data;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     VASliceParameterBufferMPEG2 slice_param;
     GetBitContext gb;
     uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset;
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index e227bee113..76602c544a 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -49,11 +49,11 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_
 {
     Mpeg4DecContext *ctx = avctx->priv_data;
     MpegEncContext *s = &ctx->m;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     VAPictureParameterBufferMPEG4 pic_param;
     int i, err;
 
-    pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic_ptr->f);
+    pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic.ptr->f);
 
     pic_param = (VAPictureParameterBufferMPEG4) {
         .vop_width                        = s->width,
@@ -78,7 +78,7 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_
         .vop_fields.bits = {
             .vop_coding_type              = s->pict_type - AV_PICTURE_TYPE_I,
             .backward_reference_vop_coding_type =
-                s->pict_type == AV_PICTURE_TYPE_B ? s->next_pic.f->pict_type - AV_PICTURE_TYPE_I : 0,
+                s->pict_type == AV_PICTURE_TYPE_B ? s->next_pic.ptr->f->pict_type - AV_PICTURE_TYPE_I : 0,
             .vop_rounding_type            = s->no_rounding,
             .intra_dc_vlc_thr             = mpeg4_get_intra_dc_vlc_thr(ctx),
             .top_field_first              = s->top_field_first,
@@ -100,9 +100,9 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_
     }
 
     if (s->pict_type == AV_PICTURE_TYPE_B)
-        pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.f);
+        pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.ptr->f);
     if (s->pict_type != AV_PICTURE_TYPE_I)
-        pic_param.forward_reference_picture  = ff_vaapi_get_surface_id(s->last_pic.f);
+        pic_param.forward_reference_picture  = ff_vaapi_get_surface_id(s->last_pic.ptr->f);
 
     err = ff_vaapi_decode_make_param_buffer(avctx, pic,
                                             VAPictureParameterBufferType,
@@ -139,7 +139,7 @@ fail:
 static int vaapi_mpeg4_end_frame(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     int ret;
 
     ret = ff_vaapi_decode_issue(avctx, pic);
@@ -155,7 +155,7 @@ fail:
 static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext *s = avctx->priv_data;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     VASliceParameterBufferMPEG4 slice_param;
     int err;
 
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index ef914cf4b2..8aedad7828 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -253,11 +253,11 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t
 {
     const VC1Context *v = avctx->priv_data;
     const MpegEncContext *s = &v->s;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     VAPictureParameterBufferVC1 pic_param;
     int err;
 
-    pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic_ptr->f);
+    pic->output_surface = ff_vaapi_get_surface_id(s->cur_pic.ptr->f);
 
     pic_param = (VAPictureParameterBufferVC1) {
         .forward_reference_picture         = VA_INVALID_ID,
@@ -374,10 +374,12 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t
 
     switch (s->pict_type) {
     case AV_PICTURE_TYPE_B:
-        pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.f);
+        if (s->next_pic.ptr)
+            pic_param.backward_reference_picture = ff_vaapi_get_surface_id(s->next_pic.ptr->f);
         // fall-through
     case AV_PICTURE_TYPE_P:
-        pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_pic.f);
+        if (s->last_pic.ptr)
+            pic_param.forward_reference_picture = ff_vaapi_get_surface_id(s->last_pic.ptr->f);
         break;
     }
 
@@ -450,7 +452,7 @@ static int vaapi_vc1_end_frame(AVCodecContext *avctx)
 {
     VC1Context *v = avctx->priv_data;
     MpegEncContext *s = &v->s;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     int ret;
 
     ret = ff_vaapi_decode_issue(avctx, pic);
@@ -465,7 +467,7 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
 {
     const VC1Context *v = avctx->priv_data;
     const MpegEncContext *s = &v->s;
-    VAAPIDecodePicture *pic = s->cur_pic_ptr->hwaccel_picture_private;
+    VAAPIDecodePicture *pic = s->cur_pic.ptr->hwaccel_picture_private;
     VASliceParameterBufferVC1 slice_param;
     int mb_height;
     int err;
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index 643232653c..987e77fcc7 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -856,7 +856,7 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
             v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
         else
             v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
-        v->s.cur_pic_ptr->f->pict_type = v->s.pict_type;
+        v->s.cur_pic.ptr->f->pict_type = v->s.pict_type;
         if (!v->pic_header_flag)
             goto parse_common_info;
     }
diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c
index 9cb9fd27bf..b880f978d1 100644
--- a/libavcodec/vc1_block.c
+++ b/libavcodec/vc1_block.c
@@ -59,9 +59,9 @@ static inline void init_block_index(VC1Context *v)
     MpegEncContext *s = &v->s;
     ff_init_block_index(s);
     if (v->field_mode && !(v->second_field ^ v->tff)) {
-        s->dest[0] += s->cur_pic_ptr->f->linesize[0];
-        s->dest[1] += s->cur_pic_ptr->f->linesize[1];
-        s->dest[2] += s->cur_pic_ptr->f->linesize[2];
+        s->dest[0] += s->cur_pic.ptr->f->linesize[0];
+        s->dest[1] += s->cur_pic.ptr->f->linesize[1];
+        s->dest[2] += s->cur_pic.ptr->f->linesize[2];
     }
 }
 
@@ -2106,7 +2106,7 @@ static int vc1_decode_b_mb_intfi(VC1Context *v)
             if (bmvtype == BMV_TYPE_DIRECT) {
                 dmv_x[0] = dmv_y[0] = pred_flag[0] = 0;
                 dmv_x[1] = dmv_y[1] = pred_flag[0] = 0;
-                if (!s->next_pic_ptr->field_picture) {
+                if (!s->next_pic.ptr->field_picture) {
                     av_log(s->avctx, AV_LOG_ERROR, "Mixed field/frame direct mode not supported\n");
                     return AVERROR_INVALIDDATA;
                 }
@@ -2272,7 +2272,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v)
             direct = v->direct_mb_plane[mb_pos];
 
         if (direct) {
-            if (s->next_pic_ptr->field_picture)
+            if (s->next_pic.ptr->field_picture)
                 av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
             s->mv[0][0][0] = s->cur_pic.motion_val[0][s->block_index[0]][0] = scale_mv(s->next_pic.motion_val[1][s->block_index[0]][0], v->bfraction, 0, s->quarter_sample);
             s->mv[0][0][1] = s->cur_pic.motion_val[0][s->block_index[0]][1] = scale_mv(s->next_pic.motion_val[1][s->block_index[0]][1], v->bfraction, 0, s->quarter_sample);
@@ -2969,7 +2969,7 @@ void ff_vc1_decode_blocks(VC1Context *v)
 
     v->s.esc3_level_length = 0;
     if (v->x8_type) {
-        ff_intrax8_decode_picture(&v->x8, &v->s.cur_pic,
+        ff_intrax8_decode_picture(&v->x8, v->s.cur_pic.ptr,
                                   &v->s.gb, &v->s.mb_x, &v->s.mb_y,
                                   2 * v->pq + v->halfpq, v->pq * !v->pquantizer,
                                   v->s.loop_filter, v->s.low_delay);
diff --git a/libavcodec/vc1_mc.c b/libavcodec/vc1_mc.c
index ad41004e66..de9774ac2b 100644
--- a/libavcodec/vc1_mc.c
+++ b/libavcodec/vc1_mc.c
@@ -187,8 +187,8 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir)
         !v->s.last_pic.data[0])
         return;
 
-    linesize   = s->cur_pic_ptr->f->linesize[0];
-    uvlinesize = s->cur_pic_ptr->f->linesize[1];
+    linesize   = s->cur_pic.ptr->f->linesize[0];
+    uvlinesize = s->cur_pic.ptr->f->linesize[1];
 
     mx = s->mv[dir][0][0];
     my = s->mv[dir][0][1];
@@ -233,7 +233,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir)
             luty  = v->last_luty;
             lutuv = v->last_lutuv;
             use_ic = v->last_use_ic;
-            interlace = !!(s->last_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+            interlace = s->last_pic.ptr->interlaced;
         }
     } else {
         srcY = s->next_pic.data[0];
@@ -242,7 +242,7 @@ void ff_vc1_mc_1mv(VC1Context *v, int dir)
         luty  = v->next_luty;
         lutuv = v->next_lutuv;
         use_ic = v->next_use_ic;
-        interlace = !!(s->next_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+        interlace = s->next_pic.ptr->interlaced;
     }
 
     if (!srcY || !srcU) {
@@ -467,7 +467,7 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
         !v->s.last_pic.data[0])
         return;
 
-    linesize = s->cur_pic_ptr->f->linesize[0];
+    linesize = s->cur_pic.ptr->f->linesize[0];
 
     mx = s->mv[dir][n][0];
     my = s->mv[dir][n][1];
@@ -482,13 +482,13 @@ void ff_vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)
             srcY = s->last_pic.data[0];
             luty = v->last_luty;
             use_ic = v->last_use_ic;
-            interlace = !!(s->last_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+            interlace = s->last_pic.ptr->interlaced;
         }
     } else {
         srcY = s->next_pic.data[0];
         luty = v->next_luty;
         use_ic = v->next_use_ic;
-        interlace = !!(s->next_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+        interlace = s->next_pic.ptr->interlaced;
     }
 
     if (!srcY) {
@@ -669,7 +669,7 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
     s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;
     s->cur_pic.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;
 
-    uvlinesize = s->cur_pic_ptr->f->linesize[1];
+    uvlinesize = s->cur_pic.ptr->f->linesize[1];
 
     uvmx = (tx + ((tx & 3) == 3)) >> 1;
     uvmy = (ty + ((ty & 3) == 3)) >> 1;
@@ -708,14 +708,14 @@ void ff_vc1_mc_4mv_chroma(VC1Context *v, int dir)
             srcV = s->last_pic.data[2];
             lutuv = v->last_lutuv;
             use_ic = v->last_use_ic;
-            interlace = !!(s->last_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+            interlace = s->last_pic.ptr->interlaced;
         }
     } else {
         srcU = s->next_pic.data[1];
         srcV = s->next_pic.data[2];
         lutuv = v->next_lutuv;
         use_ic = v->next_use_ic;
-        interlace = !!(s->next_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+        interlace = s->next_pic.ptr->interlaced;
     }
 
     if (!srcU) {
@@ -856,7 +856,7 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
     if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
         return;
 
-    uvlinesize = s->cur_pic_ptr->f->linesize[1];
+    uvlinesize = s->cur_pic.ptr->f->linesize[1];
 
     for (i = 0; i < 4; i++) {
         int d = i < 2 ? dir: dir2;
@@ -884,13 +884,13 @@ void ff_vc1_mc_4mv_chroma4(VC1Context *v, int dir, int dir2, int avg)
             srcV = s->next_pic.data[2];
             lutuv  = v->next_lutuv;
             use_ic = v->next_use_ic;
-            interlace = !!(s->next_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+            interlace = s->next_pic.ptr->interlaced;
         } else {
             srcU = s->last_pic.data[1];
             srcV = s->last_pic.data[2];
             lutuv  = v->last_lutuv;
             use_ic = v->last_use_ic;
-            interlace = !!(s->last_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+            interlace = s->last_pic.ptr->interlaced;
         }
         if (!srcU)
             return;
@@ -1015,8 +1015,8 @@ void ff_vc1_interp_mc(VC1Context *v)
     if (!v->field_mode && !v->s.next_pic.data[0])
         return;
 
-    linesize   = s->cur_pic_ptr->f->linesize[0];
-    uvlinesize = s->cur_pic_ptr->f->linesize[1];
+    linesize   = s->cur_pic.ptr->f->linesize[0];
+    uvlinesize = s->cur_pic.ptr->f->linesize[1];
 
     mx   = s->mv[1][0][0];
     my   = s->mv[1][0][1];
@@ -1034,7 +1034,7 @@ void ff_vc1_interp_mc(VC1Context *v)
     srcU = s->next_pic.data[1];
     srcV = s->next_pic.data[2];
 
-    interlace = !!(s->next_pic.f->flags & AV_FRAME_FLAG_INTERLACED);
+    interlace = s->next_pic.ptr->interlaced;
 
     src_x   = s->mb_x * 16 + (mx   >> 2);
     src_y   = s->mb_y * 16 + (my   >> 2);
diff --git a/libavcodec/vc1_pred.c b/libavcodec/vc1_pred.c
index 9141290d26..6e260fa053 100644
--- a/libavcodec/vc1_pred.c
+++ b/libavcodec/vc1_pred.c
@@ -719,7 +719,7 @@ void ff_vc1_pred_b_mv(VC1Context *v, int dmv_x[2], int dmv_y[2],
         s->cur_pic.motion_val[1][xy][1] = 0;
         return;
     }
-        if (direct && s->next_pic_ptr->field_picture)
+        if (direct && s->next_pic.ptr->field_picture)
             av_log(s->avctx, AV_LOG_WARNING, "Mixed frame/field direct mode not supported\n");
 
         s->mv[0][0][0] = scale_mv(s->next_pic.motion_val[1][xy][0], v->bfraction, 0, s->quarter_sample);
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 71fda305da..9bbd5cecf6 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -322,7 +322,7 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb)
         return AVERROR_UNKNOWN;
     }
 
-    if (v->two_sprites && (!s->last_pic_ptr || !s->last_pic.data[0])) {
+    if (v->two_sprites && (!s->last_pic.ptr || !s->last_pic.data[0])) {
         av_log(avctx, AV_LOG_WARNING, "Need two sprites, only got one\n");
         v->two_sprites = 0;
     }
@@ -340,7 +340,7 @@ static void vc1_sprite_flush(AVCodecContext *avctx)
 {
     VC1Context *v     = avctx->priv_data;
     MpegEncContext *s = &v->s;
-    MPVPicture *f = &s->cur_pic;
+    MPVWorkPicture *f = &s->cur_pic;
     int plane, i;
 
     /* Windows Media Image codecs have a convergence interval of two keyframes.
@@ -837,10 +837,10 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict,
     /* no supplementary picture */
     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_pic_ptr) {
-            if ((ret = av_frame_ref(pict, s->next_pic_ptr->f)) < 0)
+        if (s->low_delay == 0 && s->next_pic.ptr) {
+            if ((ret = av_frame_ref(pict, s->next_pic.ptr->f)) < 0)
                 return ret;
-            s->next_pic_ptr = NULL;
+            s->next_pic.ptr = NULL;
 
             *got_frame = 1;
         }
@@ -1047,7 +1047,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict,
     }
 
     /* skip B-frames if we don't have reference frames */
-    if (!s->last_pic_ptr && s->pict_type == AV_PICTURE_TYPE_B) {
+    if (!s->last_pic.ptr && s->pict_type == AV_PICTURE_TYPE_B) {
         av_log(v->s.avctx, AV_LOG_DEBUG, "Skipping B frame without reference frames\n");
         goto end;
     }
@@ -1061,19 +1061,20 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict,
         goto err;
     }
 
-    v->s.cur_pic_ptr->field_picture = v->field_mode;
-    v->s.cur_pic_ptr->f->flags |= AV_FRAME_FLAG_INTERLACED * (v->fcm != PROGRESSIVE);
-    v->s.cur_pic_ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!v->tff;
+    v->s.cur_pic.ptr->field_picture = v->field_mode;
+    v->s.cur_pic.ptr->f->flags |= AV_FRAME_FLAG_INTERLACED * (v->fcm != PROGRESSIVE);
+    v->s.cur_pic.ptr->f->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST * !!v->tff;
+    v->s.cur_pic.ptr->interlaced = v->fcm != PROGRESSIVE;
 
     // process pulldown flags
-    s->cur_pic_ptr->f->repeat_pict = 0;
+    s->cur_pic.ptr->f->repeat_pict = 0;
     // Pulldown flags are only valid when 'broadcast' has been set.
     if (v->rff) {
         // repeat field
-        s->cur_pic_ptr->f->repeat_pict = 1;
+        s->cur_pic.ptr->f->repeat_pict = 1;
     } else if (v->rptfrm) {
         // repeat frames
-        s->cur_pic_ptr->f->repeat_pict = v->rptfrm * 2;
+        s->cur_pic.ptr->f->repeat_pict = v->rptfrm * 2;
     }
 
     if (avctx->hwaccel) {
@@ -1135,7 +1136,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict,
                 ret = AVERROR_INVALIDDATA;
                 goto err;
             }
-            v->s.cur_pic_ptr->f->pict_type = v->s.pict_type;
+            v->s.cur_pic.ptr->f->pict_type = v->s.pict_type;
 
             ret = hwaccel->start_frame(avctx, buf_start_second_field,
                                        (buf + buf_size) - buf_start_second_field);
@@ -1353,16 +1354,16 @@ image:
         *got_frame = 1;
     } else {
         if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
-            if ((ret = av_frame_ref(pict, s->cur_pic_ptr->f)) < 0)
+            if ((ret = av_frame_ref(pict, s->cur_pic.ptr->f)) < 0)
                 goto err;
             if (!v->field_mode)
-                ff_print_debug_info(s, s->cur_pic_ptr, pict);
+                ff_print_debug_info(s, s->cur_pic.ptr, pict);
             *got_frame = 1;
-        } else if (s->last_pic_ptr) {
-            if ((ret = av_frame_ref(pict, s->last_pic_ptr->f)) < 0)
+        } else if (s->last_pic.ptr) {
+            if ((ret = av_frame_ref(pict, s->last_pic.ptr->f)) < 0)
                 goto err;
             if (!v->field_mode)
-                ff_print_debug_info(s, s->last_pic_ptr, pict);
+                ff_print_debug_info(s, s->last_pic.ptr, pict);
             *got_frame = 1;
         }
     }
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index f46bfa2bdf..0dd5641603 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -370,7 +370,7 @@ int ff_vdpau_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
 int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
-    MPVPicture *pic = s->cur_pic_ptr;
+    MPVPicture *pic = s->cur_pic.ptr;
     struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     int val;
 
diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c
index abd8cb19af..1ce0bfaa07 100644
--- a/libavcodec/vdpau_mpeg12.c
+++ b/libavcodec/vdpau_mpeg12.c
@@ -35,7 +35,7 @@ static int vdpau_mpeg_start_frame(AVCodecContext *avctx,
                                   const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
-    MPVPicture *pic          = s->cur_pic_ptr;
+    MPVPicture *pic          = s->cur_pic.ptr;
     struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     VdpPictureInfoMPEG1Or2 *info = &pic_ctx->info.mpeg;
     VdpVideoSurface ref;
@@ -47,12 +47,12 @@ static int vdpau_mpeg_start_frame(AVCodecContext *avctx,
 
     switch (s->pict_type) {
     case AV_PICTURE_TYPE_B:
-        ref = ff_vdpau_get_surface_id(s->next_pic.f);
+        ref = ff_vdpau_get_surface_id(s->next_pic.ptr->f);
         assert(ref != VDP_INVALID_HANDLE);
         info->backward_reference = ref;
         /* fall through to forward prediction */
     case AV_PICTURE_TYPE_P:
-        ref = ff_vdpau_get_surface_id(s->last_pic.f);
+        ref = ff_vdpau_get_surface_id(s->last_pic.ptr->f);
         info->forward_reference  = ref;
     }
 
@@ -87,7 +87,7 @@ static int vdpau_mpeg_decode_slice(AVCodecContext *avctx,
                                    const uint8_t *buffer, uint32_t size)
 {
     MpegEncContext * const s = avctx->priv_data;
-    MPVPicture *pic          = s->cur_pic_ptr;
+    MPVPicture *pic          = s->cur_pic.ptr;
     struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     int val;
 
diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c
index e2766835f6..40af8655cc 100644
--- a/libavcodec/vdpau_mpeg4.c
+++ b/libavcodec/vdpau_mpeg4.c
@@ -34,7 +34,7 @@ static int vdpau_mpeg4_start_frame(AVCodecContext *avctx,
 {
     Mpeg4DecContext *ctx = avctx->priv_data;
     MpegEncContext * const s = &ctx->m;
-    MPVPicture *pic          = s->cur_pic_ptr;
+    MPVPicture *pic          = s->cur_pic.ptr;
     struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     VdpPictureInfoMPEG4Part2 *info = &pic_ctx->info.mpeg4;
     VdpVideoSurface ref;
@@ -47,13 +47,13 @@ static int vdpau_mpeg4_start_frame(AVCodecContext *avctx,
 
     switch (s->pict_type) {
     case AV_PICTURE_TYPE_B:
-        ref = ff_vdpau_get_surface_id(s->next_pic.f);
+        ref = ff_vdpau_get_surface_id(s->next_pic.ptr->f);
         assert(ref != VDP_INVALID_HANDLE);
         info->backward_reference = ref;
         info->vop_coding_type    = 2;
         /* fall-through */
     case AV_PICTURE_TYPE_P:
-        ref = ff_vdpau_get_surface_id(s->last_pic.f);
+        ref = ff_vdpau_get_surface_id(s->last_pic.ptr->f);
         assert(ref != VDP_INVALID_HANDLE);
         info->forward_reference  = ref;
     }
diff --git a/libavcodec/vdpau_vc1.c b/libavcodec/vdpau_vc1.c
index 9ed1665cad..d02a454bb8 100644
--- a/libavcodec/vdpau_vc1.c
+++ b/libavcodec/vdpau_vc1.c
@@ -36,7 +36,7 @@ static int vdpau_vc1_start_frame(AVCodecContext *avctx,
 {
     VC1Context * const v  = avctx->priv_data;
     MpegEncContext * const s = &v->s;
-    MPVPicture *pic          = s->cur_pic_ptr;
+    MPVPicture *pic          = s->cur_pic.ptr;
     struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     VdpPictureInfoVC1 *info = &pic_ctx->info.vc1;
     VdpVideoSurface ref;
@@ -47,15 +47,15 @@ static int vdpau_vc1_start_frame(AVCodecContext *avctx,
 
     switch (s->pict_type) {
     case AV_PICTURE_TYPE_B:
-        if (s->next_pic_ptr) {
-            ref = ff_vdpau_get_surface_id(s->next_pic.f);
+        if (s->next_pic.ptr) {
+            ref = ff_vdpau_get_surface_id(s->next_pic.ptr->f);
             assert(ref != VDP_INVALID_HANDLE);
             info->backward_reference = ref;
         }
         /* fall-through */
     case AV_PICTURE_TYPE_P:
-        if (s->last_pic_ptr) {
-            ref = ff_vdpau_get_surface_id(s->last_pic.f);
+        if (s->last_pic.ptr) {
+            ref = ff_vdpau_get_surface_id(s->last_pic.ptr->f);
             assert(ref != VDP_INVALID_HANDLE);
             info->forward_reference  = ref;
         }
@@ -104,7 +104,7 @@ static int vdpau_vc1_decode_slice(AVCodecContext *avctx,
 {
     VC1Context * const v  = avctx->priv_data;
     MpegEncContext * const s = &v->s;
-    MPVPicture *pic          = s->cur_pic_ptr;
+    MPVPicture *pic          = s->cur_pic.ptr;
     struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
     int val;
 
diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
index 7807047aa6..a8ea8ff7ff 100644
--- a/libavcodec/videotoolbox.c
+++ b/libavcodec/videotoolbox.c
@@ -1108,7 +1108,7 @@ static int videotoolbox_mpeg_decode_slice(AVCodecContext *avctx,
 static int videotoolbox_mpeg_end_frame(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
-    AVFrame *frame = s->cur_pic_ptr->f;
+    AVFrame *frame = s->cur_pic.ptr->f;
 
     return ff_videotoolbox_common_end_frame(avctx, frame);
 }
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index 432d6f7223..bb3829dcd6 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -330,7 +330,7 @@ int ff_wmv2_decode_secondary_picture_header(MpegEncContext *s)
     s->esc3_run_length   = 0;
 
     if (w->j_type) {
-        ff_intrax8_decode_picture(&w->x8, &s->cur_pic,
+        ff_intrax8_decode_picture(&w->x8, s->cur_pic.ptr,
                                   &s->gb, &s->mb_x, &s->mb_y,
                                   2 * s->qscale, (s->qscale - 1) | 1,
                                   s->loop_filter, s->low_delay);
