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.
---
 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 1e8d240..2b171a4 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;
@@ -1247,11 +1248,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;
 
-- 
2.6.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to