From 70f50ddc5e97020d64ea0702748a00eddebc2473 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Wed, 26 Mar 2014 01:46:38 +0100 Subject: video: Add support for non-BT.709 primaries This add support for reading primary information from lavc, categorized into BT.601-525, BT.601-625, BT.709 and BT.2020; and passes it on to the vo. In vo_opengl, we always generate the 3dlut against the wider BT.2020 and transform our source into this colorspace in the shader. --- video/csputils.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'video/csputils.c') diff --git a/video/csputils.c b/video/csputils.c index 13398d6d10..32461697c0 100644 --- a/video/csputils.c +++ b/video/csputils.c @@ -42,7 +42,7 @@ const char *const mp_csp_names[MP_CSP_COUNT] = { "BT.601 (SD)", "BT.709 (HD)", "SMPTE-240M", - "BT.2020 (NC)", + "BT.2020-NC (UHD)", "RGB", "XYZ", "YCgCo", @@ -54,6 +54,14 @@ const char *const mp_csp_levels_names[MP_CSP_LEVELS_COUNT] = { "PC", }; +const char *const mp_csp_prim_names[MP_CSP_PRIM_COUNT] = { + "Autoselect", + "BT.601 (525-line SD)", + "BT.601 (625-line SD)", + "BT.709 (HD)", + "BT.2020 (UHD)", +}; + const char *const mp_csp_equalizer_names[MP_CSP_EQ_COUNT] = { "brightness", "contrast", @@ -93,6 +101,20 @@ enum mp_csp_levels avcol_range_to_mp_csp_levels(int avrange) } } +enum mp_csp_prim avcol_pri_to_mp_csp_prim(int avpri) +{ + switch (avpri) { + case AVCOL_PRI_SMPTE240M: // Same as below + case AVCOL_PRI_SMPTE170M: return MP_CSP_PRIM_BT_601_525; + case AVCOL_PRI_BT470BG: return MP_CSP_PRIM_BT_601_625; + case AVCOL_PRI_BT709: return MP_CSP_PRIM_BT_709; +#if HAVE_AVCOL_SPC_BT2020 + case AVCOL_PRI_BT2020: return MP_CSP_PRIM_BT_2020; +#endif + default: return MP_CSP_PRIM_AUTO; + } +} + int mp_csp_to_avcol_spc(enum mp_csp colorspace) { switch (colorspace) { @@ -117,6 +139,19 @@ int mp_csp_levels_to_avcol_range(enum mp_csp_levels range) } } +int mp_csp_prim_to_avcol_pri(enum mp_csp_prim prim) +{ + switch (prim) { + case MP_CSP_PRIM_BT_601_525: return AVCOL_PRI_SMPTE170M; + case MP_CSP_PRIM_BT_601_625: return AVCOL_PRI_BT470BG; + case MP_CSP_PRIM_BT_709: return AVCOL_PRI_BT709; +#if HAVE_AVCOL_SPC_BT2020 + case MP_CSP_PRIM_BT_2020: return AVCOL_PRI_BT2020; +#endif + default: return AVCOL_PRI_UNSPECIFIED; + } +} + enum mp_csp mp_csp_guess_colorspace(int width, int height) { return width >= 1280 || height > 576 ? MP_CSP_BT_709 : MP_CSP_BT_601; @@ -208,6 +243,53 @@ static void luma_coeffs(float m[3][4], float lr, float lg, float lb) // Constant coefficients (m[x][3]) not set here } +/** + * Get the coefficients of the source -> bt2020 gamut mapping matrix, + * given an identifier describing the source gamut primaries. + */ +void mp_get_cms_matrix(enum mp_csp_prim source, float m[3][3]) +{ + // Conversion matrices to BT.2020 primaries + // These were computed using: http://lpaste.net/101796 + switch (source) { + case MP_CSP_PRIM_BT_601_525: { + static const float from_525[3][3] = { + {0.5952542, 0.3493139, 0.0554319}, + {0.0812437, 0.8915033, 0.0272530}, + {0.0155123, 0.0819116, 0.9025760}, + }; + memcpy(m, from_525, sizeof(from_525)); + break; + } + case MP_CSP_PRIM_BT_601_625: { + static const float from_625[3][3] = { + {0.6550368, 0.3021610, 0.0428023}, + {0.0721406, 0.9166311, 0.0112283}, + {0.0171134, 0.0978535, 0.8850332}, + }; + memcpy(m, from_625, sizeof(from_625)); + break; + } + case MP_CSP_PRIM_BT_709: { + static const float from_709[3][3] = { + {0.6274039, 0.3292830, 0.0433131}, + {0.0690973, 0.9195404, 0.0113623}, + {0.0163914, 0.0880133, 0.8955953}, + }; + memcpy(m, from_709, sizeof(from_709)); + break; + } + case MP_CSP_PRIM_BT_2020: + default: { + // No conversion necessary. This matrix should not even be used + // in this case, but assign it to the identity just to be safe. + static const float ident[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; + memcpy(m, ident, sizeof(ident)); + break; + } + } +} + /** * \brief get the coefficients of the yuv -> rgb conversion matrix * \param params struct specifying the properties of the conversion like -- cgit v1.2.3