Deliver HDR video correctly: choose PQ or HLG, encode HDR10 with static metadata, make tone-mapped SDR versions, and match platform specs (YouTube and others). Use when exporting HDR, tagging HDR files, converting HDR to SDR, or debugging washed-out or rejected HDR uploads.
./install.sh hdr-deliveryname: "hdr_delivery" description: "Deliver HDR video correctly: choose PQ or HLG, encode HDR10 with static metadata, make tone-mapped SDR versions, and match platform specs (YouTube and others). Use when exporting HDR, tagging HDR files, converting HDR to SDR, or debugging washed-out or rejected HDR uploads."
HDR delivery is metadata plus math, not just pixels. A 10-bit PQ or HLG file with wrong or missing tags plays washed out on one device and gets rejected on another. This skill takes a graded master and produces deliverables that survive the real world: a properly tagged HDR10/HEVC file, an SDR version with a sane tone map, and a verification pass that proves the tags match the pixels.
Use it when: exporting an HDR edit for YouTube/Vimeo, converting HDR to SDR for SDR-only platforms, fixing an upload that looks wrong, or checking whether a file is really HDR.
Run the helper before doing anything else:
bash
python3 bin/hdr_deliver.py probe INPUT
It reports transfer (smpte2084/PQ, arib-std-b67/HLG, bt709/SDR), primaries, bit depth, whether ST 2086 mastering-display and MaxCLL/MaxFALL side data exist, and an HDR/SDR verdict. Never trust the filename. If probe says the pixels are SDR but the tags say PQ, the file is broken: retag only after converting the pixels, never before.
Both use BT.2020 primaries. Both need 10-bit to avoid banding. Bit depth alone does not make HDR: 10-bit sRGB is still SDR, 10-bit PQ is HDR.
From a graded HDR master (or a correctly tagged PQ source), encode HEVC Main 10 with the tags and metadata intact:
bash
python3 bin/hdr_deliver.py hdr10 master.mov deliverable.mp4 \
--primaries p3 --peak-nits 1000 --max-cll 1000 --max-fall 400
This sets -color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc, writes the colr box, forces the hvc1 tag (Apple and iOS reject hev1-tagged HDR in MP4), and attaches the ST 2086 mastering-display and content-light metadata. See references/platform-specs.md for platform specifics.
The conversion must pass through linear light in floating point, or highlights clip silently:
bash
python3 bin/hdr_deliver.py to-sdr deliverable.mp4 deliverable-sdr.mp4
The helper builds the correct filter chain (zscale=t=linear:npl=100 to linear, format=gbrpf32le, primaries to BT.709, tonemap, then BT.709 transfer and matrix) and forces BT.709 output tags so the SDR file never carries leftover HDR tags. Use --tonemap bt2390 for the broadcast-standard curve, hable for a pleasing default, mobius to keep more highlight detail. Recipe variants (libplacebo, HLG sources, Dolby Vision) live in references/tonemap-recipes.md.
bash
python3 bin/hdr_deliver.py verify deliverable.mp4
It re-probes and fails loudly on the common killers: tags that disagree with pixels, missing mastering-display metadata on PQ files, 8-bit HDR, or hev1 tags aimed at Apple devices. A deliverable that does not pass verify does not ship.
Each deliverable run produces:
deliverable.mp4: HEVC Main 10, BT.2020 / PQ tags, hvc1, ST 2086 + MaxCLL/MaxFALL metadata, verify clean.deliverable-sdr.mp4: H.264, BT.709 tags, yuv420p, tone-mapped, verify clean.delivery-notes.txt next to the outputs: source probe result, transfer choice and why, tone map used, and the exact commands run (reproducible without the helper).bt2390 for broadcast compliance, hable for pleasant, mobius for highlight preservation.dovi_tool for full decode; ffmpeg alone resolves only the base layer (profile 5 is PQ-based and tone-maps like HDR10). HDR10+ dynamic metadata must be extracted and re-injected after the final encode with hdr10plus_tool; it does not survive a transcode.--to-hdr on SDR inputs unless --force is given.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.