mirror of https://github.com/mpv-player/mpv
vo_gpu: replace --icc-contrast by --icc-force-contrast
Not only does this have semantics that make far more sense, it also has a default that makes far more sense. (Equivalent to the old `icc-contrast=inf`) This removes the weird 1000:1 contrast default assumption which especially broke perceptual profiles and also screws things up for OLED/CRT/etc. Should probably close some issues but I honestly can't be bothered to figure out which of the thousands colorimetry-related issues are affected.
This commit is contained in:
parent
c26d83348b
commit
353cccfa8c
|
@ -37,6 +37,9 @@ Interface changes
|
||||||
- add an additional optional `albumart` argument to the `video-add` command,
|
- add an additional optional `albumart` argument to the `video-add` command,
|
||||||
which tells mpv to load the given video as album art.
|
which tells mpv to load the given video as album art.
|
||||||
- undeprecate `--cache-secs` option
|
- undeprecate `--cache-secs` option
|
||||||
|
- remove `--icc-contrast` and introduce `--icc-force-contrast`. The latter
|
||||||
|
defaults to the equivalent of the old `--icc-contrast=inf`, and can
|
||||||
|
instead be used to specifically set the contrast to any value.
|
||||||
--- mpv 0.33.0 ---
|
--- mpv 0.33.0 ---
|
||||||
- add `--d3d11-exclusive-fs` flag to enable D3D11 exclusive fullscreen mode
|
- add `--d3d11-exclusive-fs` flag to enable D3D11 exclusive fullscreen mode
|
||||||
when the player enters fullscreen.
|
when the player enters fullscreen.
|
||||||
|
|
|
@ -6358,14 +6358,15 @@ The following video options are currently all specific to ``--vo=gpu`` and
|
||||||
Size of the 3D LUT generated from the ICC profile in each dimension.
|
Size of the 3D LUT generated from the ICC profile in each dimension.
|
||||||
Default is 64x64x64. Sizes may range from 2 to 512.
|
Default is 64x64x64. Sizes may range from 2 to 512.
|
||||||
|
|
||||||
``--icc-contrast=<0-1000000|inf>``
|
``--icc-force-contrast=<no|0-1000000|inf>``
|
||||||
Specifies an upper limit on the target device's contrast ratio. This is
|
Override the target device's detected contrast ratio by a specific value.
|
||||||
detected automatically from the profile if possible, but for some profiles
|
This is detected automatically from the profile if possible, but for some
|
||||||
it might be missing, causing the contrast to be assumed as infinite. As a
|
profiles it might be missing, causing the contrast to be assumed as
|
||||||
result, video may appear darker than intended. This only affects BT.1886
|
infinite. As a result, video may appear darker than intended. If this is
|
||||||
content. The default of 0 means no limit if the detected contrast is less
|
the case, setting this option might help. This only affects BT.1886
|
||||||
than 100000, and limits to 1000 otherwise. Use ``--icc-contrast=inf`` to
|
content. The default of ``no`` means to use the profile values. The special
|
||||||
preserve the infinite contrast (most likely when using OLED displays).
|
value ``inf`` causes the BT.1886 curve to be treated as a pure power gamma
|
||||||
|
2.4 function.
|
||||||
|
|
||||||
``--blend-subtitles=<yes|video|no>``
|
``--blend-subtitles=<yes|video|no>``
|
||||||
Blend subtitles directly onto upscaled video frames, before interpolation
|
Blend subtitles directly onto upscaled video frames, before interpolation
|
||||||
|
|
|
@ -84,11 +84,12 @@ const struct m_sub_options mp_icc_conf = {
|
||||||
{"icc-profile-auto", OPT_FLAG(profile_auto)},
|
{"icc-profile-auto", OPT_FLAG(profile_auto)},
|
||||||
{"icc-cache-dir", OPT_STRING(cache_dir), .flags = M_OPT_FILE},
|
{"icc-cache-dir", OPT_STRING(cache_dir), .flags = M_OPT_FILE},
|
||||||
{"icc-intent", OPT_INT(intent)},
|
{"icc-intent", OPT_INT(intent)},
|
||||||
{"icc-contrast", OPT_CHOICE(contrast, {"inf", -1}),
|
{"icc-force-contrast", OPT_CHOICE(contrast, {"no", 0}, {"inf", -1}),
|
||||||
M_RANGE(0, 1000000)},
|
M_RANGE(0, 1000000)},
|
||||||
{"icc-3dlut-size", OPT_STRING_VALIDATE(size_str, validate_3dlut_size_opt)},
|
{"icc-3dlut-size", OPT_STRING_VALIDATE(size_str, validate_3dlut_size_opt)},
|
||||||
{"3dlut-size", OPT_REPLACED("icc-3dlut-size")},
|
{"3dlut-size", OPT_REPLACED("icc-3dlut-size")},
|
||||||
{"icc-cache", OPT_REMOVED("see icc-cache-dir")},
|
{"icc-cache", OPT_REMOVED("see icc-cache-dir")},
|
||||||
|
{"icc-contrast", OPT_REMOVED("see icc-force-contrast")},
|
||||||
{0}
|
{0}
|
||||||
},
|
},
|
||||||
.size = sizeof(struct mp_icc_opts),
|
.size = sizeof(struct mp_icc_opts),
|
||||||
|
@ -272,48 +273,46 @@ static cmsHPROFILE get_vid_profile(struct gl_lcms *p, cmsContext cms,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_CSP_TRC_BT_1886: {
|
case MP_CSP_TRC_BT_1886: {
|
||||||
// To build an appropriate BT.1886 transformation we need access to
|
|
||||||
// the display's black point, so we LittleCMS' detection function.
|
|
||||||
// Relative colorimetric is used since we want to approximate the
|
|
||||||
// BT.1886 to the target device's actual black point even in e.g.
|
|
||||||
// perceptual mode
|
|
||||||
const int intent = MP_INTENT_RELATIVE_COLORIMETRIC;
|
|
||||||
cmsCIEXYZ bp_XYZ;
|
|
||||||
if (!cmsDetectBlackPoint(&bp_XYZ, disp_profile, intent, 0))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Map this XYZ value back into the (linear) source space
|
|
||||||
cmsToneCurve *linear = cmsBuildGamma(cms, 1.0);
|
|
||||||
cmsHPROFILE rev_profile = cmsCreateRGBProfileTHR(cms, &wp_xyY, &prim_xyY,
|
|
||||||
(cmsToneCurve*[3]){linear, linear, linear});
|
|
||||||
cmsHPROFILE xyz_profile = cmsCreateXYZProfile();
|
|
||||||
cmsHTRANSFORM xyz2src = cmsCreateTransformTHR(cms,
|
|
||||||
xyz_profile, TYPE_XYZ_DBL, rev_profile, TYPE_RGB_DBL,
|
|
||||||
intent, 0);
|
|
||||||
cmsFreeToneCurve(linear);
|
|
||||||
cmsCloseProfile(rev_profile);
|
|
||||||
cmsCloseProfile(xyz_profile);
|
|
||||||
if (!xyz2src)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
double src_black[3];
|
double src_black[3];
|
||||||
cmsDoTransform(xyz2src, &bp_XYZ, src_black, 1);
|
if (p->opts->contrast < 0) {
|
||||||
cmsDeleteTransform(xyz2src);
|
// User requested infinite contrast, return 2.4 profile
|
||||||
|
tonecurve[0] = cmsBuildGamma(cms, 2.4);
|
||||||
// Contrast limiting
|
break;
|
||||||
if (p->opts->contrast > 0) {
|
} else if (p->opts->contrast > 0) {
|
||||||
|
MP_VERBOSE(p, "Using specified contrast: %d\n", p->opts->contrast);
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
src_black[i] = MPMAX(src_black[i], 1.0 / p->opts->contrast);
|
src_black[i] = 1.0 / p->opts->contrast;
|
||||||
}
|
} else {
|
||||||
|
// To build an appropriate BT.1886 transformation we need access to
|
||||||
|
// the display's black point, so we use LittleCMS' detection
|
||||||
|
// function. Relative colorimetric is used since we want to
|
||||||
|
// approximate the BT.1886 to the target device's actual black
|
||||||
|
// point even in e.g. perceptual mode
|
||||||
|
const int intent = MP_INTENT_RELATIVE_COLORIMETRIC;
|
||||||
|
cmsCIEXYZ bp_XYZ;
|
||||||
|
if (!cmsDetectBlackPoint(&bp_XYZ, disp_profile, intent, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Built-in contrast failsafe
|
// Map this XYZ value back into the (linear) source space
|
||||||
double contrast = 3.0 / (src_black[0] + src_black[1] + src_black[2]);
|
cmsHPROFILE rev_profile;
|
||||||
MP_VERBOSE(p, "Detected ICC profile contrast: %f\n", contrast);
|
cmsToneCurve *linear = cmsBuildGamma(cms, 1.0);
|
||||||
if (contrast > 100000 && !p->opts->contrast) {
|
rev_profile = cmsCreateRGBProfileTHR(cms, &wp_xyY, &prim_xyY,
|
||||||
MP_WARN(p, "ICC profile detected contrast very high (>100000),"
|
(cmsToneCurve*[3]){linear, linear, linear});
|
||||||
" falling back to contrast 1000 for sanity. Set the"
|
cmsHPROFILE xyz_profile = cmsCreateXYZProfile();
|
||||||
" icc-contrast option to silence this warning.\n");
|
cmsHTRANSFORM xyz2src = cmsCreateTransformTHR(cms,
|
||||||
src_black[0] = src_black[1] = src_black[2] = 1.0 / 1000;
|
xyz_profile, TYPE_XYZ_DBL, rev_profile, TYPE_RGB_DBL,
|
||||||
|
intent, 0);
|
||||||
|
cmsFreeToneCurve(linear);
|
||||||
|
cmsCloseProfile(rev_profile);
|
||||||
|
cmsCloseProfile(xyz_profile);
|
||||||
|
if (!xyz2src)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
cmsDoTransform(xyz2src, &bp_XYZ, src_black, 1);
|
||||||
|
cmsDeleteTransform(xyz2src);
|
||||||
|
|
||||||
|
double contrast = 3.0 / (src_black[0] + src_black[1] + src_black[2]);
|
||||||
|
MP_VERBOSE(p, "Detected ICC profile contrast: %f\n", contrast);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the parametric BT.1886 transfer curve, one per channel
|
// Build the parametric BT.1886 transfer curve, one per channel
|
||||||
|
|
Loading…
Reference in New Issue