[FFmpeg-cvslog] r21731 - in branches/0.5: . Changelog doc/APIchanges libavcodec/avcodec.h libavcodec/utils.c

siretart subversion
Tue Feb 9 21:28:43 CET 2010


Author: siretart
Date: Tue Feb  9 21:28:42 2010
New Revision: 21731

Log:
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.

backport r19025 by andoma

NB: This is a feature backport with little regression potential. It was
requested at FOSDEM 2010 by ben at geexbox.org for use by geexbox and the
enna mediacenter in the upcoming debian/squeeze and ubuntu/lucid
release.

Approved by DonDiego on #ffmpeg-devel

Modified:
   branches/0.5/   (props changed)
   branches/0.5/Changelog
   branches/0.5/doc/APIchanges
   branches/0.5/libavcodec/avcodec.h
   branches/0.5/libavcodec/utils.c

Modified: branches/0.5/Changelog
==============================================================================
--- branches/0.5/Changelog	Tue Feb  9 20:59:11 2010	(r21730)
+++ branches/0.5/Changelog	Tue Feb  9 21:28:42 2010	(r21731)
@@ -12,7 +12,7 @@ version 0.5.1:
 - (L)GPL license upgrade support
 - AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries
 - enable symbol versioning by default for linkers that support it
-
+- backport av_lockmgr_register(), see doc/APIchanges for details
 
 
 version 0.5:

Modified: branches/0.5/doc/APIchanges
==============================================================================
--- branches/0.5/doc/APIchanges	Tue Feb  9 20:59:11 2010	(r21730)
+++ branches/0.5/doc/APIchanges	Tue Feb  9 21:28:42 2010	(r21731)
@@ -1,3 +1,11 @@
+20090601 - r19025 - lavc 52.30.0 - av_lockmgr_register()
+  av_lockmgr_register() can be used to register a callback function
+  that lavc (and in the future, libraries that depend on lavc) can use
+  to implement mutexes. The application should provide a callback function
+  the implements the AV_LOCK_* operations described in avcodec.h.
+  When the lock manager is registered FFmpeg is guaranteed to behave
+  correct also in a multi-threaded application.
+
 20090301 - r17682 - lavf 52.31.0 - Generic metadata API
   This version introduce a new metadata API (see av_metadata_get() and friends).
   The old API is now deprecated and shouldn't be used anymore. This especially

Modified: branches/0.5/libavcodec/avcodec.h
==============================================================================
--- branches/0.5/libavcodec/avcodec.h	Tue Feb  9 20:59:11 2010	(r21730)
+++ branches/0.5/libavcodec/avcodec.h	Tue Feb  9 21:28:42 2010	(r21731)
@@ -30,7 +30,7 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 52
-#define LIBAVCODEC_VERSION_MINOR 20
+#define LIBAVCODEC_VERSION_MINOR 21
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
@@ -3344,4 +3344,30 @@ void av_register_hwaccel(AVHWAccel *hwac
  */
 AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel);
 
+
+/**
+ * Lock operation used by lockmgr
+ */
+enum AVLockOp {
+  AV_LOCK_CREATE,  ///< Create a mutex
+  AV_LOCK_OBTAIN,  ///< Lock the mutex
+  AV_LOCK_RELEASE, ///< Unlock the mutex
+  AV_LOCK_DESTROY, ///< Free mutex resources
+};
+
+/**
+ * Register a user provided lock manager supporting the operations
+ * specified by AVLockOp. \p 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.
+ *
+ * @param cb User defined callback. Note: FFmpeg 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.
+ */
+int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
+
 #endif /* AVCODEC_AVCODEC_H */

Modified: branches/0.5/libavcodec/utils.c
==============================================================================
--- branches/0.5/libavcodec/utils.c	Tue Feb  9 20:59:11 2010	(r21730)
+++ branches/0.5/libavcodec/utils.c	Tue Feb  9 21:28:42 2010	(r21731)
@@ -65,6 +65,8 @@ const uint8_t ff_reverse[256]={
 };
 
 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)
 {
@@ -420,6 +422,12 @@ int attribute_align_arg avcodec_open(AVC
 {
     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");
@@ -464,6 +472,11 @@ int attribute_align_arg avcodec_open(AVC
     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;
 }
 
@@ -583,6 +596,12 @@ int avcodec_decode_subtitle(AVCodecConte
 
 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");
@@ -598,6 +617,11 @@ int avcodec_close(AVCodecContext *avctx)
     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;
 }
 
@@ -1152,3 +1176,19 @@ AVHWAccel *ff_find_hwaccel(enum CodecID 
     }
     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;
+}



More information about the ffmpeg-cvslog mailing list