HDR tone-mapping is the math that translates a 10,000-nit HDR10 or HLG signal down to your display's real peak brightness: using the BT.2390 reference curve, so highlights are compressed smoothly instead of being clipped to white or washed out into grey, while colors and shadow detail stay intact.
If you've ever opened an HDR stream in VLC on a non-HDR monitor and thought "why does this look like washed-out grey soup?": you've met a broken tone-mapper. This guide explains what tone-mapping is, the four algorithms that matter in 2026, and what to look for in a player that claims to support HDR.
- What HDR tone-mapping actually is
- Why most IPTV players get it wrong
- HDR10 metadata: MaxCLL, MaxFALL, mastering display
- BT.2390: the reference SMPTE algorithm
- BT.2446a, b, c, three different tools for three problems
- Hable, Reinhard and the "film curve" school
- Dynamic tone mapping: why static fails on commercials
- What to look for in an HDR-capable IPTV player
- TL;DR
- Frequently asked questions
What HDR tone-mapping actually is
Your TV channel ships in HDR10: a 10-bit signal encoded in BT.2020 color space, with a Perceptual Quantizer (PQ) transfer function that can describe brightness up to 10,000 nits. Your monitor (let's be realistic) peaks at 400 nits, covers maybe 95% of DCI-P3, and runs on a sRGB gamma curve. Tone-mapping is the math that translates one to the other without throwing the picture in the trash.
There are three things tone-mapping has to do at once:
- Luminance compression, bring values up to 10,000 nits down into the 0 to 400 nit range your panel can actually emit, while preserving relative brightness relationships (a candle should still look like a candle next to a streetlight).
- Gamut mapping: convert BT.2020 colors (some of which physically cannot exist on your panel) to a color space your display can reproduce, without saturating or hue-shifting.
- Transfer function conversion: go from PQ (designed for absolute brightness reference) to your display's curve, usually sRGB gamma 2.2 or BT.1886.
Skip any one of these and you get visible artifacts. Skip all three and you get the soup.
The whole pipeline is standardised in ITU-R BT.2408 ("Operational practices for HDR television") and the algorithm choices come from BT.2390, BT.2446, and BT.2407. If you want the source-of-truth, the ITU PDFs are free.
Why most IPTV players get it wrong
The quick way to put an HDR stream on an SDR screen is to run it through a generic linear-light conversion filter, slap a gamma curve on top, and ship.
That's not tone-mapping. That's clipping. Anything above 100 nits gets crushed to white. Anything below the SDR floor gets crushed to black. The midtones get squashed into a thin grey band in the middle, which is exactly the "washed out grey soup" you've seen.
Worse: that shortcut usually runs in BT.709, completely skipping the BT.2020 → BT.709 gamut conversion. So highly saturated reds and greens that exist in BT.2020 but not BT.709 just wrap around, producing the famous IPTV-HDR magenta sky.
A correct tone-mapper does this in linear light, in a perceptually uniform space (typically ICtCp or LMS), with at least a piecewise function for the highlight roll-off. Anything less is cosmetic.
HDR10 metadata: MaxCLL, MaxFALL, mastering display
Every HDR10 stream carries (or should carry) three pieces of static metadata in the SEI message:
| Field | What it means | Typical value |
|---|---|---|
| MaxCLL | Maximum Content Light Level: the single brightest pixel anywhere in the stream | 1000 to 4000 nits |
| MaxFALL | Maximum Frame Average Light Level: peak of any frame's average | 200 to 800 nits |
| MDPL | Mastering Display Peak Luminance: what the colorist saw when grading | 1000 or 4000 nits |
For IPTV, MaxCLL is the field that matters most. It tells the tone-mapper where the highlights end, so it can scale the curve accordingly. Map a 4000-nit MaxCLL stream as if it were 1000-nit and your highlights compress too aggressively: the picture gets dim. Map a 1000-nit stream as if it were 4000-nit and you waste half your panel's headroom on signal that doesn't exist.
And here's the dirty secret: a huge fraction of IPTV streams ship with no MaxCLL/MaxFALL at all, or with values that are clearly defaults from the encoder. You can't trust the metadata; you need a player that also measures the actual signal.
If you've watched a sports HDR feed where the score-bug graphic looks blinding-bright but the field looks dim, you're seeing a player that trusted bad metadata and didn't adapt to the picture's real brightness.
BT.2390: the reference SMPTE algorithm
ITU-R BT.2390 is, in 2026, the closest thing to a reference tone-mapping algorithm. It's what professional grading suites use as a fallback when there's no per-scene dynamic metadata available, and it's what serious open-source players (mpv, MadVR) default to.
The algorithm has three pieces:
1. EETF (Electro-Electrical Transfer Function)
BT.2390's EETF is a parametric curve mapping input PQ values to output PQ values. Below a knee point (typically 50% of the target display's peak), it's a 1:1 pass-through. Above the knee, it smoothly compresses toward the display peak using a Hermite spline. The math:
// Pseudocode for BT.2390 EETF
// E1 = input PQ-encoded value [0..1]
// Lw = target display peak (in PQ, normalized)
// Lmin = target display black (in PQ)
// KS = knee start = 1.5 * Lw - 0.5
if (E1 < KS):
E2 = E1
else:
T = (E1 - KS) / (1 - KS)
P = (2*T^3 - 3*T^2 + 1) * KS
+ (T^3 - 2*T^2 + T) * (1 - KS)
+ (-2*T^3 + 3*T^2) * Lw
E2 = P
The Hermite spline is what makes the roll-off smooth: the curve and its first derivative match at the knee, so there's no visible "kink" where compression starts.
2. ICtCp working space
BT.2390 specifies that tone-mapping should happen in the ICtCp color space: a perceptually uniform space where the I channel is luma and Ct/Cp are chroma. This matters because it lets you compress luma without dragging chroma toward grey. In a naïve RGB-domain tone-mapper, when you scale a (1.0, 0.8, 0.0) pixel down, the differences between channels get squashed and the color desaturates. In ICtCp you scale I and leave the chroma channels alone.
3. Gamut mapping
Finally, BT.2390 specifies a chroma-attenuation step for out-of-gamut colors. When a BT.2020 color can't be represented on the target panel, instead of clipping it to the nearest in-gamut RGB triple (which causes hue shift), the algorithm desaturates the color toward neutral along a constant-hue line until it fits. Less vivid, but the hue stays correct: your sunset stays a sunset, not a magenta postcard.
BT.2446a, b, c: three different tools for three problems
BT.2446 is younger than BT.2390 (2019 vs 2016) and addresses cases BT.2390 doesn't handle well. It comes in three flavours that solve different problems:
| Method | Designed for | Trade-off |
|---|---|---|
| 2446a | HDR → SDR for cinematic content | Best perceptual match, slightly soft highlights |
| 2446b | HDR → SDR with preserved punch | Brighter highlights, can clip if MaxCLL is wrong |
| 2446c | SDR → HDR (the inverse direction) | Not relevant for IPTV unless you're upscaling |
For IPTV the choice is between 2446a and 2446b, and the right answer depends on content. 2446a is gentler: great for movies and dramas where you want preserved skin tones and shadow detail. 2446b leaves more "punch" in highlights: better for sports, where you want the field-floodlight glare to feel bright. Some players let you pick per-channel.
If your panel is below 600 nits, BT.2390 will look more natural than BT.2446b. If you have a true HDR400 monitor and feel the picture is too flat, switch to 2446a. BT.2446b is for HDR600+ panels where you want headroom to actually feel headroom.
Hable, Reinhard and the "film curve" school
If you've used OBS, MPC-HC or any older HDR-aware tool, you've probably seen the Hable tone-map option. Hable (the algorithm named after John Hable, who designed it for the game Uncharted 2) is a parametric filmic curve: an S-curve with shoulder, toe, and linear midsection. It looks great. It's also not a calibrated algorithm.
Same goes for Reinhard (the 2002 paper "Photographic Tone Reproduction"), Hable Uncharted, and a dozen game-engine derivatives. These algorithms were designed for computer graphics, not for translating colorist-graded HDR10. They look nice. They are not reference-accurate.
The trade-off:
- BT.2390 / BT.2446, reference-accurate, what colorists expect. Slightly less "wow factor" on a consumer panel.
- Hable / Reinhard: louder, more contrasty, more "video-game HDR" look. Hides metadata errors. Not what the director saw.
For sports and games, Hable can be the more pleasing choice. For movies and graded series, the BT family will be closer to intent. Both are better than the clip-and-pray default.
Dynamic tone mapping: why static fails on commercials
Static tone-mapping (driven by MaxCLL/MaxFALL) has one fatal flaw on broadcast IPTV: the metadata describes the whole stream, not the current scene. A commercial cut to a black-and-white ad break inherits the same peak settings as the 4000-nit sports broadcast. The midtones get crushed because the algorithm is reserving headroom for highlights that aren't in the current frame.
The fix is dynamic tone mapping: the player does not rely only on the values the stream declares, it adapts the tone-map curve to the scene on screen in real time. Players expose this differently: some as a single "dynamic HDR" switch, others as separate controls for how quickly it adapts.
Each player tunes these controls its own way, so there is no single correct configuration to copy. What matters is the result on screen: dark scenes stay dark, bright scenes keep their highlight detail, and a cut between the two does not pump or flicker.
Two things are balanced here. If the adaptation is too fast, brightness visibly pumps within a scene; if it is too slow, the picture reacts late to scene changes. A well-tuned player strikes that balance for you, so you should notice neither pumping nor a delayed fade-in.
Hard cuts need their own handling: when a movie cuts from black to a bright daylight scene, a good player recognises the cut and sets the right level at once. Weaker ones let the picture open up slowly over a few seconds, like an unwanted "fade-in".
Nightmare TV runs BT.2390 tone-mapping by default on Windows and macOS, so bright highlights keep their detail. On Android TV devices the default hands HDR to the TV's own processing instead. The 4K HDR settings guide explains what each setting changes.
See real BT.2390 tone-mapping in your own IPTV stream
Nightmare TV tone-maps HDR with BT.2390 on Windows and macOS out of the box. Try the 7-day free trial on your own playlist.
Download free trial Windows 10/11 · Microsoft Store · No card requiredWhat to look for in an HDR-capable IPTV player
Now you can read the marketing copy critically. Real questions to ask:
- Does it expose the tone-map algorithm choice? If the answer is "we just do HDR", it doesn't. A serious player lets you pick BT.2390, BT.2446a, BT.2446b, Hable, or Reinhard.
- Does it support dynamic tone mapping? Look for terms like "scene-adaptive HDR", "dynamic HDR", or "dynamic tone mapping". Static-only is a deal-breaker for broadcast.
- Does it specify a working color space? ICtCp is the correct answer. RGB is acceptable for fast paths. YUV-only is wrong.
- Does it handle missing metadata? A robust player measures the signal when MaxCLL is absent or implausible (e.g. 0 or 10000 default). If it just falls back to "1000 nits assumption", it'll fail on half the streams.
- Does it know your display's peak brightness? Your 400-nit monitor and a 1000-nit OLED need different curves. If the player has one "HDR mode" that doesn't know your panel, the picture is being mapped wrong on at least one of them.
- Does it use the GPU or CPU? CPU tone-mapping at 4K60 is possible on Threadripper but painful on a normal laptop. GPU shader-based tone-mapping (libmpv's default since 2020) is mandatory for live IPTV.
If you can't answer five of these from the player's docs in 90 seconds, it does not have a real HDR pipeline.
TL;DR
- HDR tone-mapping translates 10,000-nit BT.2020 PQ signal to your panel's actual range without crushing or hue-shifting.
- Most IPTV players do clipping, not tone-mapping. That's the "grey soup" effect.
- BT.2390 is the reference algorithm: ICtCp working space, Hermite spline knee, chroma-attenuated gamut mapping.
- BT.2446a/b are alternatives: 2446a for cinematic, 2446b for sports/punch.
- Hable / Reinhard look nice but aren't reference-accurate: game-engine heritage.
- Dynamic tone mapping is mandatory for broadcast: static metadata describes the whole stream, not the current scene.
- Ask any "HDR IPTV player" the six questions above. If five of them are unanswered, the HDR is cosmetic.