Skip to content

Commit ff57579

Browse files
committed
vo_gpu_next: add --linearize-srgb-as-power22
The sRGB EOTF is a pure gamma 2.2 function. There is some disagreement regarding the sRGB specification and whether it should be treated as a piecewise function. Many displays are actually gamma 2.2, and content mastered for PC is typically affected by that. Therefore, linearize it as such to avoid raised blacks. See: IEC 61966-2-1-1999 https://community.acescentral.com/t/srgb-piece-wise-eotf-vs-pure-gamma/4024 KhronosGroup/DataFormat#19 https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/12 https://github.com/dylanraga/win11hdr-srgb-to-gamma2.2-icm
1 parent 0a53407 commit ff57579

File tree

4 files changed

+30
-0
lines changed

4 files changed

+30
-0
lines changed

DOCS/man/options.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7354,6 +7354,19 @@ them.
73547354
transfer function is SDR. This way you can control SDR output separately
73557355
from HDR output.
73567356

7357+
``--linearize-srgb-as-power22``
7358+
When enabled, sRGB is linearized using a pure gamma 2.2 function, instead of
7359+
the sRGB piecewise function. There is some disagreement regarding the sRGB
7360+
specification and whether it should be treated as a piecewise function.
7361+
Many displays are actually gamma 2.2, and content mastered for PC is typically
7362+
affected by that. Disabled by default. (Only for ``--vo=gpu-next``)
7363+
7364+
See for more details:
7365+
https://community.acescentral.com/t/srgb-piece-wise-eotf-vs-pure-gamma/4024
7366+
https://github.com/KhronosGroup/DataFormat/issues/19
7367+
https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/12
7368+
https://github.com/dylanraga/win11hdr-srgb-to-gamma2.2-icm
7369+
73577370
``--tone-mapping=<value>``
73587371
Specifies the algorithm used for tone-mapping images onto the target
73597372
display. This is relevant for both HDR->SDR conversion as well as gamut

video/out/gpu/video.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ const struct m_sub_options gl_video_conf = {
445445
M_RANGE(10, 10000)},
446446
{"hdr-reference-white", OPT_CHOICE(hdr_reference_white, {"auto", 0}),
447447
M_RANGE(10, 10000)},
448+
{"linearize-srgb-as-power22", OPT_BOOL(linearize_srgb_as_power22)},
448449
{"target-contrast", OPT_CHOICE(target_contrast, {"auto", 0}, {"inf", -1}),
449450
M_RANGE(10, 1000000)},
450451
{"target-gamut", OPT_CHOICE_C(target_gamut, pl_csp_prim_names)},

video/out/gpu/video.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ struct gl_video_opts {
139139
int target_trc;
140140
int target_peak;
141141
int hdr_reference_white;
142+
bool linearize_srgb_as_power22;
142143
int target_contrast;
143144
int target_gamut;
144145
struct gl_tone_map_opts tone_map;

video/out/vo_gpu_next.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,21 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
675675
if (opts->hdr_reference_white && !pl_color_transfer_is_hdr(frame->color.transfer))
676676
frame->color.hdr.max_luma = opts->hdr_reference_white;
677677

678+
if (opts->linearize_srgb_as_power22 && frame->color.transfer == PL_COLOR_TRC_SRGB) {
679+
// The sRGB EOTF is a pure gamma 2.2 function. There is some disagreement
680+
// regarding the sRGB specification and whether it should be treated
681+
// as a piecewise function. Many displays are actually gamma 2.2, and content
682+
// mastered for PC is typically affected by that. Therefore, linearize it
683+
// as such to avoid raised blacks.
684+
// See:
685+
// IEC 61966-2-1-1999
686+
// <https://community.acescentral.com/t/srgb-piece-wise-eotf-vs-pure-gamma/4024>
687+
// <https://github.com/KhronosGroup/DataFormat/issues/19>
688+
// <https://gitlab.freedesktop.org/pq/color-and-hdr/-/issues/12>
689+
// <https://github.com/dylanraga/win11hdr-srgb-to-gamma2.2-icm>
690+
frame->color.transfer = PL_COLOR_TRC_GAMMA22;
691+
}
692+
678693
if (fp->hwdec) {
679694

680695
struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(par.imgfmt);

0 commit comments

Comments
 (0)