Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New LUT calibration based on mp4 test videos (part I) #896

Merged
merged 74 commits into from
Nov 8, 2024

Conversation

awawa-dev
Copy link
Owner

@awawa-dev awawa-dev commented Jul 7, 2024

I don't know what the final effect will be, but since AI is currently very popular ;) Let's use Deep Learning Function Approximation to calibrate SDR/HDR/whatever video source. We will use Python and its related libraries here but it is an optional functionality and you do not have to use it nor will we install it: it must be present in the system.
But first, let's sort out the calibrator code because it needs cleaning before further work. We will use a new library for linear algebra that will help us.


Main changes (non-AI):

  • Old method using Windows 10 and a web browser is no longer mandatory, you can use the old method using browser or simply play the video test file in your favorite video player.

  • New algos that support even video source trans-coded to full BT2020 range and provide better quality

  • Captured colors are saved in the HyperHDR directory after calibration as calibration_captured_yuv.txt and can be provided to me for analysis if I have some spare time.

  • Support only for YUV/NV12/MJPEG modes. RGB mode is not supported anymore.

  • Confirmed support for webos calibration with backend that supports NV12 flatbuffers communication. Each webos mode (SDR/HDR/DV) may require its own calibration.

  • Grabber benchmark supports flatbuffers source

  • Video source noise detection

  • multi-threading support for calibration and LUT creation. But what we gained by using all cores went to...

  • LCH color corrector. Jokes aside, this algorithm eats up huge amounts of CPU resources, but I think the effect is worth it because we get clean main colors and I didn't notice any side effects. If anything, you can disable it. More at the end.

  • Increased the number of test vertices focusing on the most problematic issues: yellow (green shift) and magenta (red shift).

  • USB grabber and flatbuffer server are disabled during calibration to save resources. We enable them at the end. Known issue: there is some issue on the webos client side that does not detect that the connection has been lost and does not reconnect it later. You have to manually restart the piccap service.

  • Added PQ in sRGB linear signal detection for AV access grabber. You can see in the first post what this grabber is capable of due to its wide range, it avoids quantization characteristic of all other grabbers.

  • Added 2-step calibration which allowed to speed up the whole process. The first step is general and is only intended to detect the appropriate tactic. The second step is detailed.

  • Moved calibration to a separate thread. Thanks to this we do not block the interface which now displays information about the progress on an ongoing basis.

  • Change some backlight behavior: only turn on the background light if the LED would otherwise be off.

  • If calibrating using Windows (using the web browser or the video player as a video source) please disable features like 'Night mode' or 'Auto-HDR'. Do not change the color balance in your graphic driver.


Video test files:
https://github.com/awawa-dev/awawa-dev.github.io/tree/master/calibration
Use SDR video only if your OS or video player will automatically apply SDR to HDR tone mapping. Or if you are calibrating eg. webos.

The web browser method and playing yuv444 file usually provides the best calibration quality but yuv444 is supported probably only by the PC players. yuv420 has better compatibility but worse quality (the risk the player is starting using its own filters like dithering).


Presenting capabilities of new tone mapping algos:

Source desktop (Windows 11 HDR enabled):
source

AV Access 4KVC00 (this wide-range grabber was ahead of its time + HDR/SDR detection on the COM port 👍 )

Captured by MS2130 (F3 firmware !!!) with and without tone mapping:

@awawa-dev
Copy link
Owner Author

awawa-dev commented Oct 31, 2024

I've managed to calibrate using extended P010 range: result ~75 (yuv 420 limited) without tweaking anything and the perfect image without quantization. I have to think whether to throw the RPi in the trash since it doesn't support P010 or whether the current result will be enough for me... At most, there will be another tutorial on the blog :)

@satgit62
Copy link

satgit62 commented Oct 31, 2024

@awawa-dev
Hi, looks good under Windows, I stumbled across this patch during my research. It should be possible to enable the P010 video format for Linux as well. What do you think? As I have seen, this was never implemented.
https://patchwork.linuxtv.org/project/linux-media/patch/[email protected]/#137507

@awawa-dev
Copy link
Owner Author

awawa-dev commented Oct 31, 2024

Hi @satgit62
havent test it yet, but it doesn't look good...

If you look at the logs when HyperHDR is being built https://github.com/awawa-dev/HyperHDR/actions/runs/11621071484
I added a checkpoint to the source code.

So we have for RPi Bookworm:

#pragma message "P010 is supported on the build machine"

so theoretically the patch is not needed.

In Ubuntu24.04 also:

#pragma message "P010 is supported on the build machine"

but in the older Ubuntu 22.04:

#pragma message "P010 is NOT supported on the build machine"

Of course this only means the presence of P010 in the header files, it does not mean that the kernel supports it.

We are slowly moving here: #967

@satgit62
Copy link

