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]
