summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-12-21 17:55:19 +0100
committerwm4 <wm4@nowhere>2013-12-21 20:50:10 +0100
commit212ce468d83732c5e6e35e307e60f3919c48de34 (patch)
treec231b6d75d49578b2f223812131855a91008f076
parentc8268701d9a4c5ff38b48f0e6b689f6dade4de42 (diff)
downloadmpv-212ce468d83732c5e6e35e307e60f3919c48de34.tar.bz2
mpv-212ce468d83732c5e6e35e307e60f3919c48de34.tar.xz
gl_lcms: use global lock to deal with crappy lcms2 message callback
lcms2 has a global message callback for error reporting. If you don't set this, these error messages are silently thrown away. I think we still want the error messages, so we have to do dumb stuff to avoid clashes. This doesn't handle the case if another library in the same process sets the message callback, but at least this should exclude possible memory errors when running multiple instances of mpv.
-rw-r--r--video/out/gl_lcms.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/video/out/gl_lcms.c b/video/out/gl_lcms.c
index 84ef2d3f68..fb2098324d 100644
--- a/video/out/gl_lcms.c
+++ b/video/out/gl_lcms.c
@@ -38,8 +38,14 @@
#if HAVE_LCMS2
+#include <pthread.h>
#include <lcms2.h>
+// lcms2 only provides a global error handler function, so we have to do this.
+// Not setting a lcms2 error handler will suppress any error messages.
+static pthread_mutex_t lcms2_dumb_crap_lock = PTHREAD_MUTEX_INITIALIZER;
+static struct mp_log *lcms2_dumb_crap;
+
static bool parse_3dlut_size(const char *arg, int *p1, int *p2, int *p3)
{
if (sscanf(arg, "%dx%dx%d", p1, p2, p3) != 3)
@@ -77,10 +83,6 @@ const struct m_sub_options mp_icc_conf = {
},
};
-// lcms2 only provides a global error handler function, so we have to do this.
-// Not setting a lcms2 error handler will suppress any error messages.
-static struct mp_log *lcms2_dumb_crap;
-
static void lcms2_error_handler(cmsContext ctx, cmsUInt32Number code,
const char *msg)
{
@@ -115,6 +117,8 @@ struct lut3d *mp_load_icc(struct mp_icc_opts *opts, struct mp_log *log,
void *tmp = talloc_new(NULL);
uint16_t *output = talloc_array(tmp, uint16_t, s_r * s_g * s_b * 3);
+ struct lut3d *lut = NULL;
+ bool locked = false;
mp_msg_log(log, MSGL_INFO, "Opening ICC profile '%s'\n", opts->profile);
struct bstr iccdata = load_file(tmp, opts->profile);
@@ -141,6 +145,8 @@ struct lut3d *mp_load_icc(struct mp_icc_opts *opts, struct mp_log *log,
}
}
+ locked = true;
+ pthread_mutex_lock(&lcms2_dumb_crap_lock);
lcms2_dumb_crap = log;
cmsSetLogErrorHandler(lcms2_error_handler);
@@ -197,23 +203,25 @@ struct lut3d *mp_load_icc(struct mp_icc_opts *opts, struct mp_log *log,
done: ;
- struct lut3d *lut = talloc_ptrtype(NULL, lut);
+ lut = talloc_ptrtype(NULL, lut);
*lut = (struct lut3d) {
.data = talloc_steal(lut, output),
.size = {s_r, s_g, s_b},
};
- lcms2_dumb_crap = NULL;
- cmsSetLogErrorHandler(NULL);
- talloc_free(tmp);
- return lut;
-
error_exit:
- mp_msg_log(log, MSGL_FATAL, "Error loading ICC profile.\n");
- lcms2_dumb_crap = NULL;
- cmsSetLogErrorHandler(NULL);
+
+ if (locked) {
+ lcms2_dumb_crap = NULL;
+ cmsSetLogErrorHandler(NULL);
+ pthread_mutex_unlock(&lcms2_dumb_crap_lock);
+ }
+
+ if (!lut)
+ mp_msg_log(log, MSGL_FATAL, "Error loading ICC profile.\n");
+
talloc_free(tmp);
- return NULL;
+ return lut;
}
#else /* HAVE_LCMS2 */