satgit62 commented Nov 1, 2024

https://patchwork.linuxtv.org/project/linux-media/patch/[email protected]/#137507

It's unfortunately already merged and doesnt work... https://github.com/raspberrypi/linux/blob/4622323f5c9e540f3356f2229c4d551b31cc234d/drivers/media/v4l2-core/v4l2-common.c#L279 https://github.com/raspberrypi/linux/blob/4622323f5c9e540f3356f2229c4d551b31cc234d/drivers/media/v4l2-core/v4l2-ioctl.c#L1358

@awawa-dev
Hello,
Thanks for trying to add the P010 driver for Linux as well. It is unfortunate that does not work. Probably needs to be integrated directly into the kernel. A pity in itself, because almost everyone has a Raspberry Pi. But you have integrated it into the Windows version. At least it's an alternative to the calibration procedure.
I have a question about the webOS HyperHDR.
Since in this case the data comes from hyperion-webos via flatbuffer and not via USB Capture, the video device and the video mode are not displayed on the information page.
Would it be possible to add/change this for flatbuffer so that at least the video mode is displayed under the webOS version?

Information

@awawa-dev
Copy link
Owner Author

awawa-dev commented Nov 1, 2024

Who knows.. maybe I'll add P010 support for the grabbers I have myself, although I was hoping that I had finished developing at the kernel drivers level after my adventure with tvboxes ;-) It's possible that elgato is a broken exception (even Corsair claims that Linux is not supported) and these new grabbers with new chipsets will be supported

Would it be possible to add/change this for flatbuffer so that at least the video mode is displayed under the webOS version?

There is a significant difference: for grabbers you set these settings in the grabber properties and for flatbuffers these settings are dynamic based on what's came

@awawa-dev awawa-dev merged commit 81a93c4 into master Nov 8, 2024
15 checks passed
@awawa-dev awawa-dev deleted the ai_calibration branch November 8, 2024 01:18
@awawa-dev
Copy link
Owner Author

awawa-dev commented Dec 2, 2024

Just for your information: we found a bug (I guess we can call it that) in the Kodi (at least Intel is confirmed) configuration where it turns out that HDR test files must have a master-display tag for HDR passthrough to be enabled at all. Otherwise, you risk calibrating SDR mode, because Kodi will treat the HDR test file that way.
More details can be found here: #997
The HDR test file (yuv420 limited) has been updated with a new tag.

@awawa-dev
Copy link
Owner Author

I created a small tutorial, not as detailed as @satgit62's :) but I needed some documentation for HyperHDR too: https://github.com/awawa-dev/HyperHDR/wiki/lut-calibration
BTW there was also another quite serious bug in the calibration fixed before the merge into the PR P010 main branch, but it was rather related to USB grabbers not webOS. At least in the webOS logs I have, the YUV range was always in fact limited. And as it turned out, it wasn't only the P010 format that was affected by the bug: my Elgato also likes full range for YUV mode. #967 (reply in thread)

@awawa-dev
Copy link
Owner Author

awawa-dev commented Dec 8, 2024

@satgit62 @NatyaSadella @s1mptom
There is a bug in the webOS backend with merged nv12 support that causes SDR to not work outside the calibration: backend always turns the tone mapping off when SDR on webOS is detected. Tone mapping must be always enable, otherwise createting a separate LUT for SDR does not make sense:
#1012

@awawa-dev
Copy link
Owner Author

The bug is here: https://github.com/webosbrew/hyperion-webos/blob/a27ad43d4c6e961c53a7534de723866307aee667/src/json_rpc_client.c#L202
You can also turn tone mapping on manually for SDR to compare the result in the live preview...

@satgit62
Copy link

satgit62 commented Dec 8, 2024

Thank you @awawa-dev,

I'll take a look at that.

If this is a bug, then it was like this from the beginning and made sense for a single LUT.
In the UI interface of PicCap under Advanced Settings you can switch this off and if tone mapping is switched on in Flattbufer, HDR (Global) always remains switched on even with SDR. However, no SDR LUT is loaded if you switch back from HDR to SDR.
It must then be changed in the backend.
Diable SDR HDR

@awawa-dev
Copy link
Owner Author

awawa-dev commented Dec 8, 2024

This method containing a bug also manages LUT switching and I don't see that the option you mention is considered there. Maybe it is checked before and then it is not called at all. Generally for webOS one LUT does not make sense: SDR is not SDR on webOS, so a special LUT is needed. If you disable tone mapping while having one LUT for HDR or SDR, webOS SDR colors will definitely not be fixed correctly just a standard NV12 to RGB. To summarize: on webOS tone mapping should always be enabled, the distribution should contain several LUTs or a note that it is only intended for eg. HDR having only one LUT.

@satgit62
Copy link

satgit62 commented Dec 8, 2024

