summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/avcodec.h28
-rw-r--r--libavcodec/utils.c36
-rw-r--r--libavcodec/version.h2
3 files changed, 44 insertions, 22 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index dfbab9b60f..f0fa7a959f 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -4393,16 +4393,26 @@ enum AVLockOp {
/**
* Register a user provided lock manager supporting the operations
- * specified by AVLockOp. mutex points to a (void *) where the
- * lockmgr should store/get a pointer to a user allocated mutex. It's
- * NULL upon AV_LOCK_CREATE and != NULL for all other ops.
+ * specified by AVLockOp. The "mutex" argument to the function points
+ * to a (void *) where the lockmgr should store/get a pointer to a user
+ * allocated mutex. It is NULL upon AV_LOCK_CREATE and equal to the
+ * value left by the last call for all other ops. If the lock manager is
+ * unable to perform the op then it should leave the mutex in the same
+ * state as when it was called and return a non-zero value. However,
+ * when called with AV_LOCK_DESTROY the mutex will always be assumed to
+ * have been successfully destroyed. If av_lockmgr_register succeeds
+ * it will return a non-negative value, if it fails it will return a
+ * negative value and destroy all mutex and unregister all callbacks.
+ * av_lockmgr_register is not thread-safe, it must be called from a
+ * single thread before any calls which make use of locking are used.
*
- * @param cb User defined callback. Note: Libav may invoke calls to this
- * callback during the call to av_lockmgr_register().
- * Thus, the application must be prepared to handle that.
- * If cb is set to NULL the lockmgr will be unregistered.
- * Also note that during unregistration the previously registered
- * lockmgr callback may also be invoked.
+ * @param cb User defined callback. av_lockmgr_register invokes calls
+ * to this callback and the previously registered callback.
+ * The callback will be used to create more than one mutex
+ * each of which must be backed by its own underlying locking
+ * mechanism (i.e. do not use a single static object to
+ * implement your lock manager). If cb is set to NULL the
+ * lockmgr will be unregistered.
*/
int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index a47207610d..94eca9bd11 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -2318,20 +2318,32 @@ AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel)
int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
{
if (lockmgr_cb) {
- if (lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
- return -1;
- if (lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
- return -1;
+ // There is no good way to rollback a failure to destroy the
+ // mutex, so we ignore failures.
+ lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY);
+ lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY);
+ lockmgr_cb = NULL;
+ codec_mutex = NULL;
+ avformat_mutex = NULL;
+ }
+
+ if (cb) {
+ void *new_codec_mutex = NULL;
+ void *new_avformat_mutex = NULL;
+ int err;
+ if (err = cb(&new_codec_mutex, AV_LOCK_CREATE)) {
+ return err > 0 ? AVERROR_UNKNOWN : err;
+ }
+ if (err = cb(&new_avformat_mutex, AV_LOCK_CREATE)) {
+ // Ignore failures to destroy the newly created mutex.
+ cb(&new_codec_mutex, AV_LOCK_DESTROY);
+ return err > 0 ? AVERROR_UNKNOWN : err;
+ }
+ lockmgr_cb = cb;
+ codec_mutex = new_codec_mutex;
+ avformat_mutex = new_avformat_mutex;
}
- lockmgr_cb = cb;
-
- if (lockmgr_cb) {
- if (lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
- return -1;
- if (lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
- return -1;
- }
return 0;
}
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 849c4b2dad..773d21e355 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -30,7 +30,7 @@
#define LIBAVCODEC_VERSION_MAJOR 56
#define LIBAVCODEC_VERSION_MINOR 2
-#define LIBAVCODEC_VERSION_MICRO 0
+#define LIBAVCODEC_VERSION_MICRO 1
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \