"Fake" HDR10 on Linux
#1
Hi Folks,

I am running Kodi on Linux using somewhat old hardware that does not have any HDMI 2.0 support. I still found a way to get somewhat fake HDR10 playback through to my Epson EH-TW7100 projector that I want to let you guys know and maybe correct me if my approach has a weakness or a flaw that I am not aware of.

I have done a lot of digging into what HDR10 means w.r.t color primaries, color transfer characteristics/transfer function and color matrix/colorspace. Just wanted to get some feedback on my hacky approach.

I have a solution that works for me, I just want to double check if I can improve it further with what I have, short of buying new hardware.

The Problem:
My hardware only supports 4k30 RGB 8-bit output, no HDR Infoframe support, so no color primaries / color transfer function metadata.
Kodi assumes the display device has bt709 primaries and transfer function and performs the appropriate conversions (primaries, transfer function i.e. tonemapping) when playing back a 4k HDR10 file with bt2020 metadata after using the (inverse) bt2020nc matrix to convert YUV to RGB.
While the tonemapping function can be easily disabled in the playback settings, the conversion of the primaries cannot.

My Idea:
I can manually set the Projector to using the bt2020 primaries and transfer function, even when it receives only a mere 8 bit RGB signal.
This means i want Kodi to only use the bt2020nc matrix to convert the YUV to RGB but then pass the resulting RGB unchanged (apart from rounding/dithering down to 8 bits) to the output.

side note: The projector also has a setting for full range/limited range which I have set to limited range and also enabled limited range playback in kodi to avoid any level adjustments until the very last moment when the projector applies its transfer function, as most files actually use limited range. I could change both to full range to maybe get a little more precision, but this would be another setting i would constantly have to change in the projector when using other sources

My Solution:
I manually change the metadata of my HDR10 files to the following without changing the actual video data:
  • primaries = bt709 (instead of bt2020)
  • trc (transfer funtion) = bt709 (instead of pq/smpte2084)
  • matrix (what ffmpeg calls colorspace) = unchanged (typically bt2020nc)
  • range = unchanged (typically tv)
This would cause Kodi to use the (inverse) bt2020nc matrix for YUV to RGB conversion, but perform no further color correction w.r.t. primaries or trc and just output the RGB versions as produced by the (inverse) bt2020nc matrix, because the primaries and trc match perfectly the assumption of outputting to a bt709 display.

side note: I do this using ffmpegs metadata bitstream filter. I may also transcode to x264 with tune=film,fastdecode (keeping 10bpc), but this is just so my cpu is fast enough to decode in realtime. In that case I can use the setparams filter instead, which also does not change the actual video data. I use a recent enough version of ffmpeg that actually puts the metadata in the x264 stream and i neither need to use the separate -colorspace, -color_range, -color_primaries, -color_trc arguments nor the similar -x264opts argument. I can verify the resulting metadata in the output using ffprobe or mediainfo.

The Drawbacks I am well aware of:
  • I have to switch manually the Color Primaries and Transfer function in the projector each time.
  • Dropping to 8 bits introduces some noise from the dithering and/or some visible banding. This is why HDR needs 10 bits in the first place. I am aware of this.
  • When the modified files are played back on a different setup (where the display device is not manually switched to bt2020 primaries and transfer function) the output will be wrong.
My Experience so far:
  • Dithering gets almost completely rid of any banding. The introduced noise is almost invisible to my eye.
  • Comparing the resulting image with proper HDR10 sources (like prime video on a chromecast with google tv attached via hdmi 2.0) yields only negligible visible differences.
Possible Improvements:
  • If Kodi had a setting to disable automatic color conversion for the primaries, I wouldn't have to produce files with fake metadata and could achieve the same.
Reply
#2
(2022-01-23, 22:47)sunday Wrote: I am running Kodi on Linux using somewhat old hardware that does not have any HDMI 2.0 support.
..
My hardware only supports 4k30 RGB 8-bit output, no HDR Infoframe support, so no color primaries / color transfer function metadata.

It's quite an opening post and I am by no mans a video guru, but to begin with what hardware are you using, and which Linux OS is running on it?
AFAICT, a Raspberry Pi 4b can already improve on that, although it's hard to get one of them these days.
Reply
#3
It's an AMD A10-7860K with integrated Radeon R7 graphics on an ASRock A88M-ITX/ac board running Arch Linux with vanilla Kodi. Hardware decoding is limited to H264 1080p. It does not have enough cpu power to decode 4k 10bit HEVC content (some files it does play fine, but others not), but does fine consistently on 4k 10bit H264 with -tune fastdecode.

I never really planned the upgrade to 4k UHD, but my old projector (EH-TW5910) died and I had to get a new one. So I am just trying to get the most of what I have, since there is currently no budget for new hardware.
Reply

Logout Mark Read Team Forum Stats Members Help
"Fake" HDR10 on Linux0