HDR (HLG) camera streaming — stage 1#80
Merged
Merged
Conversation
"color": "hlg" (10-bit HEVC, BT.2020 + HLG) with "log" reserved for Apple Log; absent = 8-bit SDR BT.709, which every stream was before the field existed. Informational by design -- the decoder takes the authoritative colour description from the bitstream VUI, so receivers that ignore the field render correctly; it exists so UIs can label the stream without decoding it. HDR is HEVC-only and camera-only. Spec lands ahead of the implementation (stage 1 in progress). Release-Skip: true Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015dWUcqAkNNuNELnMPS4RdT
README gains the HDR (beta) feature bullet; PERFORMANCE.md's "wire is 8-bit" divergence note becomes "defaults to 8-bit", pinning the rule that SDR, screen mirror, and H.264 stay free of 10-bit branches. Release-Skip: true Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015dWUcqAkNNuNELnMPS4RdT
StreamColor (sdr/hlg, Apple Log slots in later) threads from format selection to the wire: HLG restricts formats to x420 with BT.2020 HLG capture, pins activeColorSpace, encodes HEVC Main10 with BT.2020/HLG VUI tags, and adds "color":"hlg" to VIDEO_CONFIG (absent = SDR). The toggle only appears on devices that encode Main10, forces HEVC (H.264 hides while on), degrades to SDR when a combo lacks an HLG format — never a black stream — and bumps bitrate 25% for the extra depth. STATE advertises HEVC-only codecs plus "hdr":true while active; SDR snapshots and paths are byte-identical to before. Release-Skip: true Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015dWUcqAkNNuNELnMPS4RdT
Software HEVC Main10 decode now reaches OBS: yuv420p10 maps to I010, the frame's transfer function rides along as trc (never set before — even hardware P010 rendered with the SDR transfer), and colour params come from the format-aware variant so 10-bit ranges are right. The GPU-pipeline beta learns 10-bit CPU upload (P010 as R16+RG16, I010 as three R16 planes) with new HLG effect techniques that own the whole chain — BT.2020 limited-range matrix, BT.2100 inverse OETF + reference OOTF, BT.2087 primaries, no clamping — and a video_get_color_space callback reporting the extended-range canvas; 10-bit hardware surfaces are refused by the zero-copy mappers (they'd import as garbage or black) and take the CPU path until stage 2. gpu_frame_map_result now carries a pixel-format enum instead of an rgba bool, ready for zero-copy 10-bit. SDR behaviour is bit-identical throughout. Release-Bump: minor Release-Beta: true Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015dWUcqAkNNuNELnMPS4RdT
MyNamesEMurray
enabled auto-merge
July 25, 2026 08:48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Adds opt-in 10-bit HDR camera streaming, end to end: the app captures HLG (
x420, BT.2020) and hardware-encodes HEVC Main10 with the correct colour tags in the bitstream; the plugin decodes it and renders it correctly on both the standard async path (newyuv420p10→ I010 mapping plus the frame's transfer function, which was never being set — a latent bug that also mis-rendered hardware P010) and the GPU-pipeline beta (10-bit CPU upload with new HLG shader techniques and an extended-range colour-space report). Off by default; HEVC-only; degrades to SDR rather than ever producing a black stream.Built with stage 2 (zero-copy 10-bit GPU pipeline) and Apple Log capture in mind: colour is an enum (
StreamColor) not a boolean,gpu_frame_map_resultnow carries a pixel-format enum, the wire signal is an extensible"color"field on VIDEO_CONFIG (spec'd in docs/PROTOCOL.md; absent = SDR, bitstream VUI stays authoritative), and the zero-copy mappers explicitly refuse 10-bit hardware surfaces so they take the CPU path instead of rendering garbage.Also in this PR: STATE advertises
"hdr": trueand an HEVC-only codec list while HLG is active (remote UIs refuse H.264 through the existingset_formatvalidation, no web-panel changes needed), the Camera diagnostics table gains a colour column (10bit/8bit,HLG,Log), and docs updates (PROTOCOL, PERFORMANCE, README).How it was tested
h264-decoder.cwith a generated HEVC Main10 BT.2020/HLG bitstream: beforeframes=0(dropped as unsupported), afterframes=18 format=I010 cs=2100-HLG trc=hlg; the SDR H.264 sample is byte-identical to its baseline.-Wall -Wextra -Werror(Linux); Swift sources parse clean viasyntax-check.sh.🤖 Generated with Claude Code
https://claude.ai/code/session_015dWUcqAkNNuNELnMPS4RdT
Generated by Claude Code