diff options
author | Andreas Öman <andreas@lonelycoder.com> | 2009-05-31 06:51:18 +0000 |
---|---|---|
committer | Andreas Öman <andreas@lonelycoder.com> | 2009-05-31 06:51:18 +0000 |
commit | f988ce6cad8a98af1eaf260fb6995deac65542e5 (patch) | |
tree | f4785848576e8e2071a3a575217fcb4d5d3f7513 /libavcodec/utils.c | |
parent | b8df8d0d1c6b9b5f284319de4965276f6087e7cf (diff) | |
download | ffmpeg-f988ce6cad8a98af1eaf260fb6995deac65542e5.tar.gz |
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.
Originally committed as revision 19025 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r-- | libavcodec/utils.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 75da609eef..1236fcf764 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -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) { @@ -439,6 +441,12 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) { 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 @@ int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) 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_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, 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 @@ 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; } @@ -1213,3 +1237,19 @@ AVHWAccel *ff_find_hwaccel(enum CodecID codec_id, enum PixelFormat pix_fmt) } 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; +} |