This method containing a bug also manages LUT switching and I don't see that the option you mention is considered there. Maybe it is checked before and then it is not called at all. Generally for webOS one LUT does not make sense: SDR is not SDR on webOS, so a special LUT is needed. If you disable tone mapping while having one LUT for HDR or SDR, webOS SDR colors will definitely not be corrected correctly. To summarize: on webOS tone mapping should always be enabled, the distribution should contain several LUTs or a note that it is only intended for eg. HDR having only one LUT.

Yes, the preview image is better with HDR switched on with SDR.
So instead of 0 (zero) there is a 1 (one). Correct?

jobject_set(post_body, j_cstr_to_buffer("HDR"), jnumber_create_i32(range == SDR ? 1 : 1));

@awawa-dev
Copy link
Owner Author

or just 1
jobject_set(post_body, j_cstr_to_buffer("HDR"), jnumber_create_i32(1));
but still the user needs to have multiple LUTs: not just one.

@satgit62
Copy link

satgit62 commented Dec 8, 2024

or just 1 jobject_set(post_body, j_cstr_to_buffer("HDR"), jnumber_create_i32(1)); but still the user needs to have multiple LUTs: not just one.

Yes, that is correct, we already use different LUTs.
Thanks again for your advice.

@satgit62
Copy link

satgit62 commented Dec 9, 2024

@awawa-dev
By making the above change in ‘json_rpc_client.c’, the tone mapping also works with SDR content (HDR-Global remains switched on) and the correct LUT table is also loaded.
Do we now have to make a new calibration for SDR?

@awawa-dev
Copy link
Owner Author

awawa-dev commented Dec 9, 2024

No need to recalibrate SDR LUT if you have one. Simply that calibrated LUT didnt work after calibration if tone mapping was disabled. The difference should be visible in the video live preview on some SDR content while switching tone mapping on & off when SDR LUT is selected.

@awawa-dev
Copy link
Owner Author

awawa-dev commented Dec 9, 2024

I think the mistake could have been because there is no SDR on webOS like in the case of grabbers (even when the input signal was in SDR format). It is the same mode that requires correction like HDR or DV. So if we are dealing with calibrated LUTs, tone mapping must always be active to apply this correction from the selected LUT.

@NatyaSadella
Copy link

So my system isn't working correctly when HyperHDR shows:

[FLATBUFSERVER] (LutLoader.cpp:74) Index 2 for YUV
[FLATBUFSERVER] Found and loaded LUT: '/home/XYZ/.hyperhdr/lut_lin_tables.3d'

when I switch from HDR to SDR?

If I toggle HDR in HyperHDR when watching SDR content, the live preview is barely different. Only a slightly red hue is added to the picture. HDR toggle off looks like Warm40 on LG OLED's white point settings and HDR toggle on looks like Warm50.

When I toggle HDR on while watching SDR, HyperHDR shows the same lines in the log. So in both cases the same LUT is "found and loaded", doesn't matter if the toggle is on or off.

@awawa-dev
Copy link
Owner Author

awawa-dev commented Dec 9, 2024

[FLATBUFSERVER] Found and loaded LUT: '/home/XYZ/.hyperhdr/lut_lin_tables.3d'

Does this LUT is calibrated for SDR? Or it's shipped with the package on webos?

[FLATBUFSERVER] (LutLoader.cpp:74) Index 2 for YUV

Index 2 is just basic decoding NV12 to RGB without any correction from the calibration (tone mapping is DISABLED). Index 1 is calibrated for NV12 and Index 0 is calibrated for RGB (tone mapping is ENABLED).

@NatyaSadella
Copy link

The lut_lin_tables.3d file is the calibrated SDR LUT. I have three LUT's, one for SDR, HDR and DV.

@awawa-dev
Copy link
Owner Author

There is a verification procedure for SDR: #1000 (comment)

@awawa-dev
Copy link
Owner Author

awawa-dev commented Dec 9, 2024

[FLATBUFSERVER] (LutLoader.cpp:74) Index 2 for YUV

This indicates that you have disabled tone mapping in flatbutffers configuration if Index does not switch to 1 when you enable tone mapping.

@satgit62
Copy link

satgit62 commented Dec 9, 2024

@NatyaSadella

Hello,
You can test my hyperion-webos backend, it runs as @awawa-dev has intended.
Download: https://github.com/satgit62/hyperion-webos/actions/runs/12232031341/artifacts/2292506957

Here I have made the change:
https://github.com/satgit62/hyperion-webos/tree/nv12

@NatyaSadella
Copy link

@satgit62 Thank you but I'm not really sure if I should do that. I need a way to have different LED gamma values at different picture modes and if HyperHDR is in HDR-always-on mode that wouldn't work anymore

sundermann added a commit to sundermann/hyperion-webos that referenced this pull request Dec 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants