[farsight2/master] Split updating of special sources into two part to prevents races
Olivier Crête
olivier.crete at collabora.co.uk
Tue Dec 23 15:23:13 PST 2008
---
gst/fsrtpconference/fs-rtp-session.c | 63 ++++++++++++----
gst/fsrtpconference/fs-rtp-special-source.c | 107 +++++++++++++++++---------
gst/fsrtpconference/fs-rtp-special-source.h | 11 +++-
3 files changed, 128 insertions(+), 53 deletions(-)
diff --git a/gst/fsrtpconference/fs-rtp-session.c b/gst/fsrtpconference/fs-rtp-session.c
index 2ff17fe..b01a1f0 100644
--- a/gst/fsrtpconference/fs-rtp-session.c
+++ b/gst/fsrtpconference/fs-rtp-session.c
@@ -2801,6 +2801,24 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
self->priv->current_send_codec = NULL;
+ self->priv->extra_sources = fs_rtp_special_sources_remove (
+ self->priv->extra_sources,
+ self->priv->codec_associations, codec,
+ GST_ELEMENT (self->priv->conference),
+ self->priv->rtpmuxer, &error);
+ if (error)
+ {
+ fs_session_emit_error (FS_SESSION (self), error->code,
+ "Could not remove unused special sources: %s", error->message);
+ goto done;
+ }
+
+ /*
+ * Lets reset the clock-rate (because rtpmuxer saves it.. )
+ */
+ g_object_set (self->priv->rtpmuxer, "clock-rate", 0, NULL);
+
+
codecbin = fs_rtp_session_add_send_codec_bin (self, codec, bp,
&error);
@@ -2810,6 +2828,20 @@ _send_src_pad_blocked_callback (GstPad *pad, gboolean blocked,
"Could not build a new send codec bin", error->message);
}
+
+ self->priv->extra_sources = fs_rtp_special_sources_create (
+ self->priv->extra_sources,
+ self->priv->codec_associations, codec,
+ GST_ELEMENT (self->priv->conference),
+ self->priv->rtpmuxer, &error);
+ if (error)
+ {
+ fs_session_emit_error (FS_SESSION (self), error->code,
+ "Could not create special sources: %s", error->message);
+ goto done;
+ }
+
+
done:
g_clear_error (&error);
@@ -2848,19 +2880,10 @@ fs_rtp_session_verify_send_codec_bin_locked (FsRtpSession *self, GError **error)
if (!codec)
return FALSE;
- self->priv->extra_sources = fs_rtp_special_sources_update (
- self->priv->extra_sources,
- self->priv->codec_associations, codec,
- GST_ELEMENT (self->priv->conference),
- self->priv->rtpmuxer, error);
- if (local_gerror)
- {
- g_propagate_error (error, local_gerror);
- goto error;
- }
-
if (self->priv->current_send_codec)
{
+ GstPad *pad;
+
if (fs_codec_are_equal (codec, self->priv->current_send_codec))
goto done;
@@ -2878,11 +2901,21 @@ fs_rtp_session_verify_send_codec_bin_locked (FsRtpSession *self, GError **error)
{
/* The codec does exist yet, lets just create it */
- codecbin = fs_rtp_session_add_send_codec_bin (self, codec, bp, error);
-
- if (!codecbin)
- /* We have an error !! */
+ codecbin = fs_rtp_session_add_send_codec_bin (self, codec, bp, error);
+ if (!codecbin)
+ /* We have an error !! */
+ goto error;
+
+ self->priv->extra_sources = fs_rtp_special_sources_create (
+ self->priv->extra_sources,
+ self->priv->codec_associations, codec,
+ GST_ELEMENT (self->priv->conference),
+ self->priv->rtpmuxer, &local_gerror);
+ if (local_gerror)
+ {
+ g_propagate_error (error, local_gerror);
goto error;
+ }
}
done:
diff --git a/gst/fsrtpconference/fs-rtp-special-source.c b/gst/fsrtpconference/fs-rtp-special-source.c
index 2ab7900..ed4a025 100644
--- a/gst/fsrtpconference/fs-rtp-special-source.c
+++ b/gst/fsrtpconference/fs-rtp-special-source.c
@@ -382,20 +382,21 @@ _source_order_compare_func (gconstpointer item1,gconstpointer item2)
}
/**
- * fs_rtp_special_sources_update:
+ * fs_rtp_special_sources_remove:
* @current_extra_sources: The #GList returned by previous calls to this function
* @negotiated_codecs: A #GList of current negotiated #CodecAssociation
+ * @send_codec: The currently selected send codec
+ * @bin: The #GstBin to add the stuff to
+ * @rtpmuxer: The rtpmux element
* @error: NULL or the local of a #GError
*
- * This function checks which extra sources are currently being used and
- * which should be used according to currently negotiated codecs. It then
- * creates, destroys or modifies the list accordingly
+ * This function removes any special source that are not compatible with the
+ * currently selected send codec.
*
* Returns: A #GList to be passed to other functions in this class
*/
-
GList *
-fs_rtp_special_sources_update (
+fs_rtp_special_sources_remove (
GList *current_extra_sources,
GList *negotiated_codecs,
FsCodec *send_codec,
@@ -427,50 +428,82 @@ fs_rtp_special_sources_update (
if (obj_item)
{
- if (fs_rtp_special_source_class_want_source (klass, negotiated_codecs,
- send_codec))
- {
- if (!fs_rtp_special_source_update (obj, negotiated_codecs, send_codec))
- {
-
- current_extra_sources = g_list_remove (current_extra_sources, obj);
- g_object_unref (obj);
- obj = fs_rtp_special_source_new (klass, negotiated_codecs, send_codec,
- bin, rtpmuxer, error);
- if (!obj)
- goto error;
-
- current_extra_sources = g_list_insert_sorted (current_extra_sources,
- obj, _source_order_compare_func);
- }
- }
- else
+ if (!fs_rtp_special_source_class_want_source (klass, negotiated_codecs,
+ send_codec) ||
+ fs_rtp_special_source_update (obj, negotiated_codecs, send_codec))
{
current_extra_sources = g_list_remove (current_extra_sources, obj);
g_object_unref (obj);
}
}
- else
+ }
+
+ return current_extra_sources;
+}
+
+
+/**
+ * fs_rtp_special_sources_remove:
+ * @current_extra_sources: The #GList returned by previous calls to this function
+ * @negotiated_codecs: A #GList of current negotiated #CodecAssociation
+ * @send_codec: The currently selected send codec
+ * @bin: The #GstBin to add the stuff to
+ * @rtpmuxer: The rtpmux element
+ * @error: NULL or the local of a #GError
+ *
+ * This function add special sources that don't already exist but are needed
+ *
+ * Returns: A #GList to be passed to other functions in this class
+ */
+GList *
+fs_rtp_special_sources_create (
+ GList *current_extra_sources,
+ GList *negotiated_codecs,
+ FsCodec *send_codec,
+ GstElement *bin,
+ GstElement *rtpmuxer,
+ GError **error)
+{
+ GList *klass_item = NULL;
+
+ fs_rtp_special_sources_init ();
+
+ for (klass_item = g_list_first (classes);
+ klass_item;
+ klass_item = g_list_next (klass_item))
+ {
+ FsRtpSpecialSourceClass *klass = klass_item->data;
+ GList *obj_item;
+ FsRtpSpecialSource *obj = NULL;
+
+ /* Check if we already have an object for this type */
+ for (obj_item = g_list_first (current_extra_sources);
+ obj_item;
+ obj_item = g_list_next (obj_item))
{
- if (fs_rtp_special_source_class_want_source (klass, negotiated_codecs,
- send_codec))
- {
- obj = fs_rtp_special_source_new (klass, negotiated_codecs, send_codec,
- bin, rtpmuxer, error);
- if (!obj)
- goto error;
- current_extra_sources = g_list_insert_sorted (current_extra_sources,
- obj, _source_order_compare_func);
- }
+ obj = obj_item->data;
+ if (G_OBJECT_TYPE(obj) == G_OBJECT_CLASS_TYPE(klass))
+ break;
+ }
+
+ if (!obj_item &&
+ fs_rtp_special_source_class_want_source (klass, negotiated_codecs,
+ send_codec))
+ {
+ obj = fs_rtp_special_source_new (klass, negotiated_codecs, send_codec,
+ bin, rtpmuxer, error);
+ if (!obj)
+ goto error;
+ current_extra_sources = g_list_insert_sorted (current_extra_sources,
+ obj, _source_order_compare_func);
}
}
- error:
+ error:
return current_extra_sources;
}
-
static FsRtpSpecialSource *
fs_rtp_special_source_new (FsRtpSpecialSourceClass *klass,
GList *negotiated_codecs,
diff --git a/gst/fsrtpconference/fs-rtp-special-source.h b/gst/fsrtpconference/fs-rtp-special-source.h
index 8ca640c..b35a297 100644
--- a/gst/fsrtpconference/fs-rtp-special-source.h
+++ b/gst/fsrtpconference/fs-rtp-special-source.h
@@ -117,7 +117,16 @@ struct _FsRtpSpecialSource
GType fs_rtp_special_source_get_type (void);
GList *
-fs_rtp_special_sources_update (
+fs_rtp_special_sources_remove (
+ GList *current_extra_sources,
+ GList *negotiated_codecs,
+ FsCodec *send_codec,
+ GstElement *bin,
+ GstElement *rtpmuxer,
+ GError **error);
+
+GList *
+fs_rtp_special_sources_create (
GList *current_extra_sources,
GList *negotiated_codecs,
FsCodec *send_codec,
--
1.5.6.5
More information about the farsight-commits
mailing list