diff --git a/ChangeLog b/ChangeLog index ea3e449e1b..43ecb19e8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-12-16 Tim-Philipp Müller + + * ext/ffmpeg/gstffmpeg.c: (gst_ffmpeg_avcodec_open), + (gst_ffmpeg_avcodec_close): + * ext/ffmpeg/gstffmpeg.h: + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_close), + (gst_ffmpegdec_open): + * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_dispose), + (gst_ffmpegenc_getcaps), (gst_ffmpegenc_setcaps), + (gst_ffmpegenc_change_state): + Do proper locking around avcodec_open() and avcodec_close() + (fixes #322254, patch by: Sebastien Cote and Luca Ognibene). + 2005-12-10 Tim-Philipp Müller * gst-libs/ext/Makefile.am: diff --git a/ext/ffmpeg/gstffmpeg.c b/ext/ffmpeg/gstffmpeg.c index 61a03d7867..bb2ec7c31e 100644 --- a/ext/ffmpeg/gstffmpeg.c +++ b/ext/ffmpeg/gstffmpeg.c @@ -37,6 +37,31 @@ GST_DEBUG_CATEGORY (ffmpeg_debug); +static GStaticMutex gst_avcodec_mutex = G_STATIC_MUTEX_INIT; + + +int +gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec) { + int ret; + + g_static_mutex_lock (&gst_avcodec_mutex); + ret = avcodec_open (avctx, codec); + g_static_mutex_unlock (&gst_avcodec_mutex); + + return ret; +} + +int +gst_ffmpeg_avcodec_close (AVCodecContext *avctx) { + int ret; + + g_static_mutex_lock (&gst_avcodec_mutex); + ret = avcodec_close (avctx); + g_static_mutex_unlock (&gst_avcodec_mutex); + + return ret; +} + #ifndef GST_DISABLE_GST_DEBUG static void gst_ffmpeg_log_callback (void * ptr, int level, const char * fmt, va_list vl) diff --git a/ext/ffmpeg/gstffmpeg.h b/ext/ffmpeg/gstffmpeg.h index 99616ea57d..50ebc379cb 100644 --- a/ext/ffmpeg/gstffmpeg.h +++ b/ext/ffmpeg/gstffmpeg.h @@ -51,6 +51,9 @@ extern gboolean gst_ffmpegcsp_register (GstPlugin * plugin); extern gboolean gst_ffmpegscale_register (GstPlugin * plugin); extern gboolean gst_ffmpegdeinterlace_register (GstPlugin * plugin); +int gst_ffmpeg_avcodec_open (AVCodecContext *avctx, AVCodec *codec); +int gst_ffmpeg_avcodec_close (AVCodecContext *avctx); + G_END_DECLS extern URLProtocol gstreamer_protocol; diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c index 0ecb2f0981..30278651f5 100644 --- a/ext/ffmpeg/gstffmpegdec.c +++ b/ext/ffmpeg/gstffmpegdec.c @@ -384,7 +384,7 @@ gst_ffmpegdec_close (GstFFMpegDec * ffmpegdec) } if (ffmpegdec->context->priv_data) - avcodec_close (ffmpegdec->context); + gst_ffmpeg_avcodec_close (ffmpegdec->context); ffmpegdec->opened = FALSE; if (ffmpegdec->context->palctrl) { @@ -419,7 +419,7 @@ gst_ffmpegdec_open (GstFFMpegDec * ffmpegdec) GstFFMpegDecClass *oclass = (GstFFMpegDecClass *) (G_OBJECT_GET_CLASS (ffmpegdec)); - if (avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0) + if (gst_ffmpeg_avcodec_open (ffmpegdec->context, oclass->in_plugin) < 0) goto could_not_open; ffmpegdec->opened = TRUE; diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c index 0f70698a75..40f3972cdd 100644 --- a/ext/ffmpeg/gstffmpegenc.c +++ b/ext/ffmpeg/gstffmpegenc.c @@ -283,7 +283,7 @@ gst_ffmpegenc_dispose (GObject * object) /* close old session */ if (ffmpegenc->opened) { - avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context); ffmpegenc->opened = FALSE; } @@ -338,17 +338,17 @@ gst_ffmpegenc_getcaps (GstPad * pad) _shut_up_I_am_probing = TRUE; for (pixfmt = 0; pixfmt < PIX_FMT_NB; pixfmt++) { ctx->pix_fmt = pixfmt; - if (avcodec_open (ctx, oclass->in_plugin) >= 0 && + if (gst_ffmpeg_avcodec_open (ctx, oclass->in_plugin) >= 0 && ctx->pix_fmt == pixfmt) { ctx->width = -1; if (!caps) caps = gst_caps_new_empty (); gst_caps_append (caps, gst_ffmpeg_codectype_to_caps (oclass->in_plugin->type, ctx)); - avcodec_close (ctx); + gst_ffmpeg_avcodec_close (ctx); } if (ctx->priv_data) - avcodec_close (ctx); + gst_ffmpeg_avcodec_close (ctx); } av_free (ctx); _shut_up_I_am_probing = FALSE; @@ -376,7 +376,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) /* close old session */ if (ffmpegenc->opened) { - avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context); ffmpegenc->opened = FALSE; } @@ -417,9 +417,9 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) pix_fmt = ffmpegenc->context->pix_fmt; /* open codec */ - if (avcodec_open (ffmpegenc->context, oclass->in_plugin) < 0) { + if (gst_ffmpeg_avcodec_open (ffmpegenc->context, oclass->in_plugin) < 0) { if (ffmpegenc->context->priv_data) - avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context); GST_DEBUG ("ffenc_%s: Failed to open FFMPEG codec", oclass->in_plugin->name); return FALSE; @@ -427,7 +427,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) /* is the colourspace correct? */ if (pix_fmt != ffmpegenc->context->pix_fmt) { - avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context); GST_DEBUG ("ffenc_%s: AV wants different colourspace (%d given, %d wanted)", oclass->in_plugin->name, pix_fmt, ffmpegenc->context->pix_fmt); return FALSE; @@ -452,7 +452,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) ffmpegenc->context, TRUE); if (!other_caps) { - avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context); GST_DEBUG ("Unsupported codec - no caps found"); return FALSE; } @@ -476,7 +476,7 @@ gst_ffmpegenc_setcaps (GstPad * pad, GstCaps * caps) } if (!gst_pad_set_caps (ffmpegenc->srcpad, icaps)) { - avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context); gst_caps_unref (icaps); return FALSE; } @@ -711,7 +711,7 @@ gst_ffmpegenc_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_PAUSED_TO_READY: if (ffmpegenc->opened) { - avcodec_close (ffmpegenc->context); + gst_ffmpeg_avcodec_close (ffmpegenc->context); ffmpegenc->opened = FALSE; } if (ffmpegenc->cache) {