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

Is it possible for MPV to gamut map Bt.2020 to dci-p3 but keep it inside a BT.2020 container? #12777

Closed
danbezerra opened this issue Oct 30, 2023 · 14 comments · Fixed by #12786
Closed

Comments

@danbezerra
Copy link

Here is my scenario: I tone map my UHD rips to SDR BT.2020 as this is the best outcome for my JVC projector, using target-prim=bt.2020 and target-trc = gamma2.4. (also using spline tone mapping).

However, I know my projector only covers the P3 color space, which is smaller than BT.2020. The projector was calibrated to BT.2020 and as far as I know, if I set the target-prim=dci-p3 I would have color related issues unless the projector is properly calibrated to P3.

Question - can MPV gamut map BT.2020 to DCI-P3, but send the information still inside a BT.2020 container? This would allow the gamut compression of any color that falls outside the DCI-P3 triangle while still sending the information in the container expected by the projector.

Thanks

@danbezerra danbezerra changed the title Is it possible for MPV to gamut map Bt.2020 to dci-p3 but send it inside a BT.2020 container? Is it possible for MPV to gamut map Bt.2020 to dci-p3 but keep it inside a BT.2020 container? Oct 30, 2023
@haasn
Copy link
Member

haasn commented Oct 30, 2023

This patch should do the trick, can you test it?

diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index 69be403933..bb17901a13 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -374,6 +374,7 @@ const struct m_sub_options gl_video_conf = {
             M_RANGE(10, 10000)},
         {"target-contrast", OPT_CHOICE(target_contrast, {"auto", 0}, {"inf", -1}),
             M_RANGE(10, 1000000)},
