VLCHDRExpander · Metal Compute AVFoundation Pipeline

HDR on macOS

Your display can go six times brighter than SDR white. Almost nothing you own asks it to.

An XDR display can go five to six times brighter than SDR white.

Play an ordinary video file — which is almost every file you own — and none of that is used, because an ordinary file carries no HDR signal at all. Your expensive display sits idle on 99% of your library.

MacLC bridges that gap. A Metal compute shader (VLCHDRExpander, 895 lines) re-encodes each SDR frame into 10-bit BT.2020 PQ: shadows and mid-tones reach your eye at exactly the brightness they always did, while highlights are lifted into spare panel headroom.

6.15 ×

Display headroom on M3 Max

0.53 ms

Frame cost at 1080p

0.91 ms

Frame cost at 4K

895 lines

Metal compute shader

What HDR on macOS actually means

On macOS, High Dynamic Range is not a global display switch.

Standard dynamic range content is displayed at SDR white. An XDR display can go five to six times brighter than SDR white, exposing its spare optical capability as dynamic headroom.

Play an ordinary video file — which is almost every file you own — and none of that is used, because an ordinary file carries no HDR signal at all.

01 · Compositing

Extended Dynamic Range

macOS allows SDR and HDR content to coexist on screen simultaneously without clipping. MacLC applies a per-window ICC profile taken from the window's own screen rather than the main one.

02 · Hardware

Panel Headroom (6.15× Measured)

An XDR display can go five to six times brighter than SDR white, with 6.15× display headroom measured on an M3 Max. SDR → HDR needs a display with real extended range (XDR or an HDR external panel); on an SDR display it does nothing.

03 · The Gap

Your Display Sits Idle

Play an ordinary video file — which is almost every file you own — and none of that extended range is used. Your expensive display sits idle on 99% of your library.

Why SDR looks flat, and why the naive fix fails

An XDR display can go five to six times brighter than SDR white. Play an ordinary video file — which is almost every file you own — and none of that is used, because an ordinary file carries no HDR signal at all. Your expensive display sits idle on 99% of your library.

You cannot just relabel an SDR file as HDR. Under the PQ encoding used by HDR, the same numbers mean roughly five times the brightness.

Do that and mid-tones blow out — faces go white, the whole picture looks wrong.

Simulation on an SDR display. Relabelling an SDR file as HDR makes the same numbers mean roughly five times the brightness under PQ, blowing out mid-tones and faces.

The knee at half SDR white

Why the expansion curve is the interesting part of the engineering.

The expansion is the identity at and below a knee at half SDR white, and quadratic above it. It is chosen so that value and slope match the identity exactly at the knee, and SDR white lands exactly on the boost multiplier.

The calculation is applied to the largest of the three colour components, and the whole triplet is scaled by the result. Hue and saturation never move.

f(0.5) = 0.5 · f'(0.5) = 1.0

Slope Match at the Knee

The expansion is quadratic above the knee at half SDR white — chosen so that value and slope match the identity exactly at the knee, and SDR white lands exactly on the boost.

Triplet Scaling

Hue and Saturation Never Move

Applied to the largest of the three colour components, and the whole triplet is scaled by the result, so hue and saturation never move.

Preserved Mid-Tones

Shadows and Mid-Tones Don't Move

Shadows and mid-tones reach your eye at exactly the brightness they always did. Nothing is "brightened". Only the highlights — a glint on metal, a sky, a streetlight, an explosion — are lifted into the range your panel had spare all along.

The 7-stage Metal compute pipeline

VLCHDRExpander · 895 lines · Metal compute kernel

The shader intercepts the video frame on macOS's default AVFoundation display path. Starting from planar Y'CbCr 4:2:0 chroma-subsampled or BGRA input buffers, it re-encodes each SDR frame into 10-bit BT.2020 PQ in a single GPU compute dispatch.

Stage 4 — VLCHDRExpander

Identity at and below a knee at half SDR white, and quadratic above it — lifting highlights into spare headroom while shadows and mid-tones never move.

Pipeline reconstruction. Stages animate on scroll; select any stage with keyboard or cursor to inspect its operation.

The expansion curve, plotted live

Shadows and mid-tones reach your eye at exactly the brightness they always did. Nothing is "brightened".

Only the highlights — a glint on metal, a sky, a streetlight, an explosion — are lifted into the range your panel had spare all along.

4.0 is natural, higher is dramatic and less faithful.

Live mathematical evaluation of VLCHDRExpander. Quadratic boost matches value and slope at the 0.5 knee.

