diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c
index d0b529dc37..8a058c4a77 100644
--- a/libavcodec/mpegpicture.c
+++ b/libavcodec/mpegpicture.c
@@ -91,40 +91,27 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
     return 0;
 }
 
-/**
- * Check the pic's linesize and allocate linesize dependent scratch buffers
- */
-static int handle_pic_linesizes(AVCodecContext *avctx, Picture *pic,
-                                MotionEstContext *me, ScratchpadContext *sc,
-                                int linesize, int uvlinesize)
+int ff_mpv_pic_check_linesize(void *logctx, const AVFrame *f,
+                              ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep)
 {
-    int ret;
-
-    if ((linesize   &&   linesize != pic->f->linesize[0]) ||
-        (uvlinesize && uvlinesize != pic->f->linesize[1])) {
-        av_log(avctx, AV_LOG_ERROR, "Stride change unsupported: "
-               "linesize=%d/%d uvlinesize=%d/%d)\n",
-               linesize,   pic->f->linesize[0],
-               uvlinesize, pic->f->linesize[1]);
-        ff_mpeg_unref_picture(pic);
+    ptrdiff_t linesize = *linesizep, uvlinesize = *uvlinesizep;
+
+    if ((linesize   &&   linesize != f->linesize[0]) ||
+        (uvlinesize && uvlinesize != f->linesize[1])) {
+        av_log(logctx, AV_LOG_ERROR, "Stride change unsupported: "
+               "linesize=%"PTRDIFF_SPECIFIER"/%d uvlinesize=%"PTRDIFF_SPECIFIER"/%d)\n",
+               linesize,   f->linesize[0],
+               uvlinesize, f->linesize[1]);
         return AVERROR_PATCHWELCOME;
     }
 
-    if (av_pix_fmt_count_planes(pic->f->format) > 2 &&
-        pic->f->linesize[1] != pic->f->linesize[2]) {
-        av_log(avctx, AV_LOG_ERROR, "uv stride mismatch unsupported\n");
-        ff_mpeg_unref_picture(pic);
+    if (av_pix_fmt_count_planes(f->format) > 2 &&
+        f->linesize[1] != f->linesize[2]) {
+        av_log(logctx, AV_LOG_ERROR, "uv stride mismatch unsupported\n");
         return AVERROR_PATCHWELCOME;
     }
-
-    ret = ff_mpeg_framesize_alloc(avctx, me, sc,
-                                  pic->f->linesize[0]);
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR,
-               "get_buffer() failed to allocate context scratch buffers.\n");
-        ff_mpeg_unref_picture(pic);
-        return ret;
-    }
+    *linesizep   = f->linesize[0];
+    *uvlinesizep = f->linesize[1];
 
     return 0;
 }
@@ -155,28 +142,22 @@ static int alloc_picture_tables(BufferPoolContext *pools, Picture *pic,
     return 0;
 }
 
-/**
- * Allocate a Picture.
- * The pixels are allocated/set by calling get_buffer() if shared = 0
- */
-int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
-                     ScratchpadContext *sc, BufferPoolContext *pools,
-                     int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize)
+int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, Picture *pic,
+                                 MotionEstContext *me, ScratchpadContext *sc,
+                                 BufferPoolContext *pools, int mb_height)
 {
     int ret;
 
-    if (handle_pic_linesizes(avctx, pic, me, sc,
-                             *linesize, *uvlinesize) < 0)
-        return -1;
-
-    *linesize   = pic->f->linesize[0];
-    *uvlinesize = pic->f->linesize[1];
-
     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)
+        goto fail;
+
     ret = alloc_picture_tables(pools, pic, mb_height);
     if (ret < 0)
         goto fail;
@@ -191,9 +172,8 @@ int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
 
     return 0;
 fail:
-    av_log(avctx, AV_LOG_ERROR, "Error allocating a picture.\n");
-    ff_mpeg_unref_picture(pic);
-    return AVERROR(ENOMEM);
+    av_log(avctx, AV_LOG_ERROR, "Error allocating picture accessories.\n");
+    return ret;
 }
 
 /**
diff --git a/libavcodec/mpegpicture.h b/libavcodec/mpegpicture.h
index 814f71213e..6589b38262 100644
--- a/libavcodec/mpegpicture.h
+++ b/libavcodec/mpegpicture.h
@@ -96,9 +96,18 @@ typedef struct Picture {
 /**
  * Allocate a Picture's accessories, but not the AVFrame's buffer itself.
  */
-int ff_alloc_picture(AVCodecContext *avctx, Picture *pic, MotionEstContext *me,
-                     ScratchpadContext *sc, BufferPoolContext *pools,
-                     int mb_height, ptrdiff_t *linesize, ptrdiff_t *uvlinesize);
+int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, Picture *pic,
+                                 MotionEstContext *me, ScratchpadContext *sc,
+                                 BufferPoolContext *pools, int mb_height);
+
+/**
+ * Check that the linesizes of an AVFrame are consistent with the requirements
+ * of mpegvideo.
+ * FIXME: There should be no need for this function. mpegvideo should be made
+ *        to work with changing linesizes.
+ */
+int ff_mpv_pic_check_linesize(void *logctx, const struct AVFrame *f,
+                              ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep);
 
 int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me,
                             ScratchpadContext *sc, int linesize);
