[FFmpeg-cvslog] libavcodec/mpegvideo_enc.c: Fix encoding videos with less frames than the delay of the encoder.

Alexis Ballier git at videolan.org
Sun Oct 18 12:12:51 CEST 2015


ffmpeg | branch: master | Alexis Ballier <aballier at gentoo.org> | Fri Oct 16 10:42:33 2015 +0200| [6e8d856ad6d3decfabad83bc169c2e7a16a16b55] | committer: Michael Niedermayer

libavcodec/mpegvideo_enc.c: Fix encoding videos with less frames than the delay of the encoder.

When the encoder is fed with less frames than its delay, the picture list looks like { NULL, NULL, ..., frame, frame, frame }. When flushing the encoder (input frame == NULL), we need to ensure the picture list is shifted enough so that we do not return an empty packet, which would mean the encoder has finished, while it has not encoded any frame.

Before the patch, the command:
'./ffmpeg_g -loglevel debug -f lavfi -i "testsrc=d=0.01" -bf 2 -vcodec mpeg2video out.mxf' prints:

Output stream #0:0 (video): 1 frames encoded; 0 packets muxed (0 bytes);

After:

Output stream #0:0 (video): 1 frames encoded; 1 packets muxed (8058 bytes);

Relates to ticket #4817.

Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>

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

 libavcodec/mpegvideo_enc.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index 12922ac..d4e0532 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -1123,9 +1123,10 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
     Picture *pic = NULL;
     int64_t pts;
     int i, display_picture_number = 0, ret;
-    const int encoding_delay = s->max_b_frames ? s->max_b_frames :
-                                                 (s->low_delay ? 0 : 1);
+    int encoding_delay = s->max_b_frames ? s->max_b_frames :
+                                           (s->low_delay ? 0 : 1);
     int direct = 1;
+    int shift  = 1;
 
     if (pic_arg) {
         pts = pic_arg->pts;
@@ -1245,11 +1246,18 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg)
 
         pic->f->display_picture_number = display_picture_number;
         pic->f->pts = pts; // we set this here to avoid modifiying pic_arg
+    } else {
+        /* Flushing: When we have not received enough input frames,
+         * ensure s->input_picture[0] contains the first picture */
+        for (shift = 0; shift < encoding_delay + 1; shift++)
+            if (s->input_picture[shift]) break;
+        if (shift <= 1) shift = 1;
+        else encoding_delay = encoding_delay - shift + 1;
     }
 
     /* shift buffer entries */
-    for (i = 1; i < MAX_PICTURE_COUNT /*s->encoding_delay + 1*/; i++)
-        s->input_picture[i - 1] = s->input_picture[i];
+    for (i = shift; i < MAX_PICTURE_COUNT /*s->encoding_delay + 1*/; i++)
+        s->input_picture[i - shift] = s->input_picture[i];
 
     s->input_picture[encoding_delay] = (Picture*) pic;
 



More information about the ffmpeg-cvslog mailing list