From d2d194e85fea6b6e9b55177dba443518161c19df Mon Sep 17 00:00:00 2001
From: Tanguy Rozier <trozier@freebox.fr>
Date: Tue, 2 Sep 2025 15:14:43 +0200
Subject: [PATCH 6/6] libavformat/mov: read seig in spgd to override tenc
 information


diff --git a/libavformat/mov.c b/libavformat/mov.c
index eea27131e4..e0ce3ad372 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3792,10 +3792,11 @@ static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     grouping_type = avio_rl32(pb);
 
     /*
-     * This function only supports "sync" boxes, but the code is able to parse
+     * This function only supports "sync" and "seig" boxes, but the code is able to parse
      * other boxes (such as "tscl", "tsas" and "stsa")
      */
-    if (grouping_type != MKTAG('s','y','n','c'))
+    if (grouping_type != MKTAG('s','y','n','c') &&
+        grouping_type != MKTAG('s','e','i','g'))
         return 0;
 
     default_length = version >= 1 ? avio_rb32(pb) : 0;
@@ -3816,6 +3817,54 @@ static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             const uint8_t nal_unit_type = avio_r8(pb) & 0x3f;
             sc->sgpd_sync[i] = nal_unit_type;
             description_length -= 1;
+        } else if (grouping_type == MKTAG('s','e','i','g')) {
+            uint8_t pattern, is_protected;
+
+            if (!sc->cenc.default_encrypted_sample) {
+                sc->cenc.default_encrypted_sample = av_encryption_info_alloc(0, 16, 16);
+                if (!sc->cenc.default_encrypted_sample)
+                    return AVERROR(ENOMEM);
+            }
+
+            avio_r8(pb); //reserved
+            pattern = avio_r8(pb);
+            sc->cenc.default_encrypted_sample->crypt_byte_block = pattern >> 4;
+            sc->cenc.default_encrypted_sample->skip_byte_block = pattern & 0x0f;
+
+            is_protected = avio_r8(pb);
+            if (is_protected && !sc->cenc.encryption_index) {
+                // The whole stream should be by-default encrypted.
+                sc->cenc.encryption_index = av_mallocz(sizeof(MOVEncryptionIndex));
+                if (!sc->cenc.encryption_index)
+                    return AVERROR(ENOMEM);
+            }
+            sc->cenc.per_sample_iv_size = avio_r8(pb);
+            if (sc->cenc.per_sample_iv_size != 0 && sc->cenc.per_sample_iv_size != 8 &&
+                sc->cenc.per_sample_iv_size != 16) {
+                av_log(c->fc, AV_LOG_ERROR, "invalid per-sample IV size value\n");
+                return AVERROR_INVALIDDATA;
+            }
+            if (avio_read(pb, sc->cenc.default_encrypted_sample->key_id, 16) != 16) {
+                av_log(c->fc, AV_LOG_ERROR, "failed to read the default key ID\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            description_length -= 20;
+
+            if (is_protected && !sc->cenc.per_sample_iv_size) {
+                uint8_t iv_size = avio_r8(pb);
+                if (iv_size != 8 && iv_size != 16) {
+                    av_log(c->fc, AV_LOG_ERROR, "invalid default_constant_IV_size in tenc atom\n");
+                    return AVERROR_INVALIDDATA;
+                }
+
+                if (avio_read(pb, sc->cenc.default_encrypted_sample->iv, iv_size) != iv_size) {
+                    av_log(c->fc, AV_LOG_ERROR, "failed to read the default IV\n");
+                    return AVERROR_INVALIDDATA;
+                }
+
+                description_length -= 1 + iv_size;
+            }
         }
         avio_skip(pb, description_length);
     }
-- 
2.51.0

