summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/vo.rst11
-rw-r--r--video/out/gl_lcms.c55
-rw-r--r--video/out/gl_lcms.h2
3 files changed, 40 insertions, 28 deletions
diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst
index b398d4f57d..ead2f7b47e 100644
--- a/DOCS/man/vo.rst
+++ b/DOCS/man/vo.rst
@@ -669,11 +669,14 @@ Available video output drivers are:
NOTE: Only implemented on OS X and X11
- ``icc-cache=<file>``
- Store and load the 3D LUT created from the ICC profile in this file.
+ ``icc-cache-dir=<dirname>``
+ Store and load the 3D LUTs created from the ICC profile in this directory.
This can be used to speed up loading, since LittleCMS 2 can take a while
- to create the 3D LUT. Note that this file contains an uncompressed LUT.
- Its size depends on the ``3dlut-size``, and can be very big.
+ to create a 3D LUT. Note that these files contain uncompressed LUTs.
+ Their size depends on the ``3dlut-size``, and can be very big.
+
+ NOTE: This is not cleaned automatically, so old, unused cache files
+ may stick around indefinitely.
``icc-intent=<value>``
Specifies the ICC intent used for the color transformation (when using
diff --git a/video/out/gl_lcms.c b/video/out/gl_lcms.c
index ab273ffc0b..e49ce77a23 100644
--- a/video/out/gl_lcms.c
+++ b/video/out/gl_lcms.c
@@ -39,6 +39,8 @@
#if HAVE_LCMS2
#include <lcms2.h>
+#include <libavutil/sha.h>
+#include <libavutil/mem.h>
struct gl_lcms {
void *icc_data;
@@ -77,9 +79,11 @@ const struct m_sub_options mp_icc_conf = {
.opts = (const m_option_t[]) {
OPT_STRING("icc-profile", profile, 0),
OPT_FLAG("icc-profile-auto", profile_auto, 0),
- OPT_STRING("icc-cache", cache, 0),
+ OPT_STRING("icc-cache-dir", cache_dir, 0),
OPT_INT("icc-intent", intent, 0),
OPT_STRING_VALIDATE("3dlut-size", size_str, 0, validate_3dlut_size_opt),
+
+ OPT_REMOVED("icc-cache", "see icc-cache-dir"),
{0}
},
.size = sizeof(struct mp_icc_opts),
@@ -185,8 +189,6 @@ bool gl_lcms_has_changed(struct gl_lcms *p)
return change;
}
-#define LUT3D_CACHE_HEADER "mpv 3dlut cache 1.0\n"
-
bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d)
{
int s_r, s_g, s_b;
@@ -203,27 +205,36 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d)
struct lut3d *lut = NULL;
cmsContext cms = NULL;
- char *cache_info =
+ char *cache_file = NULL;
+ if (p->opts.cache_dir) {
// Gamma is included in the header to help uniquely identify it,
// because we may change the parameter in the future or make it
// customizable, same for the primaries.
- talloc_asprintf(tmp, "intent=%d, size=%dx%dx%d, gamma=2.4, prim=bt2020\n",
- p->opts.intent, s_r, s_g, s_b);
-
- bstr iccdata = (bstr) {
- .start = p->icc_data,
- .len = p->icc_size,
- };
+ char *cache_info = talloc_asprintf(tmp,
+ "ver=1.1, intent=%d, size=%dx%dx%d, gamma=2.4, prim=bt2020\n",
+ p->opts.intent, s_r, s_g, s_b);
+
+ uint8_t hash[32];
+ struct AVSHA *sha = av_sha_alloc();
+ if (!sha)
+ abort();
+ av_sha_init(sha, 256);
+ av_sha_update(sha, cache_info, strlen(cache_info));
+ av_sha_update(sha, p->icc_data, p->icc_size);
+ av_sha_final(sha, hash);
+ av_free(sha);
+
+ cache_file = talloc_strdup(tmp, p->opts.cache_dir);
+ cache_file = talloc_asprintf_append(cache_file, "/");
+ for (int i = 0; i < sizeof(hash); i++)
+ cache_file = talloc_asprintf_append(cache_file, "%02X", hash[i]);
+ }
// check cache
- if (p->opts.cache) {
- MP_INFO(p, "Opening 3D LUT cache in file '%s'.\n", p->opts.cache);
- struct bstr cachedata = load_file(tmp, p->opts.cache, p->global);
- if (bstr_eatstart(&cachedata, bstr0(LUT3D_CACHE_HEADER))
- && bstr_eatstart(&cachedata, bstr0(cache_info))
- && bstr_eatstart(&cachedata, iccdata)
- && cachedata.len == talloc_get_size(output))
- {
+ if (cache_file) {
+ MP_INFO(p, "Opening 3D LUT cache in file '%s'.\n", cache_file);
+ struct bstr cachedata = load_file(tmp, cache_file, p->global);
+ if (cachedata.len == talloc_get_size(output)) {
memcpy(output, cachedata.start, cachedata.len);
goto done;
} else {
@@ -284,12 +295,10 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d)
cmsDeleteTransform(trafo);
- if (p->opts.cache) {
- char *fname = mp_get_user_path(NULL, p->global, p->opts.cache);
+ if (cache_file) {
+ char *fname = mp_get_user_path(NULL, p->global, cache_file);
FILE *out = fopen(fname, "wb");
if (out) {
- fprintf(out, "%s%s", LUT3D_CACHE_HEADER, cache_info);
- fwrite(p->icc_data, p->icc_size, 1, out);
fwrite(output, talloc_get_size(output), 1, out);
fclose(out);
}
diff --git a/video/out/gl_lcms.h b/video/out/gl_lcms.h
index 883b485f66..5ad08b7d64 100644
--- a/video/out/gl_lcms.h
+++ b/video/out/gl_lcms.h
@@ -10,7 +10,7 @@ extern const struct m_sub_options mp_icc_conf;
struct mp_icc_opts {
char *profile;
int profile_auto;
- char *cache;
+ char *cache_dir;
char *size_str;
int intent;
};