[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