@@ -692,6 +692,32 @@ static bool format_supported(struct vo *vo, int format, bool use_uint)
692692 return true;
693693}
694694
695+ // Effective reference white luminance in nits to assume for SDR content.
696+ static float get_ref_luma (struct priv * p )
697+ {
698+ const struct gl_video_opts * opts = p -> opts_cache -> opts ;
699+ if (opts -> hdr_reference_white )
700+ return opts -> hdr_reference_white ;
701+
702+ // auto: follow the system reference white, if available
703+ struct ra_swapchain * sw = p -> ra_ctx -> swapchain ;
704+ if (sw -> fns -> target_ref_luma )
705+ return sw -> fns -> target_ref_luma (sw );
706+
707+ return 0 ;
708+ }
709+
710+ static bool use_ref_luma (const struct pl_color_space * csp , const struct pl_color_space * target_csp )
711+ {
712+ if (!pl_color_transfer_is_hdr (csp -> transfer ))
713+ return true;
714+ #if PL_API_VER >= 362
715+ if (csp -> transfer == PL_COLOR_TRC_SCRGB && target_csp && !pl_color_transfer_is_hdr (target_csp -> transfer ))
716+ return true;
717+ #endif
718+ return false;
719+ }
720+
695721static bool map_frame (pl_gpu gpu , pl_tex * tex , const struct pl_source_frame * src ,
696722 struct pl_frame * frame )
697723{
@@ -729,9 +755,11 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
729755 };
730756
731757 const struct gl_video_opts * opts = p -> opts_cache -> opts ;
732- if (opts -> hdr_reference_white && !pl_color_transfer_is_hdr (frame -> color .transfer ))
733- frame -> color .hdr .max_luma = opts -> hdr_reference_white ;
734-
758+ float ref_luma ;
759+ if (!pl_color_transfer_is_hdr (frame -> color .transfer ) && (ref_luma = get_ref_luma (p ))) {
760+ MP_ERR (vo , "ref: %f\n" , ref_luma );
761+ frame -> color .hdr .max_luma = ref_luma ;
762+ }
735763
736764 if (opts -> treat_srgb_as_power22 & 1 && frame -> color .transfer == PL_COLOR_TRC_SRGB ) {
737765 // The sRGB EOTF is a pure gamma 2.2 function. See reference display in
@@ -942,7 +970,8 @@ static void apply_target_contrast(struct priv *p, struct pl_color_space *color,
942970}
943971
944972static void apply_target_options (struct priv * p , struct pl_frame * target ,
945- float min_luma , bool hint )
973+ float min_luma , bool hint , float target_ref_luma ,
974+ const struct pl_color_space * target_csp )
946975{
947976 update_lut (p , & p -> next_opts -> target_lut );
948977 target -> lut = p -> next_opts -> target_lut .lut ;
@@ -959,9 +988,9 @@ static void apply_target_options(struct priv *p, struct pl_frame *target,
959988 target -> color .transfer = opts -> target_trc ;
960989 if (opts -> target_peak && (!target -> color .hdr .max_luma || !hint ))
961990 target -> color .hdr .max_luma = opts -> target_peak ;
962- if (opts -> hdr_reference_white && (!target -> color .hdr .max_luma || !hint ) &&
963- ! pl_color_transfer_is_hdr ( target -> color . transfer )) {
964- target -> color .hdr .max_luma = opts -> hdr_reference_white ;
991+ if (target_ref_luma && (!target -> color .hdr .max_luma || !hint ) &&
992+ use_ref_luma ( & target -> color , target_csp )) {
993+ target -> color .hdr .max_luma = target_ref_luma ;
965994 }
966995 if ((!target -> color .hdr .min_luma || !hint ))
967996 apply_target_contrast (p , & target -> color , min_luma );
@@ -1179,9 +1208,12 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame)
11791208 // Assume HDR is supported, if target_csp() is not available
11801209 // TODO: Remove this fallback when all backends support target_csp()
11811210 bool target_unknown = target_csp .transfer == PL_COLOR_TRC_UNKNOWN ;
1211+ float target_ref_luma = 0 ;
11821212 if (target_unknown ) {
11831213 target_csp = (struct pl_color_space ){
11841214 .transfer = opts -> target_trc ? opts -> target_trc : pl_color_space_hdr10 .transfer };
1215+ } else {
1216+ target_ref_luma = get_ref_luma (p );
11851217 }
11861218 bool external_params = false;
11871219 if (target_hint && frame -> current ) {
@@ -1246,8 +1278,8 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame)
12461278 hint .transfer = opts -> target_trc ;
12471279 if (opts -> target_peak )
12481280 hint .hdr .max_luma = opts -> target_peak ;
1249- if (opts -> hdr_reference_white && ! pl_color_transfer_is_hdr ( hint . transfer ))
1250- hint .hdr .max_luma = opts -> hdr_reference_white ;
1281+ if (target_ref_luma && use_ref_luma ( & hint , & target_csp ))
1282+ hint .hdr .max_luma = target_ref_luma ;
12511283 // Always set maxCLL, display uses this metadata and we shouldn't let it
12521284 // fallback to default value.
12531285 if (!hint .hdr .max_cll )
@@ -1311,7 +1343,8 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame)
13111343 if (external_params )
13121344 target .color = hint ;
13131345 bool strict_sw_params = target_hint && p -> next_opts -> target_hint_strict ;
1314- apply_target_options (p , & target , hint .hdr .min_luma , strict_sw_params );
1346+ apply_target_options (p , & target , hint .hdr .min_luma , strict_sw_params ,
1347+ target_ref_luma , & target_csp );
13151348 bool clip_gamut = pl_primaries_valid (& target .color .hdr .prim );
13161349#if PL_API_VER >= 362
13171350 clip_gamut = clip_gamut && target .color .transfer != PL_COLOR_TRC_SCRGB ;
@@ -1736,7 +1769,7 @@ static void video_screenshot(struct vo *vo, struct voctrl_screenshot *args)
17361769 const struct gl_video_opts * opts = p -> opts_cache -> opts ;
17371770 if (args -> scaled ) {
17381771 // Apply target LUT, ICC profile and CSP override only in window mode
1739- apply_target_options (p , & target , 0 , false);
1772+ apply_target_options (p , & target , 0 , false, 0 , NULL );
17401773 } else if (args -> native_csp ) {
17411774 target .color = image .color ;
17421775 } else {
0 commit comments