[farsight2/master] rtp: Move substream blocking logic into substream

Olivier Crête olivier.crete at collabora.co.uk
Mon Dec 21 11:09:06 PST 2009


---
 gst/fsrtpconference/fs-rtp-session.c   |  127 +++++++------------------------
 gst/fsrtpconference/fs-rtp-substream.c |   73 ++++++++++++++++---
 gst/fsrtpconference/fs-rtp-substream.h |    5 -
 3 files changed, 91 insertions(+), 114 deletions(-)

diff --git a/gst/fsrtpconference/fs-rtp-session.c b/gst/fsrtpconference/fs-rtp-session.c
index 80c08b2..c4a9813 100644
--- a/gst/fsrtpconference/fs-rtp-session.c
+++ b/gst/fsrtpconference/fs-rtp-session.c
@@ -250,8 +250,9 @@ static GType fs_rtp_session_get_stream_transmitter_type (FsSession *session,
 
 static void _substream_no_rtcp_timedout_cb (FsRtpSubStream *substream,
     FsRtpSession *session);
-static void _substream_blocked (FsRtpSubStream *substream, FsRtpStream *stream,
-    FsRtpSession *session);
+static GstElement *_substream_get_codec_bin_locked (FsRtpSubStream *substream,
+    FsRtpStream *stream, FsCodec *current_codec, FsCodec **new_codec,
+    GError **error, FsRtpSession *session);
 
 static gboolean _stream_new_remote_codecs (FsRtpStream *stream,
     GList *codecs, GError **error, gpointer user_data);
@@ -265,14 +266,6 @@ static FsStreamTransmitter *fs_rtp_session_get_new_stream_transmitter (
     GParameter *parameters,
     GError **error);
 
-static gboolean fs_rtp_session_substream_set_codec_bin_unlock (
-    FsRtpSession *session,
-    FsRtpSubStream *substream,
-    FsRtpStream *stream,
-    guint32 ssrc,
-    guint pt,
-    GError **error);
-
 static void _remove_stream (gpointer user_data,
     GObject *where_the_object_was);
 
@@ -2538,8 +2531,8 @@ fs_rtp_session_new_recv_pad (FsRtpSession *session, GstPad *new_pad,
     return;
   }
 
-  g_signal_connect_object (substream, "blocked",
-      G_CALLBACK (_substream_blocked), session, 0);
+  g_signal_connect_object (substream, "get-codec-bin-locked",
+      G_CALLBACK (_substream_get_codec_bin_locked), session, 0);
 
   g_signal_connect_object (substream, "unlinked",
       G_CALLBACK (_substream_unlinked), session, 0);
@@ -2811,66 +2804,6 @@ fs_rtp_session_get_recv_codec_locked (FsRtpSession *session,
 }
 
 /**
- * fs_rtp_session_substream_set_codec_bin_unlock:
- * @session: a #FsRtpSession
- * @substream: a #FsRtpSubStream
- * @ssrc: the ssrc of the substream
- * @pt: the payload type of the substream
- * @error: location of a #GError, or NULL if no error occured
- *
- * Sets a codecbin on a substream according to the currently negotiated codecs
- *
- * You must enter this function with the session lock held and it will release
- * it.
- *
- * Returns: %TRUE on success, %FALSE on error
- */
-
-static gboolean
-fs_rtp_session_substream_set_codec_bin_unlock (FsRtpSession *session,
-    FsRtpSubStream *substream,
-    FsRtpStream *stream,
-    guint32 ssrc,
-    guint pt,
-    GError **error)
-{
-  GstElement *codecbin = NULL;
-  gchar *name;
-  CodecAssociation *ca = NULL;
-  gboolean ret = FALSE;
-  FsCodec *codec = NULL;
-
-  ca = fs_rtp_session_get_recv_codec_locked (session, pt, stream, &codec,
-      error);
-
-  if (!ca)
-    goto out;
-
-  if (fs_codec_are_equal (codec, substream->codec))
-  {
-    ret = TRUE;
-    goto out;
-  }
-
-  name = g_strdup_printf ("recv_%d_%u_%d", session->id, ssrc, pt);
-  codecbin = _create_codec_bin (ca, codec, name, FALSE, NULL, error);
-  g_free (name);
-
-  if (!codecbin)
-    goto out;
-
-
-  return fs_rtp_sub_stream_set_codecbin_unlock (substream,
-      codec, codecbin, error);
-
- out:
-  FS_RTP_SESSION_UNLOCK (session);
-  fs_codec_destroy (codec);
-  return ret;
-}
-
-
-/**
  * fs_rtp_session_select_send_codec_locked:
  * @session: the #FsRtpSession
  *
@@ -3550,42 +3483,40 @@ fs_rtp_session_verify_send_codec_bin (FsRtpSession *self)
  * if there is, it will change the codec bin.
  */
 
-static void
-_substream_blocked (FsRtpSubStream *substream, FsRtpStream *stream,
-    FsRtpSession *session)
+static GstElement *
+_substream_get_codec_bin_locked (FsRtpSubStream *substream,
+    FsRtpStream *stream, FsCodec *current_codec, FsCodec **new_codec,
+    GError **error, FsRtpSession *session)
 {
-  GError *error = NULL;
-  guint32 ssrc;
-  guint pt;
+  GstElement *codecbin = NULL;
+  gchar *name;
+  CodecAssociation *ca = NULL;
 
   if (fs_rtp_session_has_disposed_enter (session, NULL))
-    return;
-
-  FS_RTP_SESSION_LOCK (session);
+    return NULL;
 
-  pt = substream->pt;
-  ssrc = substream->ssrc;
+  ca = fs_rtp_session_get_recv_codec_locked (session, substream->pt, stream,
+      new_codec, error);
 
-  GST_DEBUG ("Substream blocked for codec change (session:%d SSRC:%x pt:%d)",
-      session->id, substream->ssrc, substream->pt);
+  if (!ca)
+    goto out;
 
-  if (!fs_rtp_session_substream_set_codec_bin_unlock (session, substream,
-          stream, substream->ssrc, substream->pt, &error))
+  if (fs_codec_are_equal (*new_codec, current_codec))
   {
-    gchar *str = g_strdup_printf ("Could not add the new recv codec bin for"
-        " ssrc %u and payload type %d to the state NULL", ssrc, pt);
-
-    if (stream)
-      fs_stream_emit_error (FS_STREAM (stream), FS_ERROR_CONSTRUCTION,
-          "Could not add the new recv codec bin", error->message);
-    else
-      fs_session_emit_error (FS_SESSION (session), FS_ERROR_CONSTRUCTION,
-          "Could not add the new recv codec bin", error->message);
-    g_free (str);
+    g_clear_error (error);
+    goto out;
   }
 
-  g_clear_error (&error);
+  name = g_strdup_printf ("recv_%d_%u_%d", session->id, substream->ssrc,
+      substream->pt);
+  codecbin = _create_codec_bin (ca, *new_codec, name, FALSE, NULL, error);
+  g_free (name);
+
+ out:
+
   fs_rtp_session_has_disposed_exit (session);
+
+  return codecbin;
 }
 
 static void
diff --git a/gst/fsrtpconference/fs-rtp-substream.c b/gst/fsrtpconference/fs-rtp-substream.c
index 379e347..f5a3d5b 100644
--- a/gst/fsrtpconference/fs-rtp-substream.c
+++ b/gst/fsrtpconference/fs-rtp-substream.c
@@ -1,9 +1,9 @@
 /*
  * Farsight2 - Farsight RTP Sub Stream
  *
- * Copyright 2007 Collabora Ltd.
+ * Copyright 2007-2009 Collabora Ltd.
  *  @author: Olivier Crete <olivier.crete at collabora.co.uk>
- * Copyright 2007 Nokia Corp.
+ * Copyright 2007-2009 Nokia Corp.
  *
  * fs-rtp-substream.c - A Farsight RTP Substream gobject
  *
@@ -53,7 +53,7 @@ enum
   SRC_PAD_ADDED,
   CODEC_CHANGED,
   ERROR_SIGNAL,
-  BLOCKED,
+  GET_CODEC_BIN_LOCKED,
   UNLINKED,
   LAST_SIGNAL
 };
@@ -352,21 +352,27 @@ fs_rtp_sub_stream_class_init (FsRtpSubStreamClass *klass)
       G_TYPE_NONE, 0);
 
  /**
-   * FsRtpSubStream:blocked
+   * FsRtpSubStream:get-codec-bin-locked
    * @self: #FsRtpSubStream that emitted the signal
    * @stream: the #FsRtpStream this substream is attached to if any (or %NULL)
+   * @current_codec: The current codec
+   * @new_codec: A pointer to a location where the codec can be stored
+   * @error: The location of a GError where an error can be stored
    *
-   * This signal is emitted after the substream has been blocked because its
-   * codec has been invalidated OR because no codecbin was set on its creation.
+   * This emitted when the substream want to get a codecbin or replace
+   * the current one.
+   *
+   * Returns: The Codec Bin
    */
-  signals[BLOCKED] = g_signal_new ("blocked",
+  signals[GET_CODEC_BIN_LOCKED] = g_signal_new ("get-codec-bin-locked",
       G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST,
       0,
       NULL,
       NULL,
-      g_cclosure_marshal_VOID__POINTER,
-      G_TYPE_NONE, 1, G_TYPE_POINTER);
+      _fs_rtp_marshal_POINTER__POINTER_POINTER_POINTER_POINTER,
+      G_TYPE_POINTER, 4, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER,
+      G_TYPE_POINTER);
 
 
  /**
@@ -866,7 +872,7 @@ fs_rtp_sub_stream_get_property (GObject *object,
  * Returns: TRUE on success
  */
 
-gboolean
+static gboolean
 fs_rtp_sub_stream_set_codecbin_unlock (FsRtpSubStream *substream,
     FsCodec *codec,
     GstElement *codecbin,
@@ -1314,10 +1320,55 @@ static void
 _rtpbin_pad_blocked_callback (GstPad *pad, gboolean blocked, gpointer user_data)
 {
   FsRtpSubStream *substream = user_data;
+  GstElement *codecbin = NULL;
+  FsCodec *codec = NULL;
+  GError *error = NULL;
+
+  FS_RTP_SESSION_LOCK (substream->priv->session);
+
+  GST_DEBUG ("Substream blocked for codec change (session:%d SSRC:%x pt:%d)",
+      substream->priv->session->id, substream->ssrc, substream->pt);
 
-  g_signal_emit (substream, signals[BLOCKED], 0, substream->priv->stream);
+  g_signal_emit (substream, signals[GET_CODEC_BIN_LOCKED], 0,
+      substream->priv->stream, substream->codec, &codec, &error, &codecbin);
+
+  if (!codecbin)
+  {
+    if (error)
+      goto error;
+    else
+      goto out;
+  }
+
+  if (!fs_rtp_sub_stream_set_codecbin_unlock (substream,
+          codec, codecbin, &error))
+    goto error;
+
+ out:
+
+  fs_codec_destroy (codec);
+
+  g_clear_error (&error);
 
   gst_pad_set_blocked_async (pad, FALSE, do_nothing_blocked_callback, NULL);
+
+  return;
+
+ error:
+  {
+    gchar *str = g_strdup_printf ("Could not add the new recv codec bin for"
+        " ssrc %u and payload type %d to the state NULL", substream->ssrc,
+        substream->pt);
+
+    if (substream->priv->stream)
+      fs_stream_emit_error (FS_STREAM (substream->priv->stream),
+          FS_ERROR_CONSTRUCTION, str, error->message);
+    else
+      fs_session_emit_error (FS_SESSION (substream->priv->session),
+          FS_ERROR_CONSTRUCTION, str, error->message);
+    g_free (str);
+  }
+  goto out;
 }
 
 static void
diff --git a/gst/fsrtpconference/fs-rtp-substream.h b/gst/fsrtpconference/fs-rtp-substream.h
index 082b149..004c3be 100644
--- a/gst/fsrtpconference/fs-rtp-substream.h
+++ b/gst/fsrtpconference/fs-rtp-substream.h
@@ -91,11 +91,6 @@ FsRtpSubStream *fs_rtp_sub_stream_new (FsRtpConference *conference,
     GError **error);
 
 
-gboolean fs_rtp_sub_stream_set_codecbin_unlock (FsRtpSubStream *substream,
-    FsCodec *codec,
-    GstElement *codecbin,
-    GError **error);
-
 void fs_rtp_sub_stream_stop (FsRtpSubStream *substream);
 
 gboolean fs_rtp_sub_stream_add_output_ghostpad_unlock (
-- 
1.5.6.5




More information about the farsight-commits mailing list