mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-14 21:15:06 +00:00
feat(tracks): probe HDR10 tracks for HDR10+ SEI before selection
Relabel HEVC HDR10 tracks whose first fragment carries ST 2094-40 SEI as HDR10P, for dl, the REST API and remote sessions. Config key hdr10plus_probe (default true).
This commit is contained in:
@@ -497,13 +497,16 @@ audio, add hand-built subtitles or an `Attachment` (e.g. cover art). Do *not*
|
||||
filter for resolution/bitrate. See `fetch_dash_manifest` in the EXAMPLE service
|
||||
for a thorough demonstration.
|
||||
|
||||
!!! note "Flip HDR10 → HDR10+ by hand when you know the platform embeds it"
|
||||
HDR10+ is a **bitstream (SEI)** feature. The HLS parser intentionally does
|
||||
not sniff it from the bitstream, so a manifest that embeds HDR10+ SEI but labels
|
||||
the variant plain HDR10 will parse as HDR10. The label is the only signal
|
||||
the parser has, and it is wrong. Only the service author knows the platform
|
||||
embeds HDR10+, so it is on you to correct `video.range` to HDR10+ here for
|
||||
those services.
|
||||
!!! note "HDR10+ in tracks labelled HDR10"
|
||||
HDR10+ is a **bitstream (SEI)** feature, and many manifests label an HDR10+
|
||||
variant as plain HDR10. Before unshackle lists or selects tracks, the
|
||||
[`hdr10plus_probe`](../reference/configuration/download.md#hdr10plus_probe)
|
||||
reads the first fragment of each HEVC HDR10 track and changes `video.range` to
|
||||
HDR10+ when the fragment carries HDR10+ metadata. Set `video.range` yourself
|
||||
only when the probe cannot read the fragment, for example an ISM track whose
|
||||
SEI is encrypted, or when the platform gives a reliable signal of its own.
|
||||
If the playback API has no HDR10+ value, request HDR10 for an HDR10+ request
|
||||
and let the probe relabel the tracks.
|
||||
|
||||
!!! warning "`get_tracks` is your only chance to capture license inputs"
|
||||
The license callbacks (`get_widevine_license` and the others) fire **much later**, in
|
||||
|
||||
@@ -165,7 +165,8 @@ unshackle dl -q 2160 -r HDR10,DV EXAMPLE '...'
|
||||
When a title has HDR10+ but no DV track, `-r HYBRID --generate-dv` makes a Dolby Vision
|
||||
Profile 8.1 track from the HDR10+ metadata. It needs `hdr10plus_tool` as well as `dovi_tool`.
|
||||
When a title has a DV track, unshackle uses that track and ignores the flag. When it has none,
|
||||
the flag also makes unshackle ask the service for its HDR10+ tracks.
|
||||
the flag also makes unshackle ask the service for its HDR10+ tracks. A track that the service labels HDR10 but
|
||||
that carries HDR10+ metadata also qualifies (see [`hdr10plus_probe`](../reference/configuration/download.md#hdr10plus_probe)).
|
||||
|
||||
```shell title="Generate Dolby Vision from HDR10+, and keep the HDR10+ file too"
|
||||
unshackle dl -q 2160 -r HYBRID,HDR10P --generate-dv EXAMPLE '...'
|
||||
|
||||
@@ -370,6 +370,37 @@ dual_multi_mode: strict
|
||||
Regional variants of the same base language (e.g. `en-US` and `en-GB`) collapse to a single
|
||||
language in both modes, so they never trigger `{dual}` on their own.
|
||||
|
||||
## `hdr10plus_probe`
|
||||
|
||||
- **Type:** `bool` · **Default:** `true`
|
||||
|
||||
Find the HDR10+ tracks that a service labels as HDR10. Before unshackle lists or selects tracks, it
|
||||
reads the first fragment of HEVC HDR10 tracks from DASH, HLS fMP4 and one-file sources. A track
|
||||
whose first frame carries HDR10+ (SMPTE ST 2094-40) metadata becomes `HDR10P`. Then `-r HDR10P`,
|
||||
`--list` and [`--generate-dv`](../../guide/downloading.md#dolby-vision-from-hdr10) use it.
|
||||
|
||||
When two HDR10 tracks have the same resolution, they can be an HDR10 encode and an HDR10+ encode
|
||||
side by side, so unshackle probes every track. When each track has its own resolution, unshackle
|
||||
probes the two highest and the two lowest bitrates first:
|
||||
|
||||
| Result | Action |
|
||||
|--------|--------|
|
||||
| All four carry HDR10+ | Every HDR10 track of the title becomes `HDR10P`. |
|
||||
| Some carry HDR10+ | The title has HDR10 and HDR10+ encodes side by side, so unshackle probes every track. |
|
||||
| None carry HDR10+ | Every track stays `HDR10`. |
|
||||
|
||||
A probe that fails, or a fragment whose metadata is encrypted, keeps the label from the service.
|
||||
unshackle does not probe ISM tracks. Each probe makes one to three small requests: the 64 KiB
|
||||
fragment, plus the playlist of an HLS track or the header of a one-file track. The probes run in
|
||||
parallel, with no more at a time than `--workers` (or `dl.workers`) sets for a track download.
|
||||
|
||||
```yaml
|
||||
hdr10plus_probe: true
|
||||
```
|
||||
|
||||
A remote server probes its tracks before it sends them, so the setting on the server applies to
|
||||
remote downloads and to the REST API.
|
||||
|
||||
## `generate_dv_mode`
|
||||
|
||||
- **Type:** `str` · **Default:** `v29`
|
||||
|
||||
@@ -31,7 +31,7 @@ Where the file lives, how unshackle discovers it, and how to edit it:
|
||||
|------|------|
|
||||
| [Directories](directories.md) | `directories`, `filenames`, `services_repo_force` |
|
||||
| [Services & authentication](services.md) | `services`, `credentials`, `firefox_cookies`, `remote_services`, `serve` |
|
||||
| [Download & processing](download.md) | `dl`, `continue_downloads`, `merge_segments`, `subtitle`, `audio`, `muxing`, `language_tags`, `dual_multi_mode`, `generate_dv_mode` |
|
||||
| [Download & processing](download.md) | `dl`, `continue_downloads`, `merge_segments`, `subtitle`, `audio`, `muxing`, `language_tags`, `dual_multi_mode`, `generate_dv_mode`, `hdr10plus_probe` |
|
||||
| [Output & naming](output.md) | `output_template`, `tag`, `tag_rules`, `tag_group_name`, `tag_imdb_tmdb`, `chapter_fallback_name`, `unicode_filenames` |
|
||||
| [DRM & CDM](drm.md) | `cdm`, `remote_cdm`, `decryption` |
|
||||
| [Network & proxy](network.md) | `network`, `headers`, `proxy_providers` |
|
||||
|
||||
Reference in New Issue
Block a user