From 40de03fdba6cef8963f991e621866977977ef437 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Thu, 14 Sep 2023 20:31:57 +0200 Subject: [PATCH] vo_gpu: vo_gpu_next: support --icc-3dlut-size=auto And make it the default. In libplacebo, this uses internal heuristics to pick a good size based on the actual ICC characteristics. This is significantly less wasteful than always generating a 64x64x64 3DLUT (the old status quo). In vo_gpu, for simplicity, just default to 65x65x65. Note that this provides slightly better accuracy than the old default of 64x64x64 for technical reasons, and matches what libplacebo defaults to for typical display profiles. --- DOCS/interface-changes.rst | 1 + DOCS/man/options.rst | 7 ++++--- video/out/gpu/lcms.c | 8 +++++++- video/out/gpu/lcms.h | 4 ++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 44f2886895..d0a6f40843 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -57,6 +57,7 @@ Interface changes - add `video-params/crop-[w,h,x,y]` - remove `--tone-mapping-mode` - change `--subs-fallback-forced` so that it works alongside `--slang` + - add `--icc-3dlut-size=auto` and make it the default --- mpv 0.36.0 --- - add `--target-contrast` - Target luminance value is now also applied when ICC profile is used. diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index bfc815649c..1203133554 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -6812,9 +6812,10 @@ them. 3 absolute colorimetric -``--icc-3dlut-size=xx`` - Size of the 3D LUT generated from the ICC profile in each dimension. - Default is 64x64x64. Sizes may range from 2 to 512. +``--icc-3dlut-size=`` + Size of the 3D LUT generated from the ICC profile in each dimension. The + default of ``auto`` means to pick the size automatically based on internal + heuristics. Sizes may range from 2 to 512. ``--icc-force-contrast=`` Override the target device's detected contrast ratio by a specific value. diff --git a/video/out/gpu/lcms.c b/video/out/gpu/lcms.c index 47ea160d8c..360363385c 100644 --- a/video/out/gpu/lcms.c +++ b/video/out/gpu/lcms.c @@ -326,6 +326,12 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d, if (!gl_lcms_has_profile(p)) return false; + // For simplicity, default to 65x65x65, which is large enough to cover + // typical profiles with good accuracy while not being too wasteful + s_r = s_r ? s_r : 65; + s_g = s_g ? s_g : 65; + s_b = s_b ? s_b : 65; + void *tmp = talloc_new(NULL); uint16_t *output = talloc_array(tmp, uint16_t, s_r * s_g * s_b * 4); struct lut3d *lut = NULL; @@ -514,7 +520,7 @@ const struct m_sub_options mp_icc_conf = { }, .size = sizeof(struct mp_icc_opts), .defaults = &(const struct mp_icc_opts) { - .size_str = "64x64x64", + .size_str = "auto", .intent = MP_INTENT_RELATIVE_COLORIMETRIC, .use_embedded = true, .cache = true, diff --git a/video/out/gpu/lcms.h b/video/out/gpu/lcms.h index 7effc718f2..607353a84f 100644 --- a/video/out/gpu/lcms.h +++ b/video/out/gpu/lcms.h @@ -44,6 +44,10 @@ bool gl_lcms_has_changed(struct gl_lcms *p, enum mp_csp_prim prim, static inline bool gl_parse_3dlut_size(const char *arg, int *p1, int *p2, int *p3) { + if (!strcmp(arg, "auto")) { + *p1 = *p2 = *p3 = 0; + return true; + } if (sscanf(arg, "%dx%dx%d", p1, p2, p3) != 3) return false; for (int n = 0; n < 3; n++) {