[farsight2/master] Set the receive codec based on the configuration data

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


---
 gst/fsrtpconference/fs-rtp-session.c |  132 +++++++++++++++++++++++++++++----
 1 files changed, 116 insertions(+), 16 deletions(-)

diff --git a/gst/fsrtpconference/fs-rtp-session.c b/gst/fsrtpconference/fs-rtp-session.c
index 0b5e932..2362bbf 100644
--- a/gst/fsrtpconference/fs-rtp-session.c
+++ b/gst/fsrtpconference/fs-rtp-session.c
@@ -2199,6 +2199,105 @@ _create_codec_bin (CodecBlueprint *blueprint, const FsCodec *codec,
   return NULL;
 }
 
+/**
+ * fs_rtp_session_get_recv_codec_locked:
+ * @session: a #FsRtpSession
+ * @pt: The payload type to find the codec for
+ * @stream: an optional #FsRtpStream for which this data is received
+ * @bp: Then returned CodecBlueprint to create a codecbin
+ *
+ * This function returns the codec and blueprint that will be used to receive
+ * data on a specific payload type, optionally from a specific stream.
+ *
+ * Returns: A new #FsCodec or %NULL on error
+ */
+
+static FsCodec *
+fs_rtp_session_get_recv_codec_locked (FsRtpSession *session,
+    guint pt,
+    FsRtpStream *stream,
+    CodecBlueprint **bp,
+    GError **error)
+{
+  FsCodec *recv_codec = NULL;
+  CodecAssociation *ca = NULL;
+  GList *item = NULL;
+
+
+  if (!session->priv->codec_associations)
+  {
+    g_set_error (error, FS_ERROR, FS_ERROR_INTERNAL,
+        "No negotiated codecs yet");
+    return NULL;
+  }
+
+  ca = lookup_codec_association_by_pt (session->priv->codec_associations, pt);
+
+  if (!ca)
+  {
+    g_set_error (error, FS_ERROR, FS_ERROR_UNKNOWN_CODEC,
+      "There is no negotiated codec with pt %d", pt);
+    return NULL;
+  }
+
+  recv_codec = fs_codec_copy (ca->codec);
+
+  for (item = recv_codec->config_params; item; item = g_list_next (item))
+    g_slice_free (FsCodecParameter, item->data);
+
+  g_list_free (recv_codec->config_params);
+  recv_codec->config_params = NULL;
+
+  if (stream)
+  {
+    GList *remote_codecs = NULL;
+    FsCodec *remote_codec = NULL;
+
+    g_object_get (stream, "remote-codecs", &remote_codecs, NULL);
+
+    for (item = remote_codecs; item; item = g_list_next (item))
+    {
+      remote_codec = item->data;
+
+      if (recv_codec->clock_rate == remote_codec->clock_rate &&
+          (!recv_codec->channels || !remote_codec->channels ||
+              recv_codec->channels == remote_codec->channels) &&
+          (!recv_codec->encoding_name || !remote_codec->encoding_name ||
+              !g_ascii_strcasecmp (recv_codec->encoding_name,
+                  remote_codec->encoding_name)))
+      {
+        FsCodec *tmpcodec = sdp_is_compat (ca->codec, remote_codec);
+        if (tmpcodec)
+        {
+          if (fs_codec_are_equal (tmpcodec, ca->codec))
+          {
+            fs_codec_destroy (tmpcodec);
+            break;
+          }
+          fs_codec_destroy (tmpcodec);
+        }
+      }
+    }
+
+    if (item == NULL)
+      remote_codec = NULL;
+
+    if (remote_codec)
+    {
+      for (item = remote_codec->config_params; item; item = g_list_next (item))
+      {
+        FsCodecParameter *param = item->data;
+        fs_codec_add_config_parameter (recv_codec, param->name, param->value);
+      }
+    }
+
+    fs_codec_list_destroy (remote_codecs);
+  }
+
+  *bp = ca->blueprint;
+
+  return recv_codec;
+}
 
 /**
  * fs_rtp_session_substream_add_codec_bin:
@@ -2222,44 +2321,45 @@ fs_rtp_session_substream_add_codec_bin (FsRtpSession *session,
 {
   gboolean ret = FALSE;
   GstElement *codecbin = NULL;
-  CodecAssociation *ca = NULL;
   gchar *name;
+  FsRtpStream *stream = NULL;
   FsCodec *current_codec = NULL;
+  FsCodec *new_codec = NULL;
+  CodecBlueprint *bp = NULL;
 
   FS_RTP_SESSION_LOCK (session);
 
-  if (!session->priv->codec_associations) {
-    g_set_error (error, FS_ERROR, FS_ERROR_INTERNAL,
-        "No negotiated codecs yet");
-    goto out;
-  }
+  g_object_get (substream,
+      "codec", &current_codec,
+      "stream", &stream,
+      NULL);
 
-  ca = lookup_codec_association_by_pt (session->priv->codec_associations, pt);
+  new_codec = fs_rtp_session_get_recv_codec_locked (session, pt, stream, &bp,
+      error);
 
-  if (!ca) {
-    g_set_error (error, FS_ERROR, FS_ERROR_UNKNOWN_CODEC,
-      "There is no negotiated codec with pt %d", pt);
+  if (!new_codec)
     goto out;
-  }
 
-  g_object_get (substream, "codec", &current_codec, NULL);
-
-  if (fs_codec_are_equal (ca->codec, current_codec))
+  if (fs_codec_are_equal_including_config (new_codec, current_codec))
   {
     ret = TRUE;
     goto out;
   }
 
   name = g_strdup_printf ("recv%u_%d", ssrc, pt);
-  codecbin = _create_codec_bin (ca->blueprint, ca->codec, name, FALSE, error);
+  codecbin = _create_codec_bin (bp, new_codec, name, FALSE, error);
   g_free (name);
 
   if (!codecbin)
     goto out;
 
-  ret = fs_rtp_sub_stream_set_codecbin (substream, ca->codec, codecbin, error);
+  ret = fs_rtp_sub_stream_set_codecbin (substream, new_codec, codecbin, error);
 
  out:
+  if (stream)
+    g_object_unref (stream);
+
+  fs_codec_destroy (new_codec);
   fs_codec_destroy (current_codec);
 
   FS_RTP_SESSION_UNLOCK (session);
-- 
1.5.6.5




More information about the farsight-commits mailing list