From dc9a5cbfd7c30d4f0597ec0aad91dadf63defbba Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Tue, 28 Jun 2016 14:28:32 +0200 Subject: vo_opengl: revise the transfer curve logic Instead of hard-coding a big list, move some of the functionality to csputils. Affects both the auto-guess blacklist and the peak estimation. Also update the comments. --- video/csputils.c | 25 +++++++++++++++++++++++++ video/csputils.h | 2 ++ video/out/opengl/video.c | 27 ++++++++++----------------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/video/csputils.c b/video/csputils.c index 65b26acb3a..d419152e2c 100644 --- a/video/csputils.c +++ b/video/csputils.c @@ -437,6 +437,31 @@ struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim spc) } } +// Get the relative peak of a transfer curve, that is: (source reference / +// display reference), or 0 if there is none (i.e. source has an absolute peak) +float mp_csp_trc_rel_peak(enum mp_csp_trc trc) +{ + switch (trc) { + case MP_CSP_TRC_SMPTE_ST2084: return 0.0; // This has a fixed peak + case MP_CSP_TRC_ARIB_STD_B67: return 12.0; + case MP_CSP_TRC_V_LOG: return 46.0855; + } + + return 1.0; +} + +bool mp_trc_is_hdr(enum mp_csp_trc trc) +{ + switch (trc) { + case MP_CSP_TRC_SMPTE_ST2084: + case MP_CSP_TRC_ARIB_STD_B67: + case MP_CSP_TRC_V_LOG: + return true; + } + + return false; +} + // Compute the RGB/XYZ matrix as described here: // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html static void mp_get_rgb2xyz_matrix(struct mp_csp_primaries space, float m[3][3]) diff --git a/video/csputils.h b/video/csputils.h index 047b109d2b..274b548381 100644 --- a/video/csputils.h +++ b/video/csputils.h @@ -219,6 +219,8 @@ int mp_chroma_location_to_av(enum mp_chroma_location mploc); void mp_get_chroma_location(enum mp_chroma_location loc, int *x, int *y); struct mp_csp_primaries mp_get_csp_primaries(enum mp_csp_prim csp); +float mp_csp_trc_rel_peak(enum mp_csp_trc trc); +bool mp_trc_is_hdr(enum mp_csp_trc trc); /* Color conversion matrix: RGB = m * YUV + c * m is in row-major matrix, with m[row][col], e.g.: diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index fff41a1b91..519857f7f9 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -2206,31 +2206,24 @@ static void pass_colormanage(struct gl_video *p, float peak_src, } if (trc_dst == MP_CSP_TRC_AUTO) { + // Most people seem to complain when the image is darker or brighter + // than what they're "used to", so just avoid changing the gamma + // altogether by default. The only exceptions to this rule apply to + // very unusual TRCs, which even hardcode technoluddites would probably + // not enjoy viewing unaltered. trc_dst = p->image_params.gamma; - // Avoid outputting linear light or HDR content "by default" - if (trc_dst == MP_CSP_TRC_LINEAR || - trc_dst == MP_CSP_TRC_SMPTE_ST2084 || - trc_dst == MP_CSP_TRC_ARIB_STD_B67 || - trc_dst == MP_CSP_TRC_V_LOG) - { + // Avoid outputting linear light or HDR content "by default". For these + // just pick gamma 2.2 as a default, since it's a good estimate for + // the response of typical displays + if (trc_dst == MP_CSP_TRC_LINEAR || mp_trc_is_hdr(trc_dst)) trc_dst = MP_CSP_TRC_GAMMA22; - } } if (!peak_src) { // If the source has no information known, it's display-referred // (and should be treated relative to the specified desired peak_dst) - peak_src = peak_dst; - - // Exception: ARIB STD-B67's nominal peak is exactly 12 times the - // target's reference peak - if (p->image_params.gamma == MP_CSP_TRC_ARIB_STD_B67) - peak_src = 12 * peak_dst; - - // Similar deal for V-Log - if (p->image_params.gamma == MP_CSP_TRC_V_LOG) - peak_src = 46.0855 * peak_dst; + peak_src = peak_dst * mp_csp_trc_rel_peak(p->image_params.gamma); } // All operations from here on require linear light as a starting point, -- cgit v1.2.3