From b1158099d1e6ac7e53ac5d29c1fecac968621fba Mon Sep 17 00:00:00 2001 From: imSp4rky Date: Fri, 24 Apr 2026 11:50:27 -0600 Subject: [PATCH] fix(dash): expand CICP enums to full H.273 range Video.Range.from_cicp() crashed with ValueError on any CICP primaries, transfer, or matrix value outside the small subset previously enumerated (e.g. TransferCharacteristics=4 / BT.470M gamma 2.2 seen in SCTE-stitched live MPDs). Extend the three inner enums to cover all documented ITU-T H.273 / ISO/IEC 23001-8 values and fall back to Unspecified on unknown codes so SDR content no longer fails to parse. Source: https://raw.githubusercontent.com/FFmpeg/FFmpeg/master/libavutil/pixfmt.h (authoritative implementation of ITU-T H.273 / ISO/IEC 23001-8 tables). ITU spec itself: https://www.itu.int/rec/T-REC-H.273 --- unshackle/core/tracks/video.py | 33 ++++++++++++++++++++++++++++++--- uv.lock | 2 +- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/unshackle/core/tracks/video.py b/unshackle/core/tracks/video.py index 1f5674f..ed2bdb6 100644 --- a/unshackle/core/tracks/video.py +++ b/unshackle/core/tracks/video.py @@ -126,27 +126,48 @@ class Video(Track): Reserved = 0 BT_709 = 1 Unspecified = 2 + BT_470_M = 4 BT_601_625 = 5 BT_601_525 = 6 + SMPTE_240M = 7 + Generic_Film = 8 BT_2020_and_2100 = 9 + SMPTE_ST_428_1 = 10 + SMPTE_RP_431_2 = 11 # P3DCI SMPTE_ST_2113_and_EG_4321 = 12 # P3D65 + EBU_Tech_3213_E = 22 class Transfer(Enum): Reserved = 0 BT_709 = 1 Unspecified = 2 + BT_470_M = 4 BT_601 = 6 + SMPTE_240M = 7 + Linear = 8 + Log_100 = 9 + Log_316 = 10 + IEC_61966_2_4 = 11 + BT_1361 = 12 + IEC_61966_2_1 = 13 # sRGB / sYCC BT_2020 = 14 BT_2100 = 15 BT_2100_PQ = 16 + SMPTE_ST_428_1 = 17 BT_2100_HLG = 18 class Matrix(Enum): RGB = 0 YCbCr_BT_709 = 1 + Unspecified = 2 + YCbCr_FCC_73_682 = 4 YCbCr_BT_601_625 = 5 YCbCr_BT_601_525 = 6 + SMPTE_240M = 7 + YCgCo = 8 YCbCr_BT_2020_and_2100 = 9 # YCbCr BT.2100 shares the same CP + YCbCr_BT_2020_CL = 10 + YCbCr_SMPTE_ST_2085 = 11 ICtCp_BT_2100 = 14 if transfer == 5: @@ -155,9 +176,15 @@ class Video(Track): # The codebase is currently agnostic to either, so a manual conversion to 6 is done. transfer = 6 - primaries = Primaries(primaries) - transfer = Transfer(transfer) - matrix = Matrix(matrix) + def _safe(enum_cls, value): + try: + return enum_cls(value) + except ValueError: + return enum_cls(2) # Unspecified for unknown/private-use codes + + primaries = _safe(Primaries, primaries) + transfer = _safe(Transfer, transfer) + matrix = _safe(Matrix, matrix) # primaries and matrix does not strictly correlate to a range diff --git a/uv.lock b/uv.lock index bb38b22..26fc9b2 100644 --- a/uv.lock +++ b/uv.lock @@ -1651,7 +1651,7 @@ wheels = [ [[package]] name = "unshackle" -version = "4.0.0" +version = "5.0.0" source = { editable = "." } dependencies = [ { name = "aiohttp" },