diff --git a/libavcodec/mpegvideo_dec.c b/libavcodec/mpegvideo_dec.c
index 570a422b6f..663d97e60f 100644
--- a/libavcodec/mpegvideo_dec.c
+++ b/libavcodec/mpegvideo_dec.c
@@ -259,6 +259,10 @@ static int alloc_picture(MpegEncContext *s, Picture **picp, int reference)
     if (ret < 0)
         goto fail;
 
+    ret = ff_mpv_pic_check_linesize(avctx, pic->f, &s->linesize, &s->uvlinesize);
+    if (ret < 0)
+        goto fail;
+
     ret = ff_hwaccel_frame_priv_alloc(avctx, &pic->hwaccel_picture_private);
     if (ret < 0)
         goto fail;
@@ -267,8 +271,8 @@ static int alloc_picture(MpegEncContext *s, Picture **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_alloc_picture(s->avctx, pic, &s->me, &s->sc, &s->buffer_pools,
-                           s->mb_height, &s->linesize, &s->uvlinesize);
+    ret = ff_mpv_alloc_pic_accessories(s->avctx, pic, &s->me, &s->sc,
+                                       &s->buffer_pools, s->mb_height);
     if (ret < 0)
         goto fail;
     *picp = pic;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 15c6a90e9e..8e1ea36022 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1103,6 +1103,10 @@ static int alloc_picture(MpegEncContext *s, Picture *pic)
     if (ret < 0)
         return ret;
 
+    ret = ff_mpv_pic_check_linesize(avctx, pic->f, &s->linesize, &s->uvlinesize);
+    if (ret < 0)
+        return ret;
+
     for (int i = 0; pic->f->data[i]; i++) {
         int offset = (EDGE_WIDTH >> (i ? s->chroma_y_shift : 0)) *
                      pic->f->linesize[i] +
@@ -1112,11 +1116,7 @@ static int alloc_picture(MpegEncContext *s, Picture *pic)
     pic->f->width  = avctx->width;
     pic->f->height = avctx->height;
 
-    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);
-    return ff_alloc_picture(s->avctx, pic, &s->me, &s->sc, &s->buffer_pools,
-                            s->mb_height, &s->linesize, &s->uvlinesize);
+    return 0;
 }
 
 static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
@@ -1188,7 +1188,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
         } else {
             ret = alloc_picture(s, pic);
             if (ret < 0)
-                return ret;
+                goto fail;
             ret = av_frame_copy_props(pic->f, pic_arg);
             if (ret < 0) {
                 ff_mpeg_unref_picture(pic);
@@ -1258,6 +1258,9 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
     s->input_picture[encoding_delay] = pic;
 
     return 0;
+fail:
+    ff_mpeg_unref_picture(pic);
+    return ret;
 }
 
 static int skip_check(MpegEncContext *s, const Picture *p, const Picture *ref)
@@ -1600,45 +1603,37 @@ no_output_pic:
            s->reordered_input_picture[0]->f->pict_type !=
                AV_PICTURE_TYPE_B ? 3 : 0;
 
-        if ((ret = av_frame_ref(s->new_pic,
-                                s->reordered_input_picture[0]->f)))
-            goto fail;
-
         if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) {
             // input is a shared pix, so we can't modify it -> allocate a new
             // one & ensure that the shared one is reuseable
-
-            Picture *pic;
-            int i = ff_find_unused_picture(s->avctx, s->picture, 0);
-            if (i < 0)
-                return i;
-            pic = &s->picture[i];
-
-            pic->reference = s->reordered_input_picture[0]->reference;
-            ret = alloc_picture(s, pic);
+            av_frame_move_ref(s->new_pic, s->reordered_input_picture[0]->f);
+            ret = alloc_picture(s, s->reordered_input_picture[0]);
             if (ret < 0)
                 goto fail;
 
-            ret = av_frame_copy_props(pic->f, s->reordered_input_picture[0]->f);
-            if (ret < 0) {
-                ff_mpeg_unref_picture(pic);
+            ret = av_frame_copy_props(s->reordered_input_picture[0]->f, s->new_pic);
+            if (ret < 0)
                 goto fail;
-            }
-            pic->coded_picture_number = s->reordered_input_picture[0]->coded_picture_number;
-            pic->display_picture_number = s->reordered_input_picture[0]->display_picture_number;
-
-            /* mark us unused / free shared pic */
-            ff_mpeg_unref_picture(s->reordered_input_picture[0]);
-
-            s->cur_pic_ptr = pic;
         } else {
             // input is not a shared pix -> reuse buffer for current_pix
-            s->cur_pic_ptr = s->reordered_input_picture[0];
+            ret = av_frame_ref(s->new_pic, s->reordered_input_picture[0]->f);
+            if (ret < 0)
+                goto fail;
             for (int i = 0; i < MPV_MAX_PLANES; i++) {
                 if (s->new_pic->data[i])
                     s->new_pic->data[i] += INPLACE_OFFSET;
             }
         }
+        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,
+                                           &s->sc, &s->buffer_pools, s->mb_height);
+        if (ret < 0) {
+            ff_mpeg_unref_picture(s->cur_pic_ptr);
+            return ret;
+        }
         s->picture_number = s->cur_pic_ptr->display_picture_number;
 
     }
