diff options
author | Niklas Haas <git@nand.wakku.to> | 2014-06-22 08:33:43 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-06-22 19:02:06 +0200 |
commit | 17762a1919947db0e66e025bd2084de896eaa3fa (patch) | |
tree | 86aaf7c3c7bf37c9bf7a3c7f19eac9bacf7cd07e /video/out/gl_video.c | |
parent | 204fed4d5b4aa20b5a6b5824f5d4e71ccbaf87fb (diff) | |
download | mpv-17762a1919947db0e66e025bd2084de896eaa3fa.tar.bz2 mpv-17762a1919947db0e66e025bd2084de896eaa3fa.tar.xz |
video: Generate an accurate CMS matrix instead of hard-coding
This also avoids an extra matrix multiplication when using :srgb, making
that path both more efficient and also eliminating more hard-coded
values.
In addition, the previously hard-coded XYZ to RGB matrix will be
dynamically generated.
Diffstat (limited to 'video/out/gl_video.c')
-rw-r--r-- | video/out/gl_video.c | 63 |
1 files changed, 41 insertions, 22 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c index f0981887c6..c2ed11be5c 100644 --- a/video/out/gl_video.c +++ b/video/out/gl_video.c @@ -195,6 +195,9 @@ struct gl_video { struct mp_csp_equalizer video_eq; struct mp_image_params image_params; + // Source and destination color spaces for the CMS matrix + struct mp_csp_primaries csp_src, csp_dest; + struct mp_rect src_rect; // displayed part of the source video struct mp_rect src_rect_rot;// compensated for optional rotation struct mp_rect dst_rect; // video rectangle on output window @@ -642,7 +645,7 @@ static void update_uniforms(struct gl_video *p, GLuint program) loc = gl->GetUniformLocation(program, "cms_matrix"); if (loc >= 0) { float cms_matrix[3][3] = {{0}}; - mp_get_cms_matrix(p->image_params.primaries, cms_matrix); + mp_get_cms_matrix(p->csp_src, p->csp_dest, cms_matrix); gl->UniformMatrix3fv(loc, 1, GL_TRUE, &cms_matrix[0][0]); } @@ -848,7 +851,43 @@ static void compile_shaders(struct gl_video *p) shader_prelude, PRELUDE_END); bool use_cms = p->opts.srgb || p->use_lut_3d; - bool use_cms_matrix = use_cms && (p->image_params.primaries != MP_CSP_PRIM_BT_2020); + + float input_gamma = 1.0; + float conv_gamma = 1.0; + + if (p->image_desc.flags & MP_IMGFLAG_XYZ) { + input_gamma *= 2.6; + + // If we're using cms, we can treat it as proper linear input, + // otherwise we just scale back to 1.95 as a reasonable approximation. + if (use_cms) { + p->is_linear_rgb = true; + } else { + conv_gamma *= 1.0 / 1.95; + } + } + + p->input_gamma = input_gamma; + p->conv_gamma = conv_gamma; + + bool use_input_gamma = p->input_gamma != 1.0; + bool use_conv_gamma = p->conv_gamma != 1.0; + bool use_const_luma = p->image_params.colorspace == MP_CSP_BT_2020_C; + + // Linear light scaling is only enabled when either color correction + // option (3dlut or srgb) is enabled, otherwise scaling is done in the + // source space. We also need to linearize for constant luminance systems. + bool convert_to_linear_gamma = !p->is_linear_rgb && use_cms || use_const_luma; + + // Figure out the right color spaces we need to convert, if any + enum mp_csp_prim dest = p->opts.srgb ? MP_CSP_PRIM_BT_709 : MP_CSP_PRIM_BT_2020; + bool use_cms_matrix = false; + + if (use_cms && p->image_params.primaries != dest) { + p->csp_src = mp_get_csp_primaries(p->image_params.primaries); + p->csp_dest = mp_get_csp_primaries(dest); + use_cms_matrix = true; + } if (p->gl_target == GL_TEXTURE_RECTANGLE) { shader_def(&header, "VIDEO_SAMPLER", "sampler2DRect"); @@ -881,26 +920,6 @@ static void compile_shaders(struct gl_video *p) char *header_final = talloc_strdup(tmp, ""); char *header_sep = NULL; - float input_gamma = 1.0; - float conv_gamma = 1.0; - - if (p->image_desc.flags & MP_IMGFLAG_XYZ) { - input_gamma *= 2.6; - conv_gamma *= 1.0 / 2.2; - } - - p->input_gamma = input_gamma; - p->conv_gamma = conv_gamma; - - bool use_input_gamma = p->input_gamma != 1.0; - bool use_conv_gamma = p->conv_gamma != 1.0; - bool use_const_luma = p->image_params.colorspace == MP_CSP_BT_2020_C; - - // Linear light scaling is only enabled when either color correction - // option (3dlut or srgb) is enabled, otherwise scaling is done in the - // source space. We also need to linearize for constant luminance systems. - bool convert_to_linear_gamma = !p->is_linear_rgb && use_cms || use_const_luma; - if (p->image_format == IMGFMT_NV12 || p->image_format == IMGFMT_NV21) { shader_def(&header_conv, "USE_CONV", "CONV_NV12"); } else if (p->plane_count > 1) { |