[farsight2/master] Add function to shutdown the FsRtpDtmfEventSource
Olivier Crête
olivier.crete at collabora.co.uk
Tue Dec 23 15:21:33 PST 2008
---
gst/fsrtpconference/fs-rtp-dtmf-event-source.c | 106 ++++++++++++++++++++----
1 files changed, 89 insertions(+), 17 deletions(-)
diff --git a/gst/fsrtpconference/fs-rtp-dtmf-event-source.c b/gst/fsrtpconference/fs-rtp-dtmf-event-source.c
index 205a0be..522138d 100644
--- a/gst/fsrtpconference/fs-rtp-dtmf-event-source.c
+++ b/gst/fsrtpconference/fs-rtp-dtmf-event-source.c
@@ -53,6 +53,7 @@ enum
PROP_RTPMUXER
};
+/* all privates variables are protected by the mutex */
struct _FsRtpDtmfEventSourcePrivate {
gboolean disposed;
@@ -60,8 +61,10 @@ struct _FsRtpDtmfEventSourcePrivate {
GstElement *rtpmuxer;
GstElement *bin;
- GstElement *dtmfsrc;
- GstElement *capsfilter;
+
+ GThread *stop_thread;
+
+ GMutex *mutex;
};
static FsRtpSpecialSourceClass *parent_class = NULL;
@@ -77,6 +80,7 @@ static void fs_rtp_dtmf_event_source_set_property (GObject *object, guint prop_i
const GValue *value, GParamSpec *pspec);
static void fs_rtp_dtmf_event_source_dispose (GObject *object);
+static void fs_rtp_dtmf_event_source_finalize (GObject *object);
static FsRtpSpecialSource *fs_rtp_dtmf_event_source_new (
FsRtpSpecialSourceClass *klass,
@@ -93,6 +97,10 @@ static GList *fs_rtp_dtmf_event_source_class_add_blueprint (
FsRtpSpecialSourceClass *klass,
GList *blueprints);
+
+#define FS_RTP_DTMF_EVENT_SOURCE_LOCK(src) g_mutex_lock (src->priv->mutex)
+#define FS_RTP_DTMF_EVENT_SOURCE_UNLOCK(src) g_mutex_unlock (src->priv->mutex)
+
static void
fs_rtp_dtmf_event_source_class_init (FsRtpDtmfEventSourceClass *klass)
{
@@ -101,6 +109,7 @@ fs_rtp_dtmf_event_source_class_init (FsRtpDtmfEventSourceClass *klass)
parent_class = fs_rtp_dtmf_event_source_parent_class;
gobject_class->dispose = fs_rtp_dtmf_event_source_dispose;
+ gobject_class->finalize = fs_rtp_dtmf_event_source_finalize;
gobject_class->set_property = fs_rtp_dtmf_event_source_set_property;
spsource_class->new = fs_rtp_dtmf_event_source_new;
@@ -129,6 +138,26 @@ fs_rtp_dtmf_event_source_init (FsRtpDtmfEventSource *self)
{
self->priv = FS_RTP_DTMF_EVENT_SOURCE_GET_PRIVATE (self);
self->priv->disposed = FALSE;
+
+ self->priv->mutex = g_mutex_new ();
+}
+
+static gpointer
+stop_source_thread (gpointer data)
+{
+ FsRtpDtmfEventSource *self = FS_RTP_DTMF_EVENT_SOURCE (data);
+
+ gst_element_set_locked_state (self->priv->bin, TRUE);
+ gst_element_set_state (self->priv->bin, GST_STATE_NULL);
+
+ FS_RTP_DTMF_EVENT_SOURCE_LOCK (self);
+ gst_bin_remove (GST_BIN (self->priv->outer_bin), self->priv->bin);
+ self->priv->bin = NULL;
+ FS_RTP_DTMF_EVENT_SOURCE_UNLOCK (self);
+
+ g_object_unref (self);
+
+ return NULL;
}
static void
@@ -136,8 +165,38 @@ fs_rtp_dtmf_event_source_dispose (GObject *object)
{
FsRtpDtmfEventSource *self = FS_RTP_DTMF_EVENT_SOURCE (object);
+ FS_RTP_DTMF_EVENT_SOURCE_LOCK (self);
+
if (self->priv->disposed)
+ {
+ FS_RTP_DTMF_EVENT_SOURCE_UNLOCK (self);
+ return;
+ }
+
+ if (self->priv->bin)
+ {
+ GError *error = NULL;
+
+ if (self->priv->stop_thread)
+ {
+ GST_DEBUG ("stopping thread for rtpdtmfsrc already running");
+ return;
+ }
+
+ g_object_ref (self);
+ self->priv->stop_thread = g_thread_create (stop_source_thread, self, FALSE,
+ &error);
+
+ if (!self->priv->stop_thread)
+ {
+ GST_WARNING ("Could not start stopping thread for FsRtpDtmfEventSource:"
+ " %s", error->message);
+ }
+ g_clear_error (&error);
+
+ FS_RTP_DTMF_EVENT_SOURCE_UNLOCK (self);
return;
+ }
if (self->priv->rtpmuxer)
{
@@ -152,10 +211,25 @@ fs_rtp_dtmf_event_source_dispose (GObject *object)
}
self->priv->disposed = TRUE;
+
+ FS_RTP_DTMF_EVENT_SOURCE_UNLOCK (self);
+
G_OBJECT_CLASS (fs_rtp_dtmf_event_source_parent_class)->dispose (object);
}
static void
+fs_rtp_dtmf_event_source_finalize (GObject *object)
+{
+ FsRtpDtmfEventSource *self = FS_RTP_DTMF_EVENT_SOURCE (object);
+
+ if (self->priv->mutex)
+ g_mutex_free (self->priv->mutex);
+ self->priv->mutex = NULL;
+
+ G_OBJECT_CLASS (fs_rtp_dtmf_event_source_parent_class)->finalize (object);
+}
+
+static void
fs_rtp_dtmf_event_source_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
@@ -304,6 +378,8 @@ fs_rtp_dtmf_event_source_build (FsRtpDtmfEventSource *self,
FsCodec *telephony_codec = NULL;
GstCaps *caps = NULL;
GstPad *pad = NULL;
+ GstElement *dtmfsrc = NULL;
+ GstElement *capsfilter = NULL;
telephony_codec = get_telephone_event_codec (negotiated_codecs,
selected_codec->clock_rate);
@@ -329,7 +405,7 @@ fs_rtp_dtmf_event_source_build (FsRtpDtmfEventSource *self,
return FALSE;
}
- self->priv->bin = gst_bin_new ();
+ self->priv->bin = gst_bin_new (NULL);
if (!gst_bin_add (GST_BIN (self->priv->outer_bin), self->priv->bin))
{
g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
@@ -339,43 +415,41 @@ fs_rtp_dtmf_event_source_build (FsRtpDtmfEventSource *self,
return FALSE;
}
- self->priv->dtmfsrc = gst_element_factory_make ("rtpdtmfsrc", NULL);
- if (!self->priv->dtmfsrc)
+ dtmfsrc = gst_element_factory_make ("rtpdtmfsrc", NULL);
+ if (!dtmfsrc)
{
g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
"Could not make rtpdtmfsrc");
goto error;
}
- if (!gst_bin_add (GST_BIN (self->priv->bin), self->priv->dtmfsrc))
+ if (!gst_bin_add (GST_BIN (self->priv->bin), dtmfsrc))
{
g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
"Could not add rtpdtmfsrc to bin");
- gst_object_unref (self->priv->dtmfsrc);
- self->priv->dtmfsrc = NULL;
+ gst_object_unref (dtmfsrc);
goto error;
}
- self->priv->capsfilter = gst_element_factory_make ("capsfilter", NULL);
- if (!self->priv->capsfilter)
+ capsfilter = gst_element_factory_make ("capsfilter", NULL);
+ if (!capsfilter)
{
g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
"Could not make rtpcapsfilter");
goto error;
}
- if (!gst_bin_add (GST_BIN (self->priv->bin), self->priv->capsfilter))
+ if (!gst_bin_add (GST_BIN (self->priv->bin), capsfilter))
{
g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
"Could not add capsfilter to bin");
- gst_object_unref (self->priv->capsfilter);
- self->priv->capsfilter = NULL;
+ gst_object_unref (capsfilter);
goto error;
}
caps = fs_codec_to_gst_caps (telephony_codec);
- g_object_set (self->priv->capsfilter, "caps", caps, NULL);
+ g_object_set (capsfilter, "caps", caps, NULL);
gst_object_unref (caps);
- pad = gst_element_get_static_pad (self->priv->capsfilter, "src");
+ pad = gst_element_get_static_pad (capsfilter, "src");
if (!pad)
{
g_set_error (error, FS_ERROR, FS_ERROR_CONSTRUCTION,
@@ -408,8 +482,6 @@ fs_rtp_dtmf_event_source_build (FsRtpDtmfEventSource *self,
return TRUE;
error:
- self->priv->capsfilter = NULL;
- self->priv->dtmfsrc = NULL;
gst_bin_remove (GST_BIN (self->priv->outer_bin), self->priv->bin);
self->priv->bin = NULL;
--
1.5.6.5
More information about the farsight-commits
mailing list