ffmpeg | branch: master | Andreas Rheinhardt <andreas.rheinha...@outlook.com> | 
Thu Oct  5 23:16:44 2023 +0200| [b96ba62bddd1e06f42bad1407455834b19686e32] | 
committer: Andreas Rheinhardt

avcodec/mpegvideo_enc: Fix abort on allocation errors

mpegvideo_enc uses a fixed-size array of Pictures; a slot is
considered taken if the Picture's AVFrame is set.
When an error happens after a slot has been taken, this Picture
has typically not been reset and is therefore not usable for
future requests. The code aborts when one runs out of slots
and this can happen in case of allocation failures.
Fix this by always unreferencing a Picture in case of errors.

Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b96ba62bddd1e06f42bad1407455834b19686e32
---

 libavcodec/mpegvideo_enc.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index f669658127..bc89de0550 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1224,8 +1224,10 @@ static int load_input_picture(MpegEncContext *s, const 
AVFrame *pic_arg)
             }
         }
         ret = av_frame_copy_props(pic->f, pic_arg);
-        if (ret < 0)
+        if (ret < 0) {
+            ff_mpeg_unref_picture(s->avctx, pic);
             return ret;
+        }
 
         pic->display_picture_number = display_picture_number;
         pic->f->pts = pts; // we set this here to avoid modifying pic_arg
@@ -1536,8 +1538,10 @@ static int select_input_picture(MpegEncContext *s)
                 }
             } else if (s->b_frame_strategy == 2) {
                 b_frames = estimate_best_b_count(s);
-                if (b_frames < 0)
+                if (b_frames < 0) {
+                    ff_mpeg_unref_picture(s->avctx, s->input_picture[0]);
                     return b_frames;
+                }
             }
 
             emms_c();
@@ -1592,7 +1596,7 @@ no_output_pic:
 
         if ((ret = av_frame_ref(s->new_picture,
                                 s->reordered_input_picture[0]->f)))
-            return ret;
+            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
@@ -1605,13 +1609,15 @@ no_output_pic:
             pic = &s->picture[i];
 
             pic->reference = s->reordered_input_picture[0]->reference;
-            if (alloc_picture(s, pic, 0) < 0) {
-                return -1;
-            }
+            ret = alloc_picture(s, pic, 0);
+            if (ret < 0)
+                goto fail;
 
             ret = av_frame_copy_props(pic->f, 
s->reordered_input_picture[0]->f);
-            if (ret < 0)
-                return ret;
+            if (ret < 0) {
+                ff_mpeg_unref_picture(s->avctx, pic);
+                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;
 
@@ -1632,6 +1638,9 @@ no_output_pic:
 
     }
     return 0;
+fail:
+    ff_mpeg_unref_picture(s->avctx, s->reordered_input_picture[0]);
+    return ret;
 }
 
 static void frame_end(MpegEncContext *s)

_______________________________________________
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to