summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2022-09-11 16:47:14 +0200
committerNiklas Haas <github-daiK1o@haasn.dev>2022-09-12 15:35:17 +0200
commit30ca46259e574b2c311a2211948d849441e1ac4d (patch)
tree8d7e9969004f131df863450c56a797405e71a48f /video/out
parent7a6dc79e29b9a602cf668e6ff20a92207ec93223 (diff)
downloadmpv-30ca46259e574b2c311a2211948d849441e1ac4d.tar.bz2
mpv-30ca46259e574b2c311a2211948d849441e1ac4d.tar.xz
vo_gpu_next: implement ICC 3DLUT caching
Relies on a new upstream API for adding save/load callbacks to the ICC 3DLUT generation parameters. Closes: https://github.com/mpv-player/mpv/issues/10252
Diffstat (limited to 'video/out')
-rw-r--r--video/out/vo_gpu_next.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c
index bd0eb4ce84..776fdf49cd 100644
--- a/video/out/vo_gpu_next.c
+++ b/video/out/vo_gpu_next.c
@@ -1512,6 +1512,66 @@ static const struct pl_hook *load_hook(struct priv *p, const char *path)
return hook;
}
+#if PL_API_VER >= 222
+
+static stream_t *icc_open_cache(struct priv *p, uint64_t sig, int flags)
+{
+ const struct gl_video_opts *opts = p->opts_cache->opts;
+ if (!opts->icc_opts->cache_dir || !opts->icc_opts->cache_dir[0])
+ return NULL;
+
+ char cache_name[16+1];
+ for (int i = 0; i < 16; i++) {
+ cache_name[i] = "0123456789ABCDEF"[sig & 0xF];
+ sig >>= 4;
+ }
+ cache_name[16] = '\0';
+
+ char *cache_dir = mp_get_user_path(NULL, p->global, opts->icc_opts->cache_dir);
+ char *path = mp_path_join(NULL, cache_dir, cache_name);
+
+ stream_t *stream = NULL;
+ if (flags & STREAM_WRITE) {
+ mp_mkdirp(cache_dir);
+ } else {
+ // Exit silently if the file does not exist
+ if (stat(path, &(struct stat) {0}) < 0)
+ goto done;
+ }
+
+ flags |= STREAM_ORIGIN_DIRECT | STREAM_LOCAL_FS_ONLY | STREAM_LESS_NOISE;
+ stream = stream_create(path, flags, NULL, p->global);
+ // fall through
+done:
+ talloc_free(cache_dir);
+ talloc_free(path);
+ return stream;
+}
+
+static void icc_save(void *priv, uint64_t sig, const uint8_t *cache, size_t size)
+{
+ struct priv *p = priv;
+ stream_t *s = icc_open_cache(p, sig, STREAM_WRITE);
+ if (!s)
+ return;
+ stream_write_buffer(s, (void *) cache, size);
+ free_stream(s);
+}
+
+static bool icc_load(void *priv, uint64_t sig, uint8_t *cache, size_t size)
+{
+ struct priv *p = priv;
+ stream_t *s = icc_open_cache(p, sig, STREAM_READ);
+ if (!s)
+ return false;
+
+ int len = stream_read(s, cache, size);
+ free_stream(s);
+ return len == size;
+}
+
+#endif // PL_API_VER
+
static void update_icc_opts(struct priv *p, const struct mp_icc_opts *opts)
{
if (!opts)
@@ -1533,6 +1593,11 @@ static void update_icc_opts(struct priv *p, const struct mp_icc_opts *opts)
p->icc.size_r = s_r;
p->icc.size_g = s_g;
p->icc.size_b = s_b;
+#if PL_API_VER >= 222
+ p->icc.cache_priv = p;
+ p->icc.cache_save = icc_save;
+ p->icc.cache_load = icc_load;
+#endif
if (!opts->profile || !opts->profile[0]) {
// No profile enabled, un-load any existing profiles