summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorNiklas Haas <git@nand.wakku.to>2015-02-06 03:37:21 +0100
committerNiklas Haas <git@nand.wakku.to>2015-02-06 03:37:21 +0100
commit4fed18e81e7ffca623e4260d8569f959410b10bb (patch)
tree3605d5d4c042a951e0a3a21fe97fea9d94c90c85 /video/out
parent4872443fc0217429ba60308213c118dc55b7b88c (diff)
downloadmpv-4fed18e81e7ffca623e4260d8569f959410b10bb.tar.bz2
mpv-4fed18e81e7ffca623e4260d8569f959410b10bb.tar.xz
vo_opengl: add support for linear scaling without CMS
This introduces a new option linear-scaling, which is now implied by srgb, icc-profile and sigmoid-upscaling. Notably, this means (sigmoidized) linear upscaling is now enabled by default in opengl-hq mode. The impact should be negligible, and there has been no observation of negative side effects of sigmoidized scaling, so it feels safe to do so.
Diffstat (limited to 'video/out')
-rw-r--r--video/out/gl_video.c45
-rw-r--r--video/out/gl_video.h1
-rw-r--r--video/out/gl_video_shaders.glsl3
3 files changed, 31 insertions, 18 deletions
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index 9d69c822d8..231d77bdf3 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -370,6 +370,7 @@ const struct m_sub_options gl_video_conf = {
OPT_FLOATRANGE("scale-antiring", scaler_antiring[0], 0, 0.0, 1.0),
OPT_FLOATRANGE("cscale-antiring", scaler_antiring[1], 0, 0.0, 1.0),
OPT_FLAG("scaler-resizes-only", scaler_resizes_only, 0),
+ OPT_FLAG("linear-scaling", linear_scaling, 0),
OPT_FLAG("fancy-downscaling", fancy_downscaling, 0),
OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0),
OPT_FLOATRANGE("sigmoid-center", sigmoid_center, 0, 0.0, 1.0),
@@ -904,6 +905,8 @@ static void compile_shaders(struct gl_video *p)
rg, tex1d, tex3d, arrays, shader_prelude, PRELUDE_END);
bool use_cms = p->opts.srgb || p->use_lut_3d;
+ // 3DLUT overrides sRGB
+ bool use_srgb = p->opts.srgb && !p->use_lut_3d;
float input_gamma = 1.0;
float conv_gamma = 1.0;
@@ -911,12 +914,8 @@ static void compile_shaders(struct gl_video *p)
bool is_xyz = p->image_desc.flags & MP_IMGFLAG_XYZ;
if (is_xyz) {
input_gamma *= 2.6;
-
- // If we're using cms, we can treat it as proper linear input,
- // otherwise we just scale back to 2.40 to match typical displays,
- // as a reasonable approximation.
- if (!use_cms)
- conv_gamma *= 1.0 / 2.40;
+ // Note that this results in linear light, so we make sure to enable
+ // use_linear_light for XYZ inputs as well.
}
p->input_gamma = input_gamma;
@@ -928,10 +927,13 @@ static void compile_shaders(struct gl_video *p)
enum mp_csp_trc gamma_fun = MP_CSP_TRC_NONE;
- // Linear light scaling is only enabled when either color correction
- // option (3dlut or srgb) is enabled, otherwise scaling is done in the
- // source space.
- if (use_cms) {
+ // If either color correction option (3dlut or srgb) is enabled, or if
+ // sigmoidal upscaling is requested, or if the source is linear XYZ, we
+ // always scale in linear light
+ bool use_linear_light = p->opts.linear_scaling || p->opts.sigmoid_upscaling
+ || use_cms || is_xyz;
+
+ if (use_linear_light) {
// We use the color level range to distinguish between PC
// content like images, which are most likely sRGB, and TV content
// like movies, which are most likely BT.1886. XYZ input is always
@@ -945,11 +947,19 @@ static void compile_shaders(struct gl_video *p)
}
}
- bool use_linear_light = gamma_fun != MP_CSP_TRC_NONE;
+ // The inverse of the above transformation is normally handled by
+ // the CMS cases, but if CMS is disabled we need to go back manually
+ bool use_inv_bt1886 = false;
+ if (use_linear_light && !use_cms) {
+ if (gamma_fun == MP_CSP_TRC_SRGB) {
+ use_srgb = true;
+ } else {
+ use_inv_bt1886 = true;
+ }
+ }
- // Optionally transform to sigmoidal color space if requested, but only
- // when upscaling in linear light
- p->sigmoid_enabled = p->opts.sigmoid_upscaling && use_linear_light;
+ // Optionally transform to sigmoidal color space if requested.
+ p->sigmoid_enabled = p->opts.sigmoid_upscaling;
bool use_sigmoid = p->sigmoid_enabled && p->upscaling;
// Figure out the right color spaces we need to convert, if any
@@ -994,8 +1004,7 @@ static void compile_shaders(struct gl_video *p)
use_cms && gamma_fun == MP_CSP_TRC_SRGB);
shader_def_opt(&header_osd, "USE_OSD_CMS_MATRIX", use_cms_matrix);
shader_def_opt(&header_osd, "USE_OSD_3DLUT", p->use_lut_3d);
- // 3DLUT overrides SRGB
- shader_def_opt(&header_osd, "USE_OSD_SRGB", !p->use_lut_3d && p->opts.srgb);
+ shader_def_opt(&header_osd, "USE_OSD_SRGB", use_cms && use_srgb);
for (int n = 0; n < SUBBITMAP_COUNT; n++) {
const char *name = osd_shaders[n];
@@ -1042,8 +1051,8 @@ static void compile_shaders(struct gl_video *p)
shader_def_opt(&header_final, "USE_INV_GAMMA", p->user_gamma_enabled);
shader_def_opt(&header_final, "USE_CMS_MATRIX", use_cms_matrix);
shader_def_opt(&header_final, "USE_3DLUT", p->use_lut_3d);
- // 3DLUT overrides SRGB
- shader_def_opt(&header_final, "USE_SRGB", p->opts.srgb && !p->use_lut_3d);
+ shader_def_opt(&header_final, "USE_SRGB", use_srgb);
+ shader_def_opt(&header_final, "USE_INV_BT1886", use_inv_bt1886);
shader_def_opt(&header_final, "USE_DITHER", p->dither_texture != 0);
shader_def_opt(&header_final, "USE_TEMPORAL_DITHER", p->opts.temporal_dither);
diff --git a/video/out/gl_video.h b/video/out/gl_video.h
index 63e33718ce..74a8b7fd93 100644
--- a/video/out/gl_video.h
+++ b/video/out/gl_video.h
@@ -36,6 +36,7 @@ struct gl_video_opts {
float scaler_antiring[2];
float gamma;
int srgb;
+ int linear_scaling;
int fancy_downscaling;
int sigmoid_upscaling;
float sigmoid_center;
diff --git a/video/out/gl_video_shaders.glsl b/video/out/gl_video_shaders.glsl
index a7348a47e7..636828c0ca 100644
--- a/video/out/gl_video_shaders.glsl
+++ b/video/out/gl_video_shaders.glsl
@@ -508,6 +508,9 @@ void main() {
// Adapt and compand from the linear BT2020 source to the sRGB output
color = srgb_compand(color);
#endif
+#ifdef USE_INV_BT1886
+ color = pow(color, vec3(1.0/1.961));
+#endif
#ifdef USE_DITHER
vec2 dither_pos = gl_FragCoord.xy / dither_size;
#ifdef USE_TEMPORAL_DITHER