This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit ba7675a2d923fe91c0747b05dc56af5ee16b5f8f
Author:     Vincent Herbst <[email protected]>
AuthorDate: Mon Sep 21 20:26:56 2026 +0200
Commit:     michaelni <[email protected]>
CommitDate: Tue Sep 22 16:21:45 2026 +0000

    avcodec/vc1_parser: seed the parse context from extradata
    
    libavformat closes and reopens the parser on every reposition
    (ff_read_frame_flush()), so each seek hands vc1_parse() a zeroed
    VC1Context: profile reads as simple, and max_coded_width and
    max_coded_height as zero, until an in-stream sequence header happens to
    pass.
    
    An entry point BDU reaching the parser in that state is read at the wrong
    bit offset, because hrd_full[] precedes coded_size_flag only when the
    sequence header set hrd_param_flag, which a zeroed context cannot know.
    The bit taken for coded_size_flag is then the first hrd_full[] bit, so an
    entry point whose leaky bucket is below half full falls back to the zero
    pair and ff_set_dimensions() fails:
    
        [vc1] [IMGUTILS] Picture size 0x0 is invalid
        [vc1] Failed to set dimensions 0 0
    
    while one above half full takes a coded size out of the following
    payload. The same zeroed context also sends an advanced profile frame
    header through the simple/main reader, so pict_type, repeat_pict and
    field_order are whatever falls out of it; libavformat writes the first
    two into the packet key flag and the packet duration.
    
    Read the extradata headers once per parser instance, through the walk the
    decoder shares. A track whose frames carry no start codes is unaffected,
    and so is one whose landing packets repeat the sequence header; linear
    reads are byte identical either way.
---
 libavcodec/vc1_parser.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index fa7e8120fd..224ff3ee58 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -54,6 +54,7 @@ typedef struct VC1ParseContext {
     ParseContext pc;
     VC1Context v;
     uint8_t prev_start_code;
+    uint8_t extradata_parsed;
     size_t bytes_to_skip;
     uint8_t unesc_buffer[UNESCAPED_LIMIT];
     size_t unesc_index;
@@ -125,6 +126,32 @@ static void vc1_extract_header(AVCodecParserContext *s, 
AVCodecContext *avctx,
     }
 }
 
+/**
+ * Seed the parse context from extradata, the way the decoder does at init.
+ *
+ * libavformat closes and reopens the parser on every reposition
+ * (ff_read_frame_flush()), so each seek starts from a zeroed VC1Context: 
profile
+ * reads as simple, and max_coded_width/max_coded_height as zero, until an
+ * in-stream sequence header happens to pass. An entry point reaching a 
context in
+ * that state is read at the wrong bit offset, because whether hrd_full[] 
precedes
+ * coded_size_flag is a property of the sequence header, and the size it then
+ * falls back to is the zero pair.
+ *
+ * Unlike the decoder, a parser that learns nothing here still runs: it keeps
+ * reading headers out of the stream as it did before.
+ */
+static void vc1_parse_extradata(AVCodecParserContext *s, AVCodecContext *avctx)
+{
+    VC1ParseContext *vpc = s->priv_data;
+    int seq_initialized, ep_initialized;
+
+    if (!avctx->extradata || avctx->extradata_size < 16)
+        return;
+
+    vpc->v.s.avctx = avctx;
+    ff_vc1_decode_extradata(avctx, &vpc->v, &seq_initialized, &ep_initialized);
+}
+
 static int vc1_parse(AVCodecParserContext *s,
                            AVCodecContext *avctx,
                            const uint8_t **poutbuf, int *poutbuf_size,
@@ -142,6 +169,11 @@ static int vc1_parse(AVCodecParserContext *s,
     int next = END_NOT_FOUND;
     int i = vpc->bytes_to_skip;
 
+    if (!vpc->extradata_parsed) {
+        vpc->extradata_parsed = 1;
+        vc1_parse_extradata(s, avctx);
+    }
+
     if (pic_found && buf_size == 0) {
         /* EOF considered as end of frame */
         memset(unesc_buffer + unesc_index, 0, UNESCAPED_THRESHOLD - 
unesc_index);
@@ -270,6 +302,7 @@ static av_cold int vc1_parse_init(AVCodecParserContext *s)
     vpc->v.first_pic_header_flag = 1;
     vpc->v.parse_only = 1;
     vpc->prev_start_code = 0;
+    vpc->extradata_parsed = 0;
     vpc->bytes_to_skip = 0;
     vpc->unesc_index = 0;
     vpc->search_state = NO_MATCH;

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to