Measured performance and verification

Measured on Apple M3 Max with 6.15× display headroom on macOS 26.2. Validated against an independently authored CPU reference implementation of the identical transform.

Measurement Result Significance
Luma and chroma vs. reference Agree to the code Agree to the code over an eight-step ramp against independent reference.
Bit accuracy Bottom six bits clear Bottom six bits of every 16-bit word clear — true 10-bit, no noise in the pad bits.
Round-trip through PQ Exact SDR luminance Returns the exact SDR luminance for every input at or below the knee, rising monotonically to exactly the boost at SDR white.
Cost at 1080p 0.53 ms 0.53 ms per frame, including the synchronous wait.
Cost at 4K 0.91 ms 0.91 ms per frame, including the synchronous wait.
60-second 4K run Same wall-clock time Same wall-clock time as with the feature off.
Memory footprint Flat against 20s run Flat against a 20-second run.
Clamped to Headroom

min(your setting, display headroom)

Effective boost is min(your setting, the screen's real headroom) — it can never ask for more than the panel has.

ST 2086 Metadata

Mastering metadata emitted

Output carries mastering-display metadata describing the volume generated, so macOS has no reason to tone-map it back down.

Smart Passthrough

Skipped on native HDR

Skipped automatically for sources already in PQ or HLG.

Real-Time State

Live toggle during playback

Works live: flip the switch mid-film and the picture changes on the frame you are watching, not on the next file.

What is new here, and what is not

Inverse tone mapping is not a new idea — libplacebo, mpv and some TVs do versions of it.

What is genuinely distinct here is: MacLC does it in Metal on the default AVFoundation display path, where libplacebo is unreachable on macOS, exposed as one switch and one slider, and validated numerically against an independent reference.

Other implementations

Cross-platform frameworks and external renderers cannot reach the default AVFoundation display path on macOS.

MacLC approach

Built in Metal on the default AVFoundation display path, with per-window ICC profiles taken from each window's own screen.

Six defects fixed in the macOS HDR path

An audit of VLC 4.0.0-dev on Apple Silicon identified 6 confirmed defects and 9 missing capabilities in the display path. All six defects are resolved in MacLC.

What was broken in upstream VLC What you saw on screen What MacLC does
Display headroom read once, from the main screen Drag the window to a second display, HDR brightness stayed wrong. Re-measured on every screen, window-move and display-profile change.
The HDR mode selector and brightness slider in Preferences did nothing The settings were decorative. Both wired live — they take effect during playback.
No tone-mapping path to SDR HDR film on a normal display clipped to flat white. A real conversion, with a correct fallback on older macOS.
Subtitles untagged over HDR video White subtitles rendered at full HDR luminance — searingly bright over dark scenes. Subtitles pinned to SDR and scaled to the ITU-R BT.2408 203-nit reference white.
Video above 10-bit downsampled to 8-bit 12-bit and 16-bit sources lost detail before reaching the screen. Full 10-bit path preserved; 16-bit 4:2:2 wired through.
Sub-4K HDR mis-tagged, zero-nit mastering volume emitted Wide-gamut content played through the wrong primaries. Correct tagging per stream.

New capabilities beyond the fixes

01

Hardware AV1 on M3 & M4

VideoToolbox, gated on real hardware support. Falls back to software elsewhere. Confirmed available on M3 Max.

02

HDR10+ Dynamic Metadata

Carried end-to-end through the filter chain.

03

Dolby Vision Metadata Extraction

From the VideoToolbox bitstream, with hardened parsers, including a fix for Dolby Vision being lost to a stray bit on the very first frame.

04

ARM64 NEON Chroma Conversions

Hand-written ARM64 NEON chroma conversions replacing scalar loops on the software-decode path.

05

OpenGL 4.1 / 3.2 Core Profile

64-bit colour unblocks libplacebo's shaders. Upstream failed with "OpenGL version too old (2 < 3)".

06

Mastering Metadata Forwarding

Mastering-display (ST 2086) and content-light-level (CTA-861.3) metadata forwarded correctly.

07

Per-Window ICC Profile

Taken from the window's own screen rather than the main one.

The four HDR modes

MacLC avoids opaque video processor flags. Every mode describes its pipeline behavior in terms of what you will actually see on your screen.

Automatic Recommended

Detects display capabilities and source metadata to route HDR natively or convert gracefully.

Always use HDR

Forces HDR presentation on supported displays, expanding SDR media into extended headroom.

Convert HDR to SDR

Tone-maps high dynamic range video for displays without extended dynamic range.

Turn HDR off

Bypasses all HDR processing and Metal shader pipelines for standard direct presentation.

Live Pipeline Status
Connected Display Liquid Retina XDR
Measured Headroom 6.15×
Active Video Engine AVFoundation / Metal Compute
Current Stream Nothing is playing. Panel headroom measured and ready.

HDR Mode

Highlights lift into panel headroom while shadows and mid-tones hold still.

Target Peak Boost 4.0×
Brightness headroom tracking

Re-measures headroom on every window move and display profile change.

Advanced HDR & Colour Pipeline
13 verified options
Tone-mapping curve

10 algorithms: hard clip, BT.2390 EETF, Reinhard, Mobius, Hable, gamma-power, linear stretch, BT.2446A, single-pivot spline.

BT.2390 EETF
Tone-mapping parameter

Controls knee placement and compression rolloff.

0.50
Gamut mapping

7 modes for BT.2020 wide-gamut translation into display native primaries.

Perceptual (BT.2407)
Inverse tone mapping

Metal quadratic highlight expansion above half SDR white.

Dithering

Blue noise temporal algorithm prevents 10-bit to 8-bit banding artifacts.

Blue Noise (Temporal)
Per-window ICC colour management

Samples the active window screen profile rather than the primary display profile.

Interface reconstruction.

Interface reconstruction. The live status block and mode selector in MacLC's HDR & Colour preferences.

The advanced option list

Presented as reference, not marketing. Thirteen configuration controls declared across the HDR & Colour pipeline, each verified against its backing engine module.

01 libvout_display

Live Status Telemetry

Reports connected display model, measured brightness headroom, active video engine, and stream transfer function during playback.

Idle state: "When nothing is playing, it says so plainly." · Re-measured on every screen, window-move and display-profile change
02 vlchdr_edr

Brightness Headroom Tracking

Selects whether brightness headroom is tracked automatically or set manually.

Modes: Automatic | Manual (1.0×–16.0×)
03 vlchdr_tonemap

Tone-Mapping Curve (10 Algorithms)

Controls how out-of-range specular highlight luminance is compressed into target display volume. Exposes all algorithms declared in engine:

  • Hard Clip: Discards luminance above target ceiling with zero knee compression.
  • BT.2390 EETF: ITU-R standard Electrical-Electrical Transfer Function with hermite spline rolloff.
  • Reinhard: Classic photographic rational tone reproduction curve.
  • Mobius: Smooth knee preserving local shadow and mid-tone contrast.
  • Hable: Film-grade shoulder curve from Uncharted 2 filmic tonemapping.
  • Gamma-Power: Exponential power curve compression.
  • Linear Stretch: Proportional scalar compression across full signal range.
  • BT.2446A: ITU-R broadcast Method A television tone-mapping curve.
  • Single-Pivot Spline: Continuous C1-smooth cubic spline pivot curve.
04 vlchdr_tonemap

Tone-Mapping Parameter

Fine-tunes the knee threshold, rolloff slope, or contrast exponent for whichever curve algorithm is currently selected.

Range: 0.00–2.00 (Default calibrated per curve)
05 vlchdr_gamut

Gamut Mapping (7 Modes)

Translates wide-gamut coordinates into display primaries: Perceptual, Relative Colorimetric, Saturation, Absolute Colorimetric, Clip, Highlight Desaturate, Dark Desaturate.

Prevents out-of-gamut hue shifts on saturated neon and sky colors
06 VLCHDRExpander

Inverse Tone Mapping

Enables the highlight expansion shader for SDR content, scaling highlights above the knee at half SDR white into display headroom.

Boost multiplier: 1.0× to 16.0× (1.0× disables)
07 vlchdr_dither

Spatial Dithering

Mitigates quantization banding when reducing 10-bit or 12-bit pipeline buffers to 8-bit or standard panel depths.

Algorithms: Triangular dither | Blue noise | Error diffusion | Off
08 vlccolor_icc

Per-Window ICC Color Management

Applies display ICC profiles queried per window rather than system-wide default, preserving calibration on multi-monitor setups.

Per-window ICC profile taken from the window's own screen rather than the main one
09 vlchdr_metadata

Mastering Display Metadata (ST 2086)

Forwards mastering display color primaries and minimum/maximum display luminance metadata to AVFoundation without alteration.

Preserves mastering volume integrity end-to-end
10 vlchdr_metadata

Content Light Level (CTA-861.3)

Parses and forwards MaxCLL (Maximum Content Light Level) and MaxFALL (Maximum Frame-Average Light Level) per stream.

Prevents arbitrary OS clipping on intense frames
11 vlcvout_subtitles

Subtitle Luminance Clamping

Pins subtitle rendering to SDR and scales white text to the ITU-R BT.2408 203-nit reference white over HDR backgrounds.

Pins subtitles to SDR and scales to the ITU-R BT.2408 203-nit reference white
12 videotoolbox_av1

Hardware AV1 Acceleration

Gates VideoToolbox hardware decode specifically for Apple M3 and M4 chips, falling back to multi-core software decode elsewhere.

Hardware AV1 decode on M3 and M4; software fallback elsewhere
13 videotoolbox_dovi

Dolby Vision RPU Parser

Hardened bitstream parser extracting dynamic metadata, with correction for stray bit corruption on the initial stream frame.

Hardened bitstream parser with first-frame bit correction

What this does not do

It will not invent detail that was never captured.

SDR → HDR needs a display with real extended range (XDR or an HDR external panel); on an SDR display it does nothing at all.

Skipped automatically for sources already in PQ or HLG.

System Requirements

Version 0.9.0 · beta
Architecture Apple Silicon (M1 or newer)
Operating System macOS 13 Ventura or later
Display Hardware Apple Silicon display with extended dynamic range (Liquid Retina XDR, Pro Display XDR) or external HDR monitor
AV1 Hardware Decode M3 or M4 for hardware AV1 decode

Free and open source under GPL v2+ · No account or payment required

Frequently asked questions about HDR on macOS

Real questions about macOS display pipelines, subtitles, formats, and headroom — answered factually in the engineer’s voice.

01

Why does HDR look washed out or too dim on my Mac?

When an HDR film is played without a proper tone-mapping path to SDR, highlights clip to flat white. Upstream VLC had no tone-mapping path to SDR; MacLC provides a real conversion, with a correct fallback on older macOS. In the HDR preferences, MacLC provides four named modes: Automatic (recommended), Always use HDR, Convert HDR to SDR, and Turn HDR off. For custom workflows, the Advanced options expose ten tone-mapping curve algorithms, including BT.2390 EETF and BT.2446A.

02

Why do HDR subtitles look painfully bright?

In upstream VLC, subtitles untagged over HDR video rendered white at full HDR luminance — searingly bright over dark scenes. MacLC resolves this by pinning subtitles to SDR and scaling them to the ITU-R BT.2408 203-nit reference white.

03

Does macOS support Dolby Vision and HLG?

MacLC extracts Dolby Vision metadata from the VideoToolbox bitstream using hardened parsers, including a fix for Dolby Vision being lost to a stray bit on the very first frame. It also carries HDR10+ dynamic metadata end-to-end through the filter chain, and automatically skips highlight expansion for sources already in PQ or HLG.

04

Can I get HDR from ordinary SDR video on a Mac?

Yes, on a display with real extended range (XDR or an HDR external panel). MacLC’s Metal compute shader (VLCHDRExpander, 895 lines) re-encodes each SDR frame into 10-bit BT.2020 PQ on the default AVFoundation display path. The expansion is the identity at and below a knee at half SDR white, and quadratic above it — shadows and mid-tones reach your eye at exactly the brightness they always did, while highlights are lifted into spare panel headroom. On an SDR display it does nothing at all, and it will not invent detail that was never captured.

05

Which Macs decode AV1 in hardware?

Hardware AV1 decoding is available on Apple Silicon M3 and M4 chips via VideoToolbox, gated on real hardware support and confirmed available on M3 Max. Where hardware decode is unavailable, MacLC falls back to software decoding accelerated by hand-written ARM64 NEON chroma conversions.

06

What is display headroom?

Display headroom is how much brighter a display can go above SDR white. An XDR display can go five to six times brighter than SDR white, with 6.15× display headroom measured on an M3 Max. Display headroom is re-measured on every screen, window-move and display-profile change. The effective boost is min(your setting, the screen's real headroom), so it can never ask for more than the panel has.

07

Does SDR to HDR work on an SDR display or external monitor?

SDR → HDR needs a display with real extended range (XDR or an HDR external panel); on an SDR display it does nothing at all. On an external HDR panel, MacLC takes a per-window ICC profile from the window's own screen rather than the main one, and forwards mastering-display (ST 2086) and content-light-level (CTA-861.3) metadata correctly.