diff utils.c @ 9742:0d6f887d91fb libavcodec

Add a lock manager API to libavcodec. Allows an application to register a callback that manages mutexes on behalf of FFmpeg. With this callback registered FFmpeg is fully thread safe.
author andoma
date Sun, 31 May 2009 06:51:18 +0000
parents bc32976d6d9d
children f114b5f2ac47
line wrap: on
line diff
--- a/utils.c	Sun May 31 06:33:58 2009 +0000
+++ b/utils.c	Sun May 31 06:51:18 2009 +0000
@@ -65,6 +65,8 @@
 };
 
 static int volatile entangled_thread_counter=0;
+int (*ff_lockmgr_cb)(void **mutex, enum AVLockOp op);
+static void *codec_mutex;
 
 void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size)
 {
@@ -439,6 +441,12 @@
 {
     int ret= -1;
 
+    /* If there is a user-supplied mutex locking routine, call it. */
+    if (ff_lockmgr_cb) {
+        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
+            return -1;
+    }
+
     entangled_thread_counter++;
     if(entangled_thread_counter != 1){
         av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n");
@@ -483,6 +491,11 @@
     ret=0;
 end:
     entangled_thread_counter--;
+
+    /* Release any user-supplied mutex. */
+    if (ff_lockmgr_cb) {
+        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
+    }
     return ret;
 }
 
@@ -642,6 +655,12 @@
 
 int avcodec_close(AVCodecContext *avctx)
 {
+    /* If there is a user-supplied mutex locking routine, call it. */
+    if (ff_lockmgr_cb) {
+        if ((*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_OBTAIN))
+            return -1;
+    }
+
     entangled_thread_counter++;
     if(entangled_thread_counter != 1){
         av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n");
@@ -657,6 +676,11 @@
     av_freep(&avctx->priv_data);
     avctx->codec = NULL;
     entangled_thread_counter--;
+
+    /* Release any user-supplied mutex. */
+    if (ff_lockmgr_cb) {
+        (*ff_lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE);
+    }
     return 0;
 }
 
@@ -1213,3 +1237,19 @@
     }
     return NULL;
 }
+
+int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
+{
+    if (ff_lockmgr_cb) {
+        if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
+            return -1;
+    }
+
+    ff_lockmgr_cb = cb;
+
+    if (ff_lockmgr_cb) {
+        if (ff_lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
+            return -1;
+    }
+    return 0;
+}