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

Git pushed a commit to branch master
in repository ffmpeg.

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

    avcodec/vc1: move the extradata header walk into vc1.c
    
    vc1_decode_init() walks the markers of VC1/WVC1/WVP2 extradata and hands
    every sequence header and entry point it finds to the readers in vc1.c.
    The parser needs the same walk to know what a sequence header set before
    it reads an entry point, so give it one place to call instead of a second
    copy.
    
    No functional change: the caller keeps the size check, the "Incomplete
    extradata" rule and the sprite flag, and the walk returns the first error
    it hits exactly as before.
---
 libavcodec/vc1.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/vc1.h    | 16 ++++++++++++++++
 libavcodec/vc1dec.c | 45 ++++-----------------------------------------
 3 files changed, 70 insertions(+), 41 deletions(-)

diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index ab247f0a7f..6806608a82 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -26,6 +26,7 @@
  * VC-1 and WMV3 decoder common code
  */
 
+#include "libavutil/mem.h"
 #include "avcodec.h"
 #include "decode.h"
 #include "mpegvideo.h"
@@ -551,6 +552,55 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, 
VC1Context *v, GetBitContex
     return 0;
 }
 
+int ff_vc1_decode_extradata(AVCodecContext *avctx, VC1Context *v,
+                            int *seq_initialized, int *ep_initialized)
+{
+    const uint8_t *start = avctx->extradata;
+    const uint8_t *end   = avctx->extradata + avctx->extradata_size;
+    const uint8_t *next;
+    uint8_t *buf2;
+    GetBitContext gb;
+    int ret = 0;
+
+    *seq_initialized = 0;
+    *ep_initialized  = 0;
+
+    buf2 = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+    if (!buf2)
+        return AVERROR(ENOMEM);
+
+    start = find_next_marker(start, end); // in WVC1 extradata first byte is 
its size, but can be 0 in mkv
+    next  = start;
+    for (; next < end; start = next) {
+        int size, buf2_size;
+
+        next = find_next_marker(start + 4, end);
+        size = next - start - 4;
+        if (size <= 0)
+            continue;
+        buf2_size = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2);
+        ret = init_get_bits8(&gb, buf2, buf2_size);
+        if (ret < 0)
+            break;
+        switch (AV_RB32(start)) {
+        case VC1_CODE_SEQHDR:
+            if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0)
+                goto end;
+            *seq_initialized = 1;
+            break;
+        case VC1_CODE_ENTRYPOINT:
+            if ((ret = ff_vc1_decode_entry_point(avctx, v, &gb)) < 0)
+                goto end;
+            *ep_initialized = 1;
+            break;
+        }
+    }
+
+end:
+    av_free(buf2);
+    return ret;
+}
+
 /* fill lookup tables for intensity compensation */
 #define INIT_LUT(lumscale, lumshift, luty, lutuv, chain) do {                 \
         int scale, shift, i;                                                  \
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index f2a52c19c1..006cefd58e 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -417,6 +417,22 @@ int ff_vc1_decode_sequence_header(AVCodecContext *avctx, 
VC1Context *v, GetBitCo
 
 int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, 
GetBitContext *gb);
 
+/**
+ * Read the sequence and entry point headers carried in VC-1 extradata
+ *
+ * Walks the markers of VC1/WVC1/WVP2 extradata and feeds every sequence header
+ * and entry point it finds to the readers above. Callers decide what an absent
+ * or unreadable header means: the decoder needs both and fails without them,
+ * the parser takes what it gets.
+ *
+ * @param avctx Codec context holding the extradata to read
+ * @param seq_initialized Set to 1 if a sequence header was read
+ * @param ep_initialized Set to 1 if an entry point was read
+ * @return 0 on success, a negative AVERROR on a malformed header
+ */
+int ff_vc1_decode_extradata(AVCodecContext *avctx, VC1Context *v,
+                            int *seq_initialized, int *ep_initialized);
+
 int ff_vc1_parse_frame_header    (VC1Context *v, GetBitContext *gb);
 int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb);
 void ff_vc1_init_common(VC1Context *v);
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 1102e8123e..94bccbfa50 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -659,53 +659,16 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
             av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count);
         }
     } else { // VC1/WVC1/WVP2
-        const uint8_t *start = avctx->extradata;
-        const uint8_t *end = avctx->extradata + avctx->extradata_size;
-        const uint8_t *next;
-        int size, buf2_size;
-        uint8_t *buf2 = NULL;
-        int seq_initialized = 0, ep_initialized = 0;
+        int seq_initialized, ep_initialized;
 
         if (avctx->extradata_size < 16) {
             av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", 
avctx->extradata_size);
             return AVERROR_INVALIDDATA;
         }
 
-        buf2  = av_mallocz(avctx->extradata_size + 
AV_INPUT_BUFFER_PADDING_SIZE);
-        if (!buf2)
-            return AVERROR(ENOMEM);
-
-        start = find_next_marker(start, end); // in WVC1 extradata first byte 
is its size, but can be 0 in mkv
-        next  = start;
-        for (; next < end; start = next) {
-            next = find_next_marker(start + 4, end);
-            size = next - start - 4;
-            if (size <= 0)
-                continue;
-            buf2_size = v->vc1dsp.vc1_unescape_buffer(start + 4, size, buf2);
-            ret = init_get_bits8(&gb, buf2, buf2_size);
-            if (ret < 0) {
-                av_free(buf2);
-                return ret;
-            }
-            switch (AV_RB32(start)) {
-            case VC1_CODE_SEQHDR:
-                if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0) {
-                    av_free(buf2);
-                    return ret;
-                }
-                seq_initialized = 1;
-                break;
-            case VC1_CODE_ENTRYPOINT:
-                if ((ret = ff_vc1_decode_entry_point(avctx, v, &gb)) < 0) {
-                    av_free(buf2);
-                    return ret;
-                }
-                ep_initialized = 1;
-                break;
-            }
-        }
-        av_free(buf2);
+        ret = ff_vc1_decode_extradata(avctx, v, &seq_initialized, 
&ep_initialized);
+        if (ret < 0)
+            return ret;
         if (!seq_initialized || !ep_initialized) {
             av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n");
             return AVERROR_INVALIDDATA;

-- 
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