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.
This commit is contained in:
Niklas Haas
2016-06-28 14:28:32 +02:00
committed by wm4
parent 65499d863a
commit dc9a5cbfd7
3 changed files with 37 additions and 17 deletions

View File

@@ -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: // Compute the RGB/XYZ matrix as described here:
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html // 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]) static void mp_get_rgb2xyz_matrix(struct mp_csp_primaries space, float m[3][3])

View File

@@ -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); 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); 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 /* Color conversion matrix: RGB = m * YUV + c
* m is in row-major matrix, with m[row][col], e.g.: * m is in row-major matrix, with m[row][col], e.g.:

View File

@@ -2206,31 +2206,24 @@ static void pass_colormanage(struct gl_video *p, float peak_src,
} }
if (trc_dst == MP_CSP_TRC_AUTO) { 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; trc_dst = p->image_params.gamma;
// Avoid outputting linear light or HDR content "by default" // Avoid outputting linear light or HDR content "by default". For these
if (trc_dst == MP_CSP_TRC_LINEAR || // just pick gamma 2.2 as a default, since it's a good estimate for
trc_dst == MP_CSP_TRC_SMPTE_ST2084 || // the response of typical displays
trc_dst == MP_CSP_TRC_ARIB_STD_B67 || if (trc_dst == MP_CSP_TRC_LINEAR || mp_trc_is_hdr(trc_dst))
trc_dst == MP_CSP_TRC_V_LOG)
{
trc_dst = MP_CSP_TRC_GAMMA22; trc_dst = MP_CSP_TRC_GAMMA22;
}
} }
if (!peak_src) { if (!peak_src) {
// If the source has no information known, it's display-referred // If the source has no information known, it's display-referred
// (and should be treated relative to the specified desired peak_dst) // (and should be treated relative to the specified desired peak_dst)
peak_src = peak_dst; peak_src = peak_dst * mp_csp_trc_rel_peak(p->image_params.gamma);
// 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;
} }
// All operations from here on require linear light as a starting point, // All operations from here on require linear light as a starting point,