mirror of
https://github.com/mpv-player/mpv
synced 2024-09-28 17:52:52 +02:00
vo_opengl: gl_lcms: replace icc-cache by icc-cache-dir
This now stores caches for multiple ICC profiles, potentially all the user has ever used. The big use case for this is for users with multiple monitors. The old logic would mandate recomputing the LUT and discarding the cache whenever dragging mpv from one screen to another. This also avoids having to save and check the ICC profile itself, since the file name already uniquely determines it.
This commit is contained in:
parent
47d46ec487
commit
1153f13bee
@ -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
|
||||
|
@ -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);
|
||||
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);
|
||||
|
||||
bstr iccdata = (bstr) {
|
||||
.start = p->icc_data,
|
||||
.len = p->icc_size,
|
||||
};
|
||||
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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user