mirror of
https://github.com/mpv-player/mpv
synced 2025-03-22 03:08:33 +00:00
video: Add BT.2020-NCL colorspace and transfer function
Source: http://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2020-0-201208-I!!PDF-E.pdf
This commit is contained in:
parent
082fbe39e8
commit
86d3d11a68
@ -537,6 +537,7 @@ OPTIONS
|
|||||||
:auto: automatic selection (default)
|
:auto: automatic selection (default)
|
||||||
:BT.601: ITU-R BT.601 (SD)
|
:BT.601: ITU-R BT.601 (SD)
|
||||||
:BT.709: ITU-R BT.709 (HD)
|
:BT.709: ITU-R BT.709 (HD)
|
||||||
|
:BT.2020-NC: ITU-R BT.2020 non-constant luminance system
|
||||||
:SMPTE-240M: SMPTE-240M
|
:SMPTE-240M: SMPTE-240M
|
||||||
|
|
||||||
``--colormatrix-input-range=<color-range>``
|
``--colormatrix-input-range=<color-range>``
|
||||||
|
@ -509,7 +509,7 @@ Available video output drivers are:
|
|||||||
absolute colorimetric
|
absolute colorimetric
|
||||||
|
|
||||||
``approx-gamma``
|
``approx-gamma``
|
||||||
Approximate the actual BT.709 gamma function as a pure power curve of
|
Approximate the actual gamma function as a pure power curve of
|
||||||
1.95. A number of video editing programs and studios apparently use this
|
1.95. A number of video editing programs and studios apparently use this
|
||||||
for mastering instead of the true curve. Most notably, anything in the
|
for mastering instead of the true curve. Most notably, anything in the
|
||||||
Apple ecosystem uses this approximation - including all programs
|
Apple ecosystem uses this approximation - including all programs
|
||||||
|
@ -797,6 +797,12 @@ api_statement_check \
|
|||||||
libavcodec/avcodec.h \
|
libavcodec/avcodec.h \
|
||||||
'int x, y; avcodec_enum_to_chroma_pos(&x, &y, AVCHROMA_LOC_UNSPECIFIED)'
|
'int x, y; avcodec_enum_to_chroma_pos(&x, &y, AVCHROMA_LOC_UNSPECIFIED)'
|
||||||
|
|
||||||
|
api_statement_check \
|
||||||
|
"libavcodec avcol_spc_bt2020 available" \
|
||||||
|
HAVE_AVCOL_SPC_BT2020 \
|
||||||
|
libavcodec/avcodec.h \
|
||||||
|
'int x = AVCOL_SPC_BT2020_NCL'
|
||||||
|
|
||||||
api_statement_check \
|
api_statement_check \
|
||||||
"libavcodec metadata update side data" \
|
"libavcodec metadata update side data" \
|
||||||
HAVE_AVCODEC_METADATA_UPDATE_SIDE_DATA \
|
HAVE_AVCODEC_METADATA_UPDATE_SIDE_DATA \
|
||||||
|
@ -389,6 +389,7 @@ const m_option_t mp_opts[] = {
|
|||||||
{"BT.601", MP_CSP_BT_601},
|
{"BT.601", MP_CSP_BT_601},
|
||||||
{"BT.709", MP_CSP_BT_709},
|
{"BT.709", MP_CSP_BT_709},
|
||||||
{"SMPTE-240M", MP_CSP_SMPTE_240M},
|
{"SMPTE-240M", MP_CSP_SMPTE_240M},
|
||||||
|
{"BT.2020-NC", MP_CSP_BT_2020_NC},
|
||||||
{"YCgCo", MP_CSP_YCGCO})),
|
{"YCgCo", MP_CSP_YCGCO})),
|
||||||
OPT_CHOICE("colormatrix-input-range", requested_input_range, 0,
|
OPT_CHOICE("colormatrix-input-range", requested_input_range, 0,
|
||||||
({"auto", MP_CSP_LEVELS_AUTO},
|
({"auto", MP_CSP_LEVELS_AUTO},
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
* version 2.1 of the License, or (at your option) any later version.
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -40,6 +42,7 @@ const char *const mp_csp_names[MP_CSP_COUNT] = {
|
|||||||
"BT.601 (SD)",
|
"BT.601 (SD)",
|
||||||
"BT.709 (HD)",
|
"BT.709 (HD)",
|
||||||
"SMPTE-240M",
|
"SMPTE-240M",
|
||||||
|
"BT.2020 (NC)",
|
||||||
"RGB",
|
"RGB",
|
||||||
"XYZ",
|
"XYZ",
|
||||||
"YCgCo",
|
"YCgCo",
|
||||||
@ -70,6 +73,9 @@ enum mp_csp avcol_spc_to_mp_csp(int avcolorspace)
|
|||||||
switch (avcolorspace) {
|
switch (avcolorspace) {
|
||||||
case AVCOL_SPC_BT709: return MP_CSP_BT_709;
|
case AVCOL_SPC_BT709: return MP_CSP_BT_709;
|
||||||
case AVCOL_SPC_BT470BG: return MP_CSP_BT_601;
|
case AVCOL_SPC_BT470BG: return MP_CSP_BT_601;
|
||||||
|
#if HAVE_AVCOL_SPC_BT2020
|
||||||
|
case AVCOL_SPC_BT2020_NCL: return MP_CSP_BT_2020_NC;
|
||||||
|
#endif
|
||||||
case AVCOL_SPC_SMPTE170M: return MP_CSP_BT_601;
|
case AVCOL_SPC_SMPTE170M: return MP_CSP_BT_601;
|
||||||
case AVCOL_SPC_SMPTE240M: return MP_CSP_SMPTE_240M;
|
case AVCOL_SPC_SMPTE240M: return MP_CSP_SMPTE_240M;
|
||||||
case AVCOL_SPC_RGB: return MP_CSP_RGB;
|
case AVCOL_SPC_RGB: return MP_CSP_RGB;
|
||||||
@ -92,6 +98,9 @@ int mp_csp_to_avcol_spc(enum mp_csp colorspace)
|
|||||||
switch (colorspace) {
|
switch (colorspace) {
|
||||||
case MP_CSP_BT_709: return AVCOL_SPC_BT709;
|
case MP_CSP_BT_709: return AVCOL_SPC_BT709;
|
||||||
case MP_CSP_BT_601: return AVCOL_SPC_BT470BG;
|
case MP_CSP_BT_601: return AVCOL_SPC_BT470BG;
|
||||||
|
#if HAVE_AVCOL_SPC_BT2020
|
||||||
|
case MP_CSP_BT_2020_NC: return AVCOL_SPC_BT2020_NCL;
|
||||||
|
#endif
|
||||||
case MP_CSP_SMPTE_240M: return AVCOL_SPC_SMPTE240M;
|
case MP_CSP_SMPTE_240M: return AVCOL_SPC_SMPTE240M;
|
||||||
case MP_CSP_RGB: return AVCOL_SPC_RGB;
|
case MP_CSP_RGB: return AVCOL_SPC_RGB;
|
||||||
case MP_CSP_YCGCO: return AVCOL_SPC_YCOCG;
|
case MP_CSP_YCGCO: return AVCOL_SPC_YCOCG;
|
||||||
@ -218,6 +227,7 @@ void mp_get_yuv2rgb_coeffs(struct mp_csp_params *params, float m[3][4])
|
|||||||
case MP_CSP_BT_601: luma_coeffs(m, 0.299, 0.587, 0.114 ); break;
|
case MP_CSP_BT_601: luma_coeffs(m, 0.299, 0.587, 0.114 ); break;
|
||||||
case MP_CSP_BT_709: luma_coeffs(m, 0.2126, 0.7152, 0.0722); break;
|
case MP_CSP_BT_709: luma_coeffs(m, 0.2126, 0.7152, 0.0722); break;
|
||||||
case MP_CSP_SMPTE_240M: luma_coeffs(m, 0.2122, 0.7013, 0.0865); break;
|
case MP_CSP_SMPTE_240M: luma_coeffs(m, 0.2122, 0.7013, 0.0865); break;
|
||||||
|
case MP_CSP_BT_2020_NC: luma_coeffs(m, 0.2627, 0.6780, 0.0593); break;
|
||||||
case MP_CSP_RGB: {
|
case MP_CSP_RGB: {
|
||||||
static const float ident[3][4] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
static const float ident[3][4] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||||
memcpy(m, ident, sizeof(ident));
|
memcpy(m, ident, sizeof(ident));
|
||||||
|
@ -37,6 +37,7 @@ enum mp_csp {
|
|||||||
MP_CSP_BT_601,
|
MP_CSP_BT_601,
|
||||||
MP_CSP_BT_709,
|
MP_CSP_BT_709,
|
||||||
MP_CSP_SMPTE_240M,
|
MP_CSP_SMPTE_240M,
|
||||||
|
MP_CSP_BT_2020_NC,
|
||||||
MP_CSP_RGB,
|
MP_CSP_RGB,
|
||||||
MP_CSP_XYZ,
|
MP_CSP_XYZ,
|
||||||
MP_CSP_YCGCO,
|
MP_CSP_YCGCO,
|
||||||
|
@ -521,6 +521,7 @@ void mp_image_params_guess_csp(struct mp_image_params *params)
|
|||||||
if (fmt.flags & MP_IMGFLAG_YUV) {
|
if (fmt.flags & MP_IMGFLAG_YUV) {
|
||||||
if (params->colorspace != MP_CSP_BT_601 &&
|
if (params->colorspace != MP_CSP_BT_601 &&
|
||||||
params->colorspace != MP_CSP_BT_709 &&
|
params->colorspace != MP_CSP_BT_709 &&
|
||||||
|
params->colorspace != MP_CSP_BT_2020_NC &&
|
||||||
params->colorspace != MP_CSP_SMPTE_240M &&
|
params->colorspace != MP_CSP_SMPTE_240M &&
|
||||||
params->colorspace != MP_CSP_YCGCO)
|
params->colorspace != MP_CSP_YCGCO)
|
||||||
{
|
{
|
||||||
|
@ -49,10 +49,10 @@ vec3 srgb_compand(vec3 v)
|
|||||||
lessThanEqual(vec3(0.0031308), v));
|
lessThanEqual(vec3(0.0031308), v));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 bt709_expand(vec3 v)
|
vec3 bt2020_expand(vec3 v)
|
||||||
{
|
{
|
||||||
return mix(v / 4.5, pow((v + vec3(0.099))/1.099, vec3(1/0.45)),
|
return mix(v / 4.5, pow((v + vec3(0.0993))/1.0993, vec3(1/0.45)),
|
||||||
lessThanEqual(vec3(0.0812), v));
|
lessThanEqual(vec3(0.08145), v));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -85,8 +85,8 @@ void main() {
|
|||||||
// Although we are not scaling in linear light, both 3DLUT and SRGB still
|
// Although we are not scaling in linear light, both 3DLUT and SRGB still
|
||||||
// operate on linear light inputs so we have to convert to it before
|
// operate on linear light inputs so we have to convert to it before
|
||||||
// either step can be applied.
|
// either step can be applied.
|
||||||
color.rgb = bt709_expand(color.rgb);
|
color.rgb = bt2020_expand(color.rgb);
|
||||||
// NOTE: This always applies the true BT709, maybe we need to use
|
// NOTE: This always applies the true BT2020, maybe we need to use
|
||||||
// approx-gamma here too?
|
// approx-gamma here too?
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_OSD_3DLUT
|
#ifdef USE_OSD_3DLUT
|
||||||
@ -387,13 +387,18 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_LINEAR_LIGHT
|
#ifdef USE_LINEAR_LIGHT
|
||||||
// If we are scaling in linear light (SRGB or 3DLUT option enabled), we
|
// If we are scaling in linear light (SRGB or 3DLUT option enabled), we
|
||||||
// expand our source colors before scaling
|
// expand our source colors before scaling. This shader currently just
|
||||||
|
// assumes everything uses the BT.2020 12-bit gamma function, since the
|
||||||
|
// difference between this and BT.601, BT.709 and BT.2020 10-bit is well
|
||||||
|
// below the rounding error threshold for both 8-bit and even 10-bit
|
||||||
|
// content. It only makes a difference for 12-bit sources, so it should be
|
||||||
|
// fine to use here.
|
||||||
#ifdef USE_APPROX_GAMMA
|
#ifdef USE_APPROX_GAMMA
|
||||||
// We differentiate between approximate BT.709 (gamma 1.95) ...
|
// We differentiate between approximate BT.2020 (gamma 1.95) ...
|
||||||
color = pow(color, vec3(1.95));
|
color = pow(color, vec3(1.95));
|
||||||
#else
|
#else
|
||||||
// ... and actual BT709 (two-part function)
|
// ... and actual BT.2020 (two-part function)
|
||||||
color = bt709_expand(color);
|
color = bt2020_expand(color);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
// Image upscaling happens roughly here
|
// Image upscaling happens roughly here
|
||||||
|
6
wscript
6
wscript
@ -364,6 +364,12 @@ Libav libraries ({0}). Aborting.".format(" ".join(libav_pkg_config_checks))
|
|||||||
'func': check_statement('libavcodec/avcodec.h', """int x, y;
|
'func': check_statement('libavcodec/avcodec.h', """int x, y;
|
||||||
avcodec_enum_to_chroma_pos(&x, &y, AVCHROMA_LOC_UNSPECIFIED)""",
|
avcodec_enum_to_chroma_pos(&x, &y, AVCHROMA_LOC_UNSPECIFIED)""",
|
||||||
use='libav')
|
use='libav')
|
||||||
|
}, {
|
||||||
|
'name': 'avcol-spc-bt2020',
|
||||||
|
'desc': 'libavcodec avcol_spc_bt2020 available',
|
||||||
|
'func': check_statement('libavcodec/avcodec.h',
|
||||||
|
'int x = AVCOL_SPC_BT2020_NCL',
|
||||||
|
use='libav')
|
||||||
}, {
|
}, {
|
||||||
'name': 'avutil-qp-api',
|
'name': 'avutil-qp-api',
|
||||||
'desc': 'libavutil QP API',
|
'desc': 'libavutil QP API',
|
||||||
|
Loading…
Reference in New Issue
Block a user