[FFmpeg-devel] Bugfixes to VC-1 patch series

Ben Avison bavison at riscosopen.org
Wed Apr 16 21:10:39 CEST 2014

I'm never quite sure whether it's better to post incremental changes like
this for ease of review or whether to repost the original with them squashed
in - maybe it's better this way until people have had a few days to try it
out and raise further faults?

I think the main problem was that I was reseting repeat_pict too early (it
needed to be done between frames, but not before we returned to the caller).

I also fixed an unrelated problem: when the last frame was terminated by
EOF, I wasn't parsing the last frame header. If the EOF happens part way
through the frame header, the missing bytes are filled with zeros for
consistency with the old way of doing things.

There is still a subtle difference, because vc1_parse actually gets called
two times with buf_size==0 at the end of the stream (I'm not sure if this
isn't actually a bug elsewhere in the system, but let's assume it's correct
for now). I only parse the final frame header on the first of these calls,
but on the second call, vc1_parse now returns with repeat_pict set the same
as it was for the penultimate call, whereas previously it was zeroed. It
seems unlikely that this is an important difference though?

I found that converting the VC-1 input to a MKV output file resulted in
differences every time it was run, even with the same build. But MPEG
transport stream output seems deterministic; with this patch on top of
the main patch series, ffmpeg was able to reproduce a binary identical
mpegts version of the vc1+vc1+++artifacts1.vc1 stream, which is encouraging.


 libavcodec/vc1_parser.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index 9da8d9d..b18f6dc 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -100,6 +100,8 @@ static void vc1_extract_header(AVCodecParserContext *s, AVCodecContext *avctx,
                 // repeat frames
                 s->repeat_pict = vpc->v.rptfrm * 2 + 1;
+        }else{
+            s->repeat_pict = 0;
         if (vpc->v.broadcast && vpc->v.interlace && !vpc->v.psf)
@@ -127,9 +129,12 @@ static int vc1_parse(AVCodecParserContext *s,
     int next = END_NOT_FOUND;
     int i = 0;
-    if (pic_found && buf_size == 0)
+    if (pic_found && buf_size == 0) {
         /* EOF considered as end of frame */
+        memset(unesc_buffer + unesc_index, 0, UNESCAPED_THRESHOLD - unesc_index);
+        vc1_extract_header(s, avctx, unesc_buffer, unesc_index);
         next = 0;
+    }
     while (i < buf_size) {
         int start_code_found = 0;
         uint8_t b;
@@ -220,7 +225,6 @@ static int vc1_parse(AVCodecParserContext *s,
-    s->repeat_pict = 0;
     vpc->v.first_pic_header_flag = 1;
     vpc->prev_start_code = 0;
@@ -253,7 +257,6 @@ static av_cold int vc1_parse_init(AVCodecParserContext *s)
     VC1ParseContext *vpc = s->priv_data;
     vpc->v.s.slice_context_count = 1;
-    s->repeat_pict = 0;
     vpc->v.first_pic_header_flag = 1;
     vpc->prev_start_code = 0;
     vpc->unesc_index = 0;

More information about the ffmpeg-devel mailing list