mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-06-22 08:57:25 +00:00
Smooth Streaming manifests carry no range attributes, so every ISM video track was labelled SDR even when the stream is HDR10/HLG/DV, breaking range-based selection (-r HDR10 / -r DV) for ISM services. - ism_init: walk the full HEVC SPS (incl. scaling-list and st_ref_pic_set skippers) to read the VUI colour triple (colour_primaries, transfer_characteristics, matrix_coeffs); expose parse_codec_private_data_colour() keyed by FourCC. No unshackle imports added. - ism: new ISM.get_video_range() maps the CICP triple via Video.Range.from_cicp (PQ -> HDR10, HLG -> HLG, BT.709/absent -> SDR); DVHE/DVH1 FourCCs map straight to DV since DV bitstreams signal Unspecified (2,2,2) in the VUI. to_tracks() now sets range_ on every video track. Soft-fails to SDR on malformed data. - ism: accept RnetSession in download_track() so TLS-impersonated sessions pass the type check. - tests: real PQ/HLG/BT.709 (x265-minted) and Dolby Vision (live-manifest, DoViProfile=stn, out-of-order SPS,PPS,VPS NALs) CodecPrivateData samples; byte-level VUI assertions in test_ism_init and manifest->Range characterization in new test_ism_range.
67 lines
2.7 KiB
Python
67 lines
2.7 KiB
Python
"""Offline characterization: ISM CodecPrivateData SPS VUI -> Video.Range
|
|
(PQ -> HDR10, HLG -> HLG, BT.709/absent -> SDR). HDR10+ is per-frame SEI,
|
|
undecidable from the manifest; the post-mux bitstream probe names it."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unshackle.core.manifests import ISM
|
|
from unshackle.core.tracks import Video
|
|
|
|
from tests.core.test_ism_init import (VIDEO_HEVC10_CPD, VIDEO_HEVC_DV_CPD, VIDEO_HEVC_HLG_CPD, # isort: skip
|
|
VIDEO_HEVC_PQ_CPD, VIDEO_HEVC_SDR_CPD)
|
|
|
|
|
|
def manifest_xml(cpd: str, fourcc: str = "HVC1") -> str:
|
|
return (
|
|
'<SmoothStreamingMedia MajorVersion="2" MinorVersion="0" TimeScale="10000000" Duration="100000000">'
|
|
'<StreamIndex Type="video" Name="video" Chunks="1" QualityLevels="1" MaxWidth="3840" MaxHeight="2160" '
|
|
'Url="QualityLevels({bitrate})/Fragments(video={start time})">'
|
|
f'<QualityLevel Index="0" Bitrate="15000000" FourCC="{fourcc}" MaxWidth="3840" MaxHeight="2160" '
|
|
f'CodecPrivateData="{cpd}"/>'
|
|
'<c t="0" d="100000000"/>'
|
|
"</StreamIndex>"
|
|
"</SmoothStreamingMedia>"
|
|
)
|
|
|
|
|
|
def parse_video(cpd: str, fourcc: str = "HVC1") -> Video:
|
|
tracks = ISM.from_text(manifest_xml(cpd, fourcc), url="https://x/ism/manifest").to_tracks(language="en")
|
|
assert len(tracks.videos) == 1
|
|
return tracks.videos[0]
|
|
|
|
|
|
def test_pq_codec_private_data_yields_hdr10() -> None:
|
|
assert parse_video(VIDEO_HEVC_PQ_CPD).range == Video.Range.HDR10
|
|
|
|
|
|
def test_hlg_codec_private_data_yields_hlg() -> None:
|
|
assert parse_video(VIDEO_HEVC_HLG_CPD).range == Video.Range.HLG
|
|
|
|
|
|
def test_bt709_codec_private_data_stays_sdr() -> None:
|
|
assert parse_video(VIDEO_HEVC_SDR_CPD).range == Video.Range.SDR
|
|
|
|
|
|
def test_colourless_codec_private_data_defaults_sdr() -> None:
|
|
# Real 10-bit sample without a VUI colour description: unspecified -> SDR.
|
|
assert parse_video(VIDEO_HEVC10_CPD).range == Video.Range.SDR
|
|
|
|
|
|
def test_get_video_range_dolby_vision_fourcc() -> None:
|
|
assert ISM.get_video_range("DVH1", VIDEO_HEVC_PQ_CPD) == Video.Range.DV
|
|
assert ISM.get_video_range("DVHE", "") == Video.Range.DV
|
|
|
|
|
|
def test_dv_track_from_real_smooth_cpd() -> None:
|
|
# Live manifests ship lowercase "dvhe"; its VUI is Unspecified so the
|
|
# FourCC short-circuit is the only thing standing between DV and SDR.
|
|
video = parse_video(VIDEO_HEVC_DV_CPD, fourcc="dvhe")
|
|
assert video.range == Video.Range.DV
|
|
assert ISM.get_video_range("hvc1", VIDEO_HEVC_DV_CPD) == Video.Range.SDR
|
|
|
|
|
|
def test_get_video_range_malformed_data_soft_fails_sdr() -> None:
|
|
assert ISM.get_video_range("HVC1", "not-hex") == Video.Range.SDR
|
|
assert ISM.get_video_range("HVC1", "") == Video.Range.SDR
|
|
assert ISM.get_video_range("", VIDEO_HEVC_PQ_CPD) == Video.Range.SDR
|