HDR guide

HDR transcoding and tone mapping on a home media server

What a server reads as HDR, which graphics backend converts it on the card and which one leaves the job to the processor, and which clients never ask for the conversion at all.

By Quven Editorial Team Updated 7 September 2026 Verified 7 September 2026

Tone mapping is needed when the file carries HDR and the display or the playback path wants SDR. It isn’t a brightness adjustment: you’re squeezing a wide luminance range into a narrow one, and the job is to keep the detail in the highlights and the shadows while doing it. Where your server does that squeezing, and whether it should be doing it at all, will decide what a 4K film costs you.

What the server reads as HDR

Two signals, both taken off the probe and not off the filename. A source counts as HDR10 when its transfer function is SMPTE ST.2084, the PQ curve, or when it carries mastering-display or content-light-level side data, which will stay a reliable signal even on a file whose transfer characteristic went missing somewhere along the way. A source counts as HLG when the transfer function is ARIB STD-B67, the broadcast curve. Either one puts the file in the same bucket, and from there the server can’t avoid asking whether the destination needs SDR.

Dolby Vision has no branch of its own in that decision. The scanner does read the profile and the level out of the stream, and your library statistics will count those files under a dynamic range of their own, so the Statistics tab should show them separately. What the streaming decision looks at is the transfer function. Most of what you’ll rip carries a Dolby Vision layer over an HDR10 base, that base signals PQ, and the file will be converted as HDR10 with the per-scene metadata left uninterpreted.

Convert only when the destination needs it

Desktop and mobile apps tell the server they can open the file themselves, which sends the session down the direct-file route before a single capability gets compared. The HDR test is never reached there, even though the file is HDR, and the bytes leave the machine as they sit on disk. Both profiles declare HDR10 in any case, so a session that somehow falls through to HLS won’t lose its range either.

But browsers are the interesting half. The modern browser profile covers H.264 through AV1 at up to 4K and 25 Mbps, and it leaves HDR10 out deliberately, so an HDR film played in a tab will be tone mapped unless the viewer asks otherwise. AirPlay receivers keep HDR10 and take HEVC, so an Apple TV should get the range as it was authored. A Chromecast’s default receiver takes H.264 and AAC and nothing besides, which means an HDR title cast from a phone must be converted on both counts, once for the codec and once for the range.

Every conversion you skip keeps the quality intact and leaves a core free for a session that has no choice.

Which backend does the tone map

Six encoders can end up serving a transcode, and only some of them will do the HDR conversion on the graphics hardware. So which one is yours? NVIDIA is the plain case: an NVENC or CUDA session pushes the work through libplacebo on a Vulkan device, and that device is picked independently of the encoder, discrete adapters first and integrated ones after, with software rasterisers and virtual devices excluded outright.

Intel Quick Sync uses its own video-processing unit instead, and the reason is size. Measured on a 4K HDR title, thirty seconds of content took 3.43 seconds through the Quick Sync unit against 27.4 seconds through libplacebo on that same integrated chip. VAAPI on Linux will also convert inside the video-processing unit, which covers Intel and AMD graphics alike, so long as the decoded frames are still sitting on the device. Where the decode fell back to software there’s nothing on the card to filter, so the processor chain runs and the result must be uploaded for the encoder.

AMD’s AMF backend on Windows and Apple’s VideoToolbox on macOS encode on the hardware and tone map on the processor. If you run a Radeon under Windows, that’s your answer, and the same card in a Linux host would put the conversion back on the GPU through VAAPI. It’s the one place where the operating system under your server changes what the hardware costs you.

Auto takes the first backend that validates, in the order NVENC, Quick Sync, VAAPI, VideoToolbox, AMF, then on Linux a codec-backed V4L2 device. You can override it under Settings on the Quality tab, at Server transcoding, which is an administrator’s control. What your own machine validated is listed as chips on the Info & Diagnostics tab under Hardware acceleration backends, and a backend that never passed its runtime probe won’t be offered there.

The picture shouldn’t change when the backend does

The operator is Hable everywhere. The software chain converts to linear light at a nominal peak of a hundred nits, tone maps with Hable and no desaturation, then comes back out at BT.709; libplacebo is handed the same Hable operator on purpose so that the two should match. And that’s worth more than it sounds. If moving your server from the processor to the graphics card changed the grade, a measurement taken before the move could tell you nothing about one taken after it.

When a card drops out mid-session

A hardware session that dies before it writes its first segment isn’t simply failed at you, because the server will relaunch it with software decode and the hardware encoder kept, tone mapping on the processor for that attempt. If the second launch dies the same way, the backend is marked tainted, the session restarts fully in software, and every later session in that process will go straight to libx264 without asking again.

The log narrates all of it, so you don’t have to guess. You’ll find Hardware decode failed at startup on {backend}; retrying with software decode for the first step and Hardware acceleration {backend} tainted for the second. That flag lives in memory, so restarting the server clears it and the backend can be probed afresh. Two more lines are worth recognising. GPU HDR tonemap support detected: False means the libplacebo filter or the Vulkan device never came up, and a warning that a named Vulkan device corrupts its frame transfers means that device failed the check added after a server turned up producing corrupted colour on hardware that advertised support.

Capacity planning needs real media

Resolution, source codec, bit depth, burnt-in subtitles, output bitrate: every one of them moves the cost of a transcode, and HDR and burn-in together are the heaviest thing the server does, because the overlay wants the frame back in system memory and only NVIDIA and Quick Sync can hold on to the hardware encoder through it. On any other backend that combination will drop the whole session into software, and a library full of disc rips with bitmap subtitles is exactly where you’ll meet it. The disc guide covers what picking one of those tracks costs.

Pick a 4K HDR file that stands for your library, the kind you’d actually watch on a Friday, and play it through the client and the network you’ll actually use, for long enough that the encoder settles. A capability probe can tell you a device is there, and that’s about all it can tell you, because only sustained load, over a whole film and through the client and the network somebody will actually use, will tell you whether playback holds up, and that’s what to measure.

In order of preference. Direct HDR playback first. Then an accelerated tone-map path that’s survived a real session. Then the processor, which goes everywhere and wants generous headroom at high resolution.

Frequently asked questions

Why does my Radeon encode without tone mapping?

Because you’re on Windows, where the AMF backend does the encode on the card and hands the HDR conversion to the processor. Linux is where that changes: an AMD card there is driven through VAAPI, whose video-processing unit will convert the frames in place while they’re still on the device.

My server used the graphics card yesterday and uses the processor today. What changed?

Most likely a session failed at startup and the backend was dropped for the life of the process. Search the server log for tainted and you should see which one it was and when it happened. Restarting the server clears that state and probes the backend again; if it fails a second time you have a real fault to look at instead of a stale flag.

Can I stop a browser from tone mapping an HDR film?

Yes. Settings, Quality tab, Keep HDR (no SDR tonemap) will keep the HDR10 picture through a transcode, and the description beside it names the browsers that can render one: Safari, Edge, or Chrome with HEVC. Leave it off if HDR doesn’t look right on your screen, since an SDR monitor handed an HDR stream is where that grey picture comes from. The desktop app sidesteps the question by taking the file whole.

Does the server understand Dolby Vision?

It reads the HDR10 base layer nearly every Dolby Vision file carries and converts on that. The dynamic per-scene metadata is recorded during the scan and counted in your statistics, and it isn’t interpreted for a tone map. Playing the file untouched on a desktop or mobile app leaves the whole stream alone, that layer included, and what your display makes of it is then between the player and the panel.

Bring your library home.

Free for home use and yours to run on your own hardware. Install it in minutes.