+        {"target-gamut", OPT_CHOICE_C(target_gamut, mp_csp_prim_names)},
         {"tone-mapping", OPT_CHOICE(tone_map.curve,
             {"auto",     TONE_MAPPING_AUTO},
             {"clip",     TONE_MAPPING_CLIP},
diff --git a/video/out/gpu/video.h b/video/out/gpu/video.h
index 890b76367c..85a2c0ef1f 100644
--- a/video/out/gpu/video.h
+++ b/video/out/gpu/video.h
@@ -138,6 +138,7 @@ struct gl_video_opts {
     int target_trc;
     int target_peak;
     int target_contrast;
+    int target_gamut;
     struct gl_tone_map_opts tone_map;
     bool correct_downscaling;
     bool linear_downscaling;
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c
index e2436f64f1..f6a0385434 100644
--- a/video/out/vo_gpu_next.c
+++ b/video/out/vo_gpu_next.c
@@ -889,6 +889,11 @@ static void apply_target_options(struct priv *p, struct pl_frame *target)
         target->color.hdr.max_luma = opts->target_peak;
     if (!target->color.hdr.min_luma)
         apply_target_contrast(p, &target->color);
+    if (opts->target_gamut) {
+        const struct pl_raw_primaries *prim;
+        prim = pl_raw_primaries_get(mp_prim_to_pl(opts->target_gamut));
+        target->color.hdr.prim = *prim;
+    }
     if (opts->dither_depth > 0) {
         struct pl_bit_encoding *tbits = &target->repr.bits;
         tbits->color_depth += opts->dither_depth - tbits->sample_depth;

Use with --target-prim=bt.2020 --target-gamut=display-p3

@danbezerra
Copy link
Author

danbezerra commented Oct 30, 2023

It may take a couple of days for me to have access to my projector again, but I will give you feedback by mid week. In the meantime, a question just came to my mind: Target-gamut=display-p3--> Is this the "real" DCI-P3 or is it P3 with D6500 white point (consumer P3, P3-D65)? It would need to be the consumer P3 for my case to work as intended.

@natural-harmonia-gropius
Copy link
Contributor

natural-harmonia-gropius commented Oct 30, 2023

https://github.com/natural-harmonia-gropius/hdr-toys/blob/master/gamut-mapping/clip.glsl

Can you also test this?Just add this into conf as normal shaders, no profile, no other shaders in hdr-toys. And modify two defines to FROM P3D65 TO BT2020

Hopefully it won't be any different from patch in above.

@danbezerra
Copy link
Author

@haasn first observation (using the TV as I don't have access to the projector now): Using the combination:
target-trc=gamma2.4
target-prim=bt.2020
target-gamut=display-p3

and gamut-mapping-mode=warn, I see it highlighting all pixels above bt.709. I'm surprised by that - I thought it would only highlight the ones above P3 (or perhaps just ignore the new option and look for pixels above bt.2020).

If I remove the new target-gamut option, but leave target-prim=bt.2020, warn doesn't show me anything as expected.

I double checked the scene, and confirmed that nothing should be above P3.

I still need to do the visual check but I need my projector for that.

@danbezerra
Copy link
Author

danbezerra commented Oct 30, 2023

Another discovery - I just learned that tone mapping to SDR Bt.2020 pushes more of the image to the outside of P3 gamut. Comparing a passthrough HDR with SDR BT.2020 tonemaping (spline), the amount of out of gamut warning increases considerably. So the movie I was using to check is inside P3 when using passthrough, but bleeds once tone mapping is applied.

I also compared that with MadVR tonemapping and the same thing happens - MadVR with tone mapping to SDR BT.2020 had a lot more outside of P3 vs MadVR in HDR passthrough mode.

FYI : For MadVR I used the following shader attached to MPC-HC. It's similar to "warn" mode, and allowed me to compare the results.

https://github.com/aron7awol/gamutShader

So as of now, I will say that the code is working as intended. It was just surprising to me that tone mapping will push more content outside of P3.

@haasn
Copy link
Member

haasn commented Oct 30, 2023

@danbezerra how are you testing? on my end, with

--target-trc=gamma2.4 --target-prim=bt.2020 --gamut-mapping-mode=warn --tone-mapping-visualize +

--target-gamut=bt.709

mpv-shot0001

--target-gamut=display-p3

mpv-shot0002

It expands to the larger gamut as expected.

@haasn
Copy link
Member

haasn commented Oct 30, 2023

So as of now, I will say that the code is working as intended. It was just surprising to me that tone mapping will push more content outside of P3.

Ah, okay. Good to hear, then. I suppose I'll polish up the above commit and add it as an option $tomorrow (tm)

@danbezerra
Copy link
Author

Just for curiosity - do you understand why tone mapping is pushing more content outside of P3?

@danbezerra
Copy link
Author

danbezerra commented Oct 30, 2023

https://github.com/natural-harmonia-gropius/hdr-toys/blob/master/gamut-mapping/clip.glsl

Can you also test this?Just add this into conf as normal shaders, no profile, no other shaders in hdr-toys. And modify two defines to FROM P3D65 TO BT2020

Hopefully it won't be any different from patch in above.

Not sure it's working as intended. If I leave the following lines on my config:
target-trc=gamma2.4
target-prim=bt.2020
gamut-mapping-mode=warn

Then nothing is reported as outside of the gamut (via the warn line). If I remove the target-prim (since I specified the "From" and "To" in your shader), then a lot more than MPV native solution is reported as out of P3. See the screenshots attached.

Perhaps gamut-mapping-mode-warn doesn't work with Shaders? BTW, I don't have any other HDRToys scripts installed.

mpv native
HDRToys

@haasn
Copy link
Member

haasn commented Oct 30, 2023

Just for curiosity - do you understand why tone mapping is pushing more content outside of P3?

I'm not 100% sure, but reducing luminance generally pushes content out-of-gamut. We also reduce the chromaticity of the input when tone-mapping, but we use a rough approximation of the native (BT.2020) gamut hull for this. I'd probably have to look at the problem visually to really know what's going on..

haasn added a commit to haasn/mp that referenced this issue Oct 31, 2023
haasn added a commit to haasn/mp that referenced this issue Nov 1, 2023
@movieperson
Copy link

I may be having a senior moment, but I can't for the life of me figure out where to find the windows 64 bit mpv.exe that actually contains this fix so I can test it.

Any help would be appreciated.

@danbezerra
Copy link
Author

You have to build it yourself as the fix was not checked-in yet.

@kasper93
Copy link
Contributor

kasper93 commented Nov 2, 2023

I may be having a senior moment, but I can't for the life of me figure out where to find the windows 64 bit mpv.exe that actually contains this fix so I can test it.

Any help would be appreciated.

Builds can be found in PR comment.
#12786 (comment)

@natural-harmonia-gropius
Copy link
Contributor

Not sure it's working as intended. If I leave the following lines on my config: target-trc=gamma2.4 target-prim=bt.2020 gamut-mapping-mode=warn

Then nothing is reported as outside of the gamut (via the warn line). If I remove the target-prim (since I specified the "From" and "To" in your shader), then a lot more than MPV native solution is reported as out of P3. See the screenshots attached.

Use target-prim=display-p3, and compare result with eyes 🫠. Does it looks right?

gamut-mapping-mode=warn doing things before hdr-toys so it doesn't work here.

haasn added a commit to haasn/mp that referenced this issue Nov 4, 2023
haasn added a commit to haasn/mp that referenced this issue Nov 5, 2023
haasn added a commit that referenced this issue Nov 7, 2023
Kosm8 pushed a commit to Kosm8/mpv that referenced this issue Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants