[farsight2/master] Implement codec negotiation

Olivier Crête olivier.crete at collabora.co.uk
Tue Dec 23 15:19:53 PST 2008


---
 gst/fsrtpconference/fs-rtp-session.c |   99 ++++++++++++++++++++++++++++++++++
 1 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/gst/fsrtpconference/fs-rtp-session.c b/gst/fsrtpconference/fs-rtp-session.c
index 806c0d4..ebc54a2 100644
--- a/gst/fsrtpconference/fs-rtp-session.c
+++ b/gst/fsrtpconference/fs-rtp-session.c
@@ -1188,6 +1188,105 @@ fs_rtp_session_get_stream_by_ssrc_locked (FsRtpSession *self,
     return NULL;
 }
 
+static void
+fs_rtp_session_invalidate_pt (FsRtpSession *session, guint pt)
+{
+}
+
+static gboolean
+_compare_codec_lists (GList *list1, GList *list2)
+{
+  for (; list1 && list2;
+       list1 = g_list_next (list1),
+       list2 = g_list_next (list2)) {
+    if (!fs_codec_are_equal (list1->data, list2->data))
+      return FALSE;
+  }
+
+  if (list1 == NULL && list2 == NULL)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+gboolean
+fs_rtp_session_negotiate_codecs (FsRtpSession *session, GList *remote_codecs,
+  GError **error)
+{
+  gboolean has_many_streams;
+  GHashTable *new_negotiated_codec_associations = NULL;;
+  GList *new_negotiated_codecs = NULL;
+
+  FS_SESSION_LOCK (session);
+
+  has_many_streams =
+    (g_list_next (g_list_first (session->priv->streams)) != NULL);
+
+  new_negotiated_codec_associations = negotiate_codecs (remote_codecs,
+    session->priv->negotiated_codec_associations,
+    session->priv->local_codec_associations,
+    session->priv->local_codecs,
+    has_many_streams,
+    &new_negotiated_codecs);
+
+  if (new_negotiated_codec_associations) {
+    gboolean is_new = FALSE;
+    gboolean clear_pts = FALSE;
+    int pt;
+
+    is_new = _compare_codec_lists (session->priv->negotiated_codecs,
+      new_negotiated_codecs);
+
+    /* Lets remove the codec bin for any PT that has changed type */
+    for (pt = 0; pt < 128; pt++) {
+      FsCodec *old_codec = g_hash_table_lookup (
+          session->priv->negotiated_codec_associations, GINT_TO_POINTER (pt));
+      FsCodec *new_codec = g_hash_table_lookup (
+          new_negotiated_codec_associations, GINT_TO_POINTER (pt));
+
+      if (old_codec == NULL && new_codec == NULL)
+        continue;
+
+      if (old_codec == NULL || new_codec == NULL) {
+        fs_rtp_session_invalidate_pt (session, pt);
+        clear_pts = TRUE;
+        continue;
+      }
+
+      if (!fs_codec_are_equal (old_codec, new_codec)) {
+        fs_rtp_session_invalidate_pt (session, pt);
+        clear_pts = TRUE;
+        continue;
+      }
+    }
+
+    if (clear_pts)
+      g_signal_emit_by_name (session->priv->conference->gstrtpbin,
+        "clear-pt-map");
+
+    if (session->priv->negotiated_codec_associations)
+      g_hash_table_destroy (session->priv->negotiated_codec_associations);
+    if (session->priv->negotiated_codecs)
+      fs_codec_list_destroy (session->priv->negotiated_codecs);
+
+    session->priv->negotiated_codec_associations =
+      new_negotiated_codec_associations;
+    session->priv->negotiated_codecs = new_negotiated_codecs;
+    FS_SESSION_UNLOCK (session);
+
+    if (is_new)
+      g_signal_emit_by_name (session, "new-negotiated-codec");
+
+    return TRUE;
+  } else {
+    FS_SESSION_UNLOCK (session);
+
+    g_set_error (error, FS_ERROR, FS_ERROR_NEGOTIATION_FAILED,
+      "There was no intersection between the remote codecs and the local ones");
+    return FALSE;
+  }
+}
+
 
 /**
  * fs_rtp_session_new_recv_pad:
-- 
1.5.6.5




More information about the farsight-commits mailing list