From 973c1fa5701366eed3752666d6035454ae37712c Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 16 Jun 2014 16:57:19 +0200 Subject: gl_lcms: use thread-safe lcms API, require lcms2 2.6 The error log callback was not thread-safe and not library-safe. And apparently there were some other details that made it not library-safe, such as a global lcms plugin registry. Switch the the thread-safe API provided by lcms2 starting with 2.6. Remove our approximate thread-safety hacks. Note that lcms basically provides 2 APIs now, the old functions, and the thread-safe alternatives whose names end with THR. Some functions don't change, because they already have a context of some sort. Care must be taken not to accidentally use old APIs. --- video/out/gl_lcms.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) (limited to 'video/out') diff --git a/video/out/gl_lcms.c b/video/out/gl_lcms.c index adda52b145..75388ada05 100644 --- a/video/out/gl_lcms.c +++ b/video/out/gl_lcms.c @@ -38,14 +38,8 @@ #if HAVE_LCMS2 -#include #include -// 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) @@ -87,10 +81,8 @@ const struct m_sub_options mp_icc_conf = { static void lcms2_error_handler(cmsContext ctx, cmsUInt32Number code, const char *msg) { - pthread_mutex_lock(&lcms2_dumb_crap_lock); - if (lcms2_dumb_crap) - mp_msg(lcms2_dumb_crap, MSGL_ERR, "lcms2: %s\n", msg); - pthread_mutex_unlock(&lcms2_dumb_crap_lock); + struct mp_log *log = cmsGetContextUserData(ctx); + mp_msg(log, MSGL_ERR, "lcms2: %s\n", msg); } static struct bstr load_file(void *talloc_ctx, const char *filename, @@ -133,7 +125,7 @@ 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; + cmsContext cms = NULL; mp_msg(log, MSGL_INFO, "Opening ICC profile '%s'\n", opts->profile); struct bstr iccdata = load_file(tmp, opts->profile, global); @@ -164,12 +156,12 @@ 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); + cms = cmsCreateContext(NULL, log); + if (!cms) + goto error_exit; + cmsSetLogErrorHandlerTHR(cms, lcms2_error_handler); - cmsHPROFILE profile = cmsOpenProfileFromMem(iccdata.start, iccdata.len); + cmsHPROFILE profile = cmsOpenProfileFromMemTHR(cms, iccdata.start, iccdata.len); if (!profile) goto error_exit; @@ -182,14 +174,14 @@ struct lut3d *mp_load_icc(struct mp_icc_opts *opts, struct mp_log *log, // 2.4 is arbitrarily used as a gamma compression factor for the 3DLUT, // reducing artifacts due to rounding errors on wide gamut profiles - cmsToneCurve *tonecurve = cmsBuildGamma(NULL, 2.4); - cmsHPROFILE vid_profile = cmsCreateRGBProfile(&d65, &bt709prim, + cmsToneCurve *tonecurve = cmsBuildGamma(cms, 2.4); + cmsHPROFILE vid_profile = cmsCreateRGBProfileTHR(cms, &d65, &bt709prim, (cmsToneCurve*[3]){tonecurve, tonecurve, tonecurve}); cmsFreeToneCurve(tonecurve); - cmsHTRANSFORM trafo = cmsCreateTransform(vid_profile, TYPE_RGB_16, - profile, TYPE_RGB_16, - opts->intent, - cmsFLAGS_HIGHRESPRECALC); + cmsHTRANSFORM trafo = cmsCreateTransformTHR(cms, vid_profile, TYPE_RGB_16, + profile, TYPE_RGB_16, + opts->intent, + cmsFLAGS_HIGHRESPRECALC); cmsCloseProfile(profile); cmsCloseProfile(vid_profile); @@ -234,11 +226,8 @@ done: ; error_exit: - if (locked) { - lcms2_dumb_crap = NULL; - cmsSetLogErrorHandler(NULL); - pthread_mutex_unlock(&lcms2_dumb_crap_lock); - } + if (cms) + cmsDeleteContext(cms); if (!lut) mp_msg(log, MSGL_FATAL, "Error loading ICC profile.\n"); -- cgit v1.2.3