From 7599c1a591d10137bfe384d73651b576793e2403 Mon Sep 17 00:00:00 2001 From: Luca Ognibene Date: Tue, 27 Sep 2005 15:51:59 +0000 Subject: ext/ffmpeg/: Move from dispose to finalize. Original commit message from CVS: * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_class_init), (gst_ffmpegdec_init), (gst_ffmpegdec_finalize), (gst_ffmpegdec_connect), (gst_ffmpegdec_chain): * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_class_init), (gst_ffmpegenc_init), (gst_ffmpegenc_finalize), (gst_ffmpegenc_link), (gst_ffmpegenc_chain_video), (gst_ffmpegenc_chain_audio): Move from dispose to finalize. Add a lock around _chain and _link functions. This prevent a segfault that can happens if the _link function is called while the _chain function is running. --- ChangeLog | 14 ++++++++++++++ common | 2 +- ext/ffmpeg/gstffmpegdec.c | 25 ++++++++++++++++++++----- ext/ffmpeg/gstffmpegenc.c | 43 +++++++++++++++++++++++++++++++++++++------ 4 files changed, 72 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ff2d24..3d28eb8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-09-27 Luca Ognibene + + * ext/ffmpeg/gstffmpegdec.c: (gst_ffmpegdec_class_init), + (gst_ffmpegdec_init), (gst_ffmpegdec_finalize), + (gst_ffmpegdec_connect), (gst_ffmpegdec_chain): + * ext/ffmpeg/gstffmpegenc.c: (gst_ffmpegenc_class_init), + (gst_ffmpegenc_init), (gst_ffmpegenc_finalize), + (gst_ffmpegenc_link), (gst_ffmpegenc_chain_video), + (gst_ffmpegenc_chain_audio): + Move from dispose to finalize. + Add a lock around _chain and _link functions. This prevent + a segfault that can happens if the _link function is called while + the _chain function is running. + 2005-09-05 Zaheer Abbas Merali * gst-libs/ext/Makefile.am: diff --git a/common b/common index 5488690..7caeee4 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 54886902497be267fe1f1a3f9c4dc0245bc46175 +Subproject commit 7caeee4b949b4388927fec7fcf25f767429bde30 diff --git a/ext/ffmpeg/gstffmpegdec.c b/ext/ffmpeg/gstffmpegdec.c index cb12b55..eba3958 100644 --- a/ext/ffmpeg/gstffmpegdec.c +++ b/ext/ffmpeg/gstffmpegdec.c @@ -72,6 +72,7 @@ struct _GstFFMpegDec GValue *par; /* pixel aspect ratio of incoming data */ gint hurry_up, lowres; + GMutex *mainlock; }; typedef struct _GstFFMpegDecClass GstFFMpegDecClass; @@ -116,7 +117,7 @@ static GHashTable *global_plugins; static void gst_ffmpegdec_base_init (GstFFMpegDecClass * klass); static void gst_ffmpegdec_class_init (GstFFMpegDecClass * klass); static void gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec); -static void gst_ffmpegdec_dispose (GObject * object); +static void gst_ffmpegdec_finalize (GObject * object); static gboolean gst_ffmpegdec_query (GstPad * pad, GstQueryType type, GstFormat * fmt, gint64 * value); @@ -246,7 +247,7 @@ gst_ffmpegdec_class_init (GstFFMpegDecClass * klass) "At which resolution to decode images", GST_FFMPEGDEC_TYPE_LOWRES, 0, G_PARAM_READWRITE)); - gobject_class->dispose = gst_ffmpegdec_dispose; + gobject_class->finalize = gst_ffmpegdec_finalize; gobject_class->set_property = gst_ffmpegdec_set_property; gobject_class->get_property = gst_ffmpegdec_get_property; gstelement_class->change_state = gst_ffmpegdec_change_state; @@ -283,22 +284,25 @@ gst_ffmpegdec_init (GstFFMpegDec * ffmpegdec) ffmpegdec->hurry_up = ffmpegdec->lowres = 0; ffmpegdec->last_buffer = NULL; + ffmpegdec->mainlock = g_mutex_new (); GST_FLAG_SET (ffmpegdec, GST_ELEMENT_EVENT_AWARE); } static void -gst_ffmpegdec_dispose (GObject * object) +gst_ffmpegdec_finalize (GObject * object) { GstFFMpegDec *ffmpegdec = (GstFFMpegDec *) object; - G_OBJECT_CLASS (parent_class)->dispose (object); - /* old session should have been closed in element_class->dispose */ + G_OBJECT_CLASS (parent_class)->finalize (object); + /* old session should have been closed in element_class->finalize */ g_assert (!ffmpegdec->opened); /* clean up remaining allocated data */ av_free (ffmpegdec->context); av_free (ffmpegdec->picture); + + g_mutex_free (ffmpegdec->mainlock); } static gboolean @@ -440,6 +444,8 @@ gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps) GstStructure *structure; const GValue *par; + g_mutex_lock (ffmpegdec->mainlock); + /* close old session */ gst_ffmpegdec_close (ffmpegdec); @@ -486,9 +492,12 @@ gst_ffmpegdec_connect (GstPad * pad, const GstCaps * caps) g_free (ffmpegdec->par); ffmpegdec->par = NULL; } + + g_mutex_unlock (ffmpegdec->mainlock); return GST_PAD_LINK_REFUSED; } + g_mutex_unlock (ffmpegdec->mainlock); return GST_PAD_LINK_OK; } @@ -932,9 +941,12 @@ gst_ffmpegdec_chain (GstPad * pad, GstData * _data) gint bsize, size, len, have_data; guint64 in_ts; + g_mutex_lock (ffmpegdec->mainlock); + /* event handling */ if (GST_IS_EVENT (_data)) { gst_ffmpegdec_handle_event (ffmpegdec, GST_EVENT (_data)); + g_mutex_unlock (ffmpegdec->mainlock); return; } @@ -945,6 +957,7 @@ gst_ffmpegdec_chain (GstPad * pad, GstData * _data) GST_ELEMENT_ERROR (ffmpegdec, CORE, NEGOTIATION, (NULL), ("ffdec_%s: input format was not set before data start", oclass->in_plugin->name)); + g_mutex_unlock (ffmpegdec->mainlock); return; } @@ -1023,6 +1036,8 @@ gst_ffmpegdec_chain (GstPad * pad, GstData * _data) } else if (bsize > 0) { GST_DEBUG_OBJECT (ffmpegdec, "Dropping %d bytes of data", bsize); } + + g_mutex_unlock (ffmpegdec->mainlock); gst_buffer_unref (inbuf); } diff --git a/ext/ffmpeg/gstffmpegenc.c b/ext/ffmpeg/gstffmpegenc.c index 5694411..ad51b32 100644 --- a/ext/ffmpeg/gstffmpegenc.c +++ b/ext/ffmpeg/gstffmpegenc.c @@ -55,6 +55,8 @@ struct _GstFFMpegEnc gint me_method; gint gop_size; gulong buffer_size; + + GMutex *mainlock; }; typedef struct _GstFFMpegEncClass GstFFMpegEncClass; @@ -130,7 +132,7 @@ static GHashTable *enc_global_plugins; static void gst_ffmpegenc_class_init (GstFFMpegEncClass * klass); static void gst_ffmpegenc_base_init (GstFFMpegEncClass * klass); static void gst_ffmpegenc_init (GstFFMpegEnc * ffmpegenc); -static void gst_ffmpegenc_dispose (GObject * object); +static void gst_ffmpegenc_finalize (GObject * object); static GstPadLinkReturn gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps); @@ -232,7 +234,7 @@ gst_ffmpegenc_class_init (GstFFMpegEncClass * klass) gstelement_class->change_state = gst_ffmpegenc_change_state; - gobject_class->dispose = gst_ffmpegenc_dispose; + gobject_class->finalize = gst_ffmpegenc_finalize; } static void @@ -267,10 +269,12 @@ gst_ffmpegenc_init (GstFFMpegEnc * ffmpegenc) gst_element_add_pad (GST_ELEMENT (ffmpegenc), ffmpegenc->sinkpad); gst_element_add_pad (GST_ELEMENT (ffmpegenc), ffmpegenc->srcpad); + + ffmpegenc->mainlock = g_mutex_new (); } static void -gst_ffmpegenc_dispose (GObject * object) +gst_ffmpegenc_finalize (GObject * object) { GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) object; @@ -283,8 +287,10 @@ gst_ffmpegenc_dispose (GObject * object) /* clean up remaining allocated data */ av_free (ffmpegenc->context); av_free (ffmpegenc->picture); + + g_mutex_free (ffmpegenc->mainlock); - G_OBJECT_CLASS (parent_class)->dispose (object); + G_OBJECT_CLASS (parent_class)->finalize (object); } static GstCaps * @@ -358,7 +364,9 @@ gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps) GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) gst_pad_get_parent (pad); GstFFMpegEncClass *oclass = (GstFFMpegEncClass *) G_OBJECT_GET_CLASS (ffmpegenc); - + + g_mutex_lock (ffmpegenc->mainlock); + /* close old session */ if (ffmpegenc->opened) { avcodec_close (ffmpegenc->context); @@ -399,6 +407,7 @@ gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps) avcodec_close (ffmpegenc->context); GST_DEBUG ("ffenc_%s: Failed to open FFMPEG codec", oclass->in_plugin->name); + g_mutex_unlock (ffmpegenc->mainlock); return GST_PAD_LINK_REFUSED; } @@ -407,6 +416,7 @@ gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps) 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); + g_mutex_unlock (ffmpegenc->mainlock); return GST_PAD_LINK_REFUSED; } @@ -422,6 +432,7 @@ gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps) if (!other_caps) { avcodec_close (ffmpegenc->context); GST_DEBUG ("Unsupported codec - no caps found"); + g_mutex_unlock (ffmpegenc->mainlock); return GST_PAD_LINK_REFUSED; } @@ -430,6 +441,7 @@ gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps) gst_caps_free (other_caps); if (gst_caps_is_empty (icaps)) { gst_caps_free (icaps); + g_mutex_unlock (ffmpegenc->mainlock); return GST_PAD_LINK_REFUSED; } @@ -448,6 +460,7 @@ gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps) if (!gst_pad_set_explicit_caps (ffmpegenc->srcpad, icaps)) { avcodec_close (ffmpegenc->context); gst_caps_free (icaps); + g_mutex_unlock (ffmpegenc->mainlock); return GST_PAD_LINK_REFUSED; } gst_caps_free (icaps); @@ -455,6 +468,8 @@ gst_ffmpegenc_link (GstPad * pad, const GstCaps * caps) /* success! */ ffmpegenc->opened = TRUE; + g_mutex_unlock (ffmpegenc->mainlock); + return GST_PAD_LINK_OK; } @@ -468,6 +483,8 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstData * _data) gint ret_size = 0, frame_size; const AVRational bq = { 1, 1000000000 }; + g_mutex_lock (ffmpegenc->mainlock); + /* FIXME: events (discont (flush!) and eos (close down) etc.) */ GST_DEBUG_OBJECT (ffmpegenc, @@ -478,7 +495,12 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstData * _data) GST_BUFFER_DATA (inbuf), ffmpegenc->context->pix_fmt, ffmpegenc->context->width, ffmpegenc->context->height); - g_return_if_fail (frame_size == GST_BUFFER_SIZE (inbuf)); + if (frame_size != GST_BUFFER_SIZE (inbuf)) { + gst_buffer_unref (inbuf); + g_warning ("frame_size != GST_BUFFER_SIZE (inbuf)"); + g_mutex_unlock (ffmpegenc->mainlock); + return ; + } ffmpegenc->picture->pts = gst_ffmpeg_time_gst_to_ff (GST_BUFFER_TIMESTAMP (inbuf), @@ -494,6 +516,7 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstData * _data) "ffenc_%s: failed to encode buffer", oclass->in_plugin->name); gst_buffer_unref (inbuf); gst_buffer_unref (outbuf); + g_mutex_unlock (ffmpegenc->mainlock); return; } @@ -507,6 +530,8 @@ gst_ffmpegenc_chain_video (GstPad * pad, GstData * _data) gst_pad_push (ffmpegenc->srcpad, GST_DATA (outbuf)); gst_buffer_unref (inbuf); + + g_mutex_unlock (ffmpegenc->mainlock); } static void @@ -517,6 +542,8 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstData * _data) GstFFMpegEnc *ffmpegenc = (GstFFMpegEnc *) (gst_pad_get_parent (pad)); gint size, ret_size = 0, in_size, frame_size; + g_mutex_lock (ffmpegenc->mainlock); + size = GST_BUFFER_SIZE (inbuf); /* FIXME: events (discont (flush!) and eos (close down) etc.) */ @@ -556,6 +583,7 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstData * _data) gst_buffer_unref (inbuf); } + g_mutex_unlock (ffmpegenc->mainlock); return; } @@ -587,6 +615,7 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstData * _data) gst_buffer_unref (inbuf); gst_buffer_unref (outbuf); gst_buffer_unref (subbuf); + g_mutex_unlock (ffmpegenc->mainlock); return; } @@ -597,6 +626,8 @@ gst_ffmpegenc_chain_audio (GstPad * pad, GstData * _data) in_size -= frame_size; gst_buffer_unref (subbuf); + + g_mutex_unlock (ffmpegenc->mainlock); } } -- cgit v1.2.1