@@ -2161,10 +2161,6 @@ static void info_done(void *data, struct wp_image_description_info_v1 *image_des
21612161 wd -> csp .hdr .max_cll = (wd -> csp .hdr .max_cll - a ) * b + a ;
21622162 wd -> csp .hdr .max_fall = (wd -> csp .hdr .max_fall - a ) * b + a ;
21632163 wl -> preferred_csp = wd -> csp ;
2164- if (wd -> csp .hdr .max_luma > PL_COLOR_SDR_WHITE ) {
2165- MP_VERBOSE (wl , "Setting preferred transfer to PQ for HDR output.\n" );
2166- wl -> preferred_csp .transfer = PL_COLOR_TRC_PQ ;
2167- }
21682164 } else {
21692165 if (wl -> icc_size ) {
21702166 munmap (wl -> icc_file , wl -> icc_size );
@@ -3971,10 +3967,40 @@ bool vo_wayland_check_visible(struct vo *vo)
39713967 return render ;
39723968}
39733969
3974- struct pl_color_space vo_wayland_preferred_csp (struct vo * vo )
3970+ struct pl_color_space vo_wayland_preferred_csp (struct vo * vo , float source_max_luma )
39753971{
39763972 struct vo_wayland_state * wl = vo -> wl ;
3977- return wl -> preferred_csp ;
3973+ struct pl_color_space csp = wl -> preferred_csp ;
3974+ if (!pl_color_transfer_is_hdr (csp .transfer )) {
3975+ // Transfer functions for which pl_color_transfer_is_hdr returns false have some
3976+ // limitations: mpv discards the HDR info for them, libplacebo does not use
3977+ // floating point buffers for them [1], mesa discards HDR info for them. Therefore,
3978+ // we must change the transfer function to one where pl_color_transfer_is_hdr
3979+ // returns true if we need HDR-like behavior. If you look at that function, you can
3980+ // see that PL_COLOR_TRC_PQ is the only viable choice even though PL_COLOR_TRC_LINEAR
3981+ // would be more efficient (libplacebo uses 16-bits-per-channel formats either way).
3982+ //
3983+ // [1]: Except for PL_COLOR_TRC_LINEAR, but we cannot use that one due to the other
3984+ // limitations.
3985+
3986+ float max_luma = source_max_luma ;
3987+ // INFINITY is a sentinel value used to indicate that we want to perform inverse
3988+ // tone mapping.
3989+ if (source_max_luma == INFINITY )
3990+ max_luma = csp .hdr .max_luma ;
3991+
3992+ // If the source is brighter than what the display permits, we must tone map.
3993+ // Since mpv throws the HDR metadata away for SDR transfer functions, we must
3994+ // switch to an HDR transfer function if max_luma is not the default.
3995+ if (max_luma > csp .hdr .max_luma && csp .hdr .max_luma != PL_COLOR_SDR_WHITE )
3996+ csp .transfer = PL_COLOR_TRC_PQ ;
3997+ // If the source is brighter than reference white, we cannot use an SDR transfer
3998+ // function because libplacebo will not use a floating point buffer for them and
3999+ // we would need to store values greater than 1.0 in the buffer to reach max_luma.
4000+ if (max_luma > PL_COLOR_SDR_WHITE )
4001+ csp .transfer = PL_COLOR_TRC_PQ ;
4002+ }
4003+ return csp ;
39784004}
39794005
39804006int vo_wayland_control (struct vo * vo , int * events , int request , void * arg )
0 commit comments