mirror of
https://github.com/mpv-player/mpv
synced 2025-03-19 09:57:34 +00:00
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.
This commit is contained in:
parent
4872443fc0
commit
4fed18e81e
@ -359,7 +359,7 @@ Available video output drivers are:
|
|||||||
|
|
||||||
``srgb``
|
``srgb``
|
||||||
Convert and color correct the output to sRGB before displaying it on
|
Convert and color correct the output to sRGB before displaying it on
|
||||||
the screen. This option enables linear light scaling.
|
the screen. This option enables ``linear-scaling``.
|
||||||
|
|
||||||
This option is equivalent to using ``icc-profile`` with an sRGB ICC
|
This option is equivalent to using ``icc-profile`` with an sRGB ICC
|
||||||
profile, but it is implemented without a 3DLUT and does not require
|
profile, but it is implemented without a 3DLUT and does not require
|
||||||
@ -438,6 +438,11 @@ Available video output drivers are:
|
|||||||
See ``scale-param1``, ``scale-param2``, ``scale-radius`` and
|
See ``scale-param1``, ``scale-param2``, ``scale-radius`` and
|
||||||
``scale-antiring``.
|
``scale-antiring``.
|
||||||
|
|
||||||
|
``linear-scaling``
|
||||||
|
Scale in linear light. This is automatically enabled if ``srgb``,
|
||||||
|
``icc-profile`` or ``sigmoid-upscaling`` is set. It should only
|
||||||
|
be used with a ``fbo-format`` that has at least 16 bit precision.
|
||||||
|
|
||||||
``fancy-downscaling``
|
``fancy-downscaling``
|
||||||
When using convolution based filters, extend the filter size
|
When using convolution based filters, extend the filter size
|
||||||
when downscaling. Trades quality for reduced downscaling performance.
|
when downscaling. Trades quality for reduced downscaling performance.
|
||||||
@ -447,8 +452,8 @@ Available video output drivers are:
|
|||||||
different directions.
|
different directions.
|
||||||
|
|
||||||
``sigmoid-upscaling``
|
``sigmoid-upscaling``
|
||||||
When upscaling in linear light, use a sigmoidal color transform
|
When upscaling, use a sigmoidal color transform to avoid emphasizing
|
||||||
to avoid emphasizing ringing artifacts.
|
ringing artifacts. This also enables ``linear-scaling``.
|
||||||
|
|
||||||
``sigmoid-center``
|
``sigmoid-center``
|
||||||
The center of the sigmoid curve used for ``sigmoid-upscaling``, must
|
The center of the sigmoid curve used for ``sigmoid-upscaling``, must
|
||||||
@ -521,8 +526,8 @@ Available video output drivers are:
|
|||||||
``icc-profile=<file>``
|
``icc-profile=<file>``
|
||||||
Load an ICC profile and use it to transform linear RGB to screen output.
|
Load an ICC profile and use it to transform linear RGB to screen output.
|
||||||
Needs LittleCMS 2 support compiled in. This option overrides the ``srgb``
|
Needs LittleCMS 2 support compiled in. This option overrides the ``srgb``
|
||||||
property, as using both is somewhat redundant. It also enables linear
|
property, as using both is somewhat redundant. It also enables
|
||||||
light scaling.
|
``linear-scaling``.
|
||||||
|
|
||||||
|
|
||||||
``icc-profile-auto``
|
``icc-profile-auto``
|
||||||
|
@ -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("scale-antiring", scaler_antiring[0], 0, 0.0, 1.0),
|
||||||
OPT_FLOATRANGE("cscale-antiring", scaler_antiring[1], 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("scaler-resizes-only", scaler_resizes_only, 0),
|
||||||
|
OPT_FLAG("linear-scaling", linear_scaling, 0),
|
||||||
OPT_FLAG("fancy-downscaling", fancy_downscaling, 0),
|
OPT_FLAG("fancy-downscaling", fancy_downscaling, 0),
|
||||||
OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0),
|
OPT_FLAG("sigmoid-upscaling", sigmoid_upscaling, 0),
|
||||||
OPT_FLOATRANGE("sigmoid-center", sigmoid_center, 0, 0.0, 1.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);
|
rg, tex1d, tex3d, arrays, shader_prelude, PRELUDE_END);
|
||||||
|
|
||||||
bool use_cms = p->opts.srgb || p->use_lut_3d;
|
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 input_gamma = 1.0;
|
||||||
float conv_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;
|
bool is_xyz = p->image_desc.flags & MP_IMGFLAG_XYZ;
|
||||||
if (is_xyz) {
|
if (is_xyz) {
|
||||||
input_gamma *= 2.6;
|
input_gamma *= 2.6;
|
||||||
|
// Note that this results in linear light, so we make sure to enable
|
||||||
// If we're using cms, we can treat it as proper linear input,
|
// use_linear_light for XYZ inputs as well.
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p->input_gamma = input_gamma;
|
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;
|
enum mp_csp_trc gamma_fun = MP_CSP_TRC_NONE;
|
||||||
|
|
||||||
// Linear light scaling is only enabled when either color correction
|
// If either color correction option (3dlut or srgb) is enabled, or if
|
||||||
// option (3dlut or srgb) is enabled, otherwise scaling is done in the
|
// sigmoidal upscaling is requested, or if the source is linear XYZ, we
|
||||||
// source space.
|
// always scale in linear light
|
||||||
if (use_cms) {
|
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
|
// We use the color level range to distinguish between PC
|
||||||
// content like images, which are most likely sRGB, and TV content
|
// content like images, which are most likely sRGB, and TV content
|
||||||
// like movies, which are most likely BT.1886. XYZ input is always
|
// 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
|
// Optionally transform to sigmoidal color space if requested.
|
||||||
// when upscaling in linear light
|
p->sigmoid_enabled = p->opts.sigmoid_upscaling;
|
||||||
p->sigmoid_enabled = p->opts.sigmoid_upscaling && use_linear_light;
|
|
||||||
bool use_sigmoid = p->sigmoid_enabled && p->upscaling;
|
bool use_sigmoid = p->sigmoid_enabled && p->upscaling;
|
||||||
|
|
||||||
// Figure out the right color spaces we need to convert, if any
|
// 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);
|
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_CMS_MATRIX", use_cms_matrix);
|
||||||
shader_def_opt(&header_osd, "USE_OSD_3DLUT", p->use_lut_3d);
|
shader_def_opt(&header_osd, "USE_OSD_3DLUT", p->use_lut_3d);
|
||||||
// 3DLUT overrides SRGB
|
shader_def_opt(&header_osd, "USE_OSD_SRGB", use_cms && use_srgb);
|
||||||
shader_def_opt(&header_osd, "USE_OSD_SRGB", !p->use_lut_3d && p->opts.srgb);
|
|
||||||
|
|
||||||
for (int n = 0; n < SUBBITMAP_COUNT; n++) {
|
for (int n = 0; n < SUBBITMAP_COUNT; n++) {
|
||||||
const char *name = osd_shaders[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_INV_GAMMA", p->user_gamma_enabled);
|
||||||
shader_def_opt(&header_final, "USE_CMS_MATRIX", use_cms_matrix);
|
shader_def_opt(&header_final, "USE_CMS_MATRIX", use_cms_matrix);
|
||||||
shader_def_opt(&header_final, "USE_3DLUT", p->use_lut_3d);
|
shader_def_opt(&header_final, "USE_3DLUT", p->use_lut_3d);
|
||||||
// 3DLUT overrides SRGB
|
shader_def_opt(&header_final, "USE_SRGB", use_srgb);
|
||||||
shader_def_opt(&header_final, "USE_SRGB", p->opts.srgb && !p->use_lut_3d);
|
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_DITHER", p->dither_texture != 0);
|
||||||
shader_def_opt(&header_final, "USE_TEMPORAL_DITHER", p->opts.temporal_dither);
|
shader_def_opt(&header_final, "USE_TEMPORAL_DITHER", p->opts.temporal_dither);
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ struct gl_video_opts {
|
|||||||
float scaler_antiring[2];
|
float scaler_antiring[2];
|
||||||
float gamma;
|
float gamma;
|
||||||
int srgb;
|
int srgb;
|
||||||
|
int linear_scaling;
|
||||||
int fancy_downscaling;
|
int fancy_downscaling;
|
||||||
int sigmoid_upscaling;
|
int sigmoid_upscaling;
|
||||||
float sigmoid_center;
|
float sigmoid_center;
|
||||||
|
@ -508,6 +508,9 @@ void main() {
|
|||||||
// Adapt and compand from the linear BT2020 source to the sRGB output
|
// Adapt and compand from the linear BT2020 source to the sRGB output
|
||||||
color = srgb_compand(color);
|
color = srgb_compand(color);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_INV_BT1886
|
||||||
|
color = pow(color, vec3(1.0/1.961));
|
||||||
|
#endif
|
||||||
#ifdef USE_DITHER
|
#ifdef USE_DITHER
|
||||||
vec2 dither_pos = gl_FragCoord.xy / dither_size;
|
vec2 dither_pos = gl_FragCoord.xy / dither_size;
|
||||||
#ifdef USE_TEMPORAL_DITHER
|
#ifdef USE_TEMPORAL_DITHER
|
||||||
|
Loading…
Reference in New Issue
Block a user