rtpbin: add support for AUX sender and receiver
authorWim Taymans <wtaymans@redhat.com>
Tue, 31 Dec 2013 11:31:25 +0000 (12:31 +0100)
committerWim Taymans <wtaymans@redhat.com>
Tue, 31 Dec 2013 14:08:48 +0000 (15:08 +0100)
AUX elements are elements that can be inserted into the rtpbin
pipeline right before or after 1 or more session elements.

The AUX elements are essential for implementing functionality such
as error correction (FEC) and retransmission (RTX).

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=711087

gst/rtpmanager/gstrtpbin.c
gst/rtpmanager/gstrtpbin.h

index 1d057c1..f6979ca 100644 (file)
@@ -259,6 +259,9 @@ enum
 
   SIGNAL_NEW_JITTERBUFFER,
 
+  SIGNAL_REQUEST_AUX_SENDER,
+  SIGNAL_REQUEST_AUX_RECEIVER,
+
   LAST_SIGNAL
 };
 
@@ -1983,6 +1986,41 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
           new_jitterbuffer), NULL, NULL, g_cclosure_marshal_generic,
       G_TYPE_NONE, 3, GST_TYPE_ELEMENT, G_TYPE_UINT, G_TYPE_UINT);
 
+  /**
+   * GstRtpBin::request-aux-sender:
+   * @rtpbin: the object which received the signal
+   * @session: the session
+   *
+   * Request an AUX sender element for the given @session. The AUX
+   * element will be added to the bin.
+   *
+   * If no handler is connected, no AUX element will be used.
+   *
+   * Since: 1.4
+   */
+  gst_rtp_bin_signals[SIGNAL_REQUEST_AUX_SENDER] =
+      g_signal_new ("request-aux-sender", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
+          request_aux_sender), _gst_element_accumulator, NULL,
+      g_cclosure_marshal_generic, GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
+  /**
+   * GstRtpBin::request-aux-receiver:
+   * @rtpbin: the object which received the signal
+   * @session: the session
+   *
+   * Request an AUX receiver element for the given @session. The AUX
+   * element will be added to the bin.
+   *
+   * If no handler is connected, no AUX element will be used.
+   *
+   * Since: 1.4
+   */
+  gst_rtp_bin_signals[SIGNAL_REQUEST_AUX_RECEIVER] =
+      g_signal_new ("request-aux-receiver", G_TYPE_FROM_CLASS (klass),
+      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
+          request_aux_receiver), _gst_element_accumulator, NULL,
+      g_cclosure_marshal_generic, GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
+
   g_object_class_install_property (gobject_class, PROP_SDES,
       g_param_spec_boxed ("sdes", "SDES",
           "The SDES items of this session",
@@ -2856,38 +2894,16 @@ no_stream:
   }
 }
 
-/* Create a pad for receiving RTP for the session in @name. Must be called with
- * RTP_BIN_LOCK.
- */
-static GstPad *
-create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+static gboolean
+complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
 {
-  guint sessid;
+  gchar *gname;
+  guint sessid = session->id;
+  GstPad *recv_rtp_sink;
   GstElement *decoder;
-  GstPad *sinkdpad, *decsink;
-  GstRtpBinSession *session;
-
-  /* first get the session number */
-  if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
-    goto no_name;
-
-  GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
-
-  /* get or create session */
-  session = find_session_by_id (rtpbin, sessid);
-  if (!session) {
-    GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
-    /* create session now */
-    session = create_session (rtpbin, sessid);
-    if (session == NULL)
-      goto create_error;
-  }
-
-  /* check if pad was requested */
-  if (session->recv_rtp_sink_ghost != NULL)
-    return session->recv_rtp_sink_ghost;
+  GstElementClass *klass;
+  GstPadTemplate *templ;
 
-  GST_DEBUG_OBJECT (rtpbin, "getting RTP sink pad");
   /* get recv_rtp pad and store */
   session->recv_rtp_sink =
       gst_element_get_request_pad (session->session, "recv_rtp_sink");
@@ -2900,16 +2916,17 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
   GST_DEBUG_OBJECT (rtpbin, "requesting RTP decoder");
   decoder = session_request_element (session, SIGNAL_REQUEST_RTP_DECODER);
   if (decoder) {
-    GstPad *decsrc;
+    GstPad *decsrc, *decsink;
     GstPadLinkReturn ret;
 
     GST_DEBUG_OBJECT (rtpbin, "linking RTP decoder");
     decsink = gst_element_get_static_pad (decoder, "rtp_sink");
-    decsrc = gst_element_get_static_pad (decoder, "rtp_src");
-
     if (decsink == NULL)
       goto dec_sink_failed;
 
+    recv_rtp_sink = decsink;
+
+    decsrc = gst_element_get_static_pad (decoder, "rtp_src");
     if (decsrc == NULL)
       goto dec_src_failed;
 
@@ -2918,38 +2935,136 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
 
     if (ret != GST_PAD_LINK_OK)
       goto dec_link_failed;
+
   } else {
     GST_DEBUG_OBJECT (rtpbin, "no RTP decoder given");
-    decsink = gst_object_ref (session->recv_rtp_sink);
+    recv_rtp_sink = gst_object_ref (session->recv_rtp_sink);
   }
 
-  GST_DEBUG_OBJECT (rtpbin, "getting RTP src pad");
-  /* get srcpad, link to SSRCDemux */
+  GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
+  klass = GST_ELEMENT_GET_CLASS (rtpbin);
+  gname = g_strdup_printf ("recv_rtp_sink_%u", sessid);
+  templ = gst_element_class_get_pad_template (klass, "recv_rtp_sink_%u");
+  session->recv_rtp_sink_ghost =
+      gst_ghost_pad_new_from_template (gname, recv_rtp_sink, templ);
+  gst_object_unref (recv_rtp_sink);
+  gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
+  gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
+  g_free (gname);
+
+  return TRUE;
+
+  /* ERRORS */
+pad_failed:
+  {
+    g_warning ("rtpbin: failed to get session recv_rtp_sink pad");
+    return FALSE;
+  }
+dec_sink_failed:
+  {
+    g_warning ("rtpbin: failed to get decoder sink pad for session %d", sessid);
+    return FALSE;
+  }
+dec_src_failed:
+  {
+    g_warning ("rtpbin: failed to get decoder src pad for session %d", sessid);
+    gst_object_unref (recv_rtp_sink);
+    return FALSE;
+  }
+dec_link_failed:
+  {
+    g_warning ("rtpbin: failed to link rtp decoder for session %d", sessid);
+    gst_object_unref (recv_rtp_sink);
+    return FALSE;
+  }
+}
+
+/* Create a pad for receiving RTP for the session in @name. Must be called with
+ * RTP_BIN_LOCK.
+ */
+static GstPad *
+create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+{
+  guint sessid;
+  GstElement *aux;
+  GstPad *recv_rtp_src;
+  GstRtpBinSession *session;
+
+  /* first get the session number */
+  if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
+    goto no_name;
+
+  GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
+
+  /* get or create session */
+  session = find_session_by_id (rtpbin, sessid);
+  if (!session) {
+    GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
+    /* create session now */
+    session = create_session (rtpbin, sessid);
+    if (session == NULL)
+      goto create_error;
+  }
+
+  /* check if pad was requested */
+  if (session->recv_rtp_sink_ghost != NULL)
+    return session->recv_rtp_sink_ghost;
+
+  /* setup the session sink pad */
+  if (!complete_session_sink (rtpbin, session))
+    goto session_sink_failed;
+
   session->recv_rtp_src =
       gst_element_get_static_pad (session->session, "recv_rtp_src");
   if (session->recv_rtp_src == NULL)
-    goto src_pad_failed;
+    goto pad_failed;
 
-  GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTP sink pad");
-  sinkdpad = gst_element_get_static_pad (session->demux, "sink");
-  GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
-  gst_pad_link_full (session->recv_rtp_src, sinkdpad,
-      GST_PAD_LINK_CHECK_NOTHING);
-  gst_object_unref (sinkdpad);
+  /* find out if we need AUX elements or if we can go into the SSRC demuxer
+   * directly */
+  aux = session_request_element (session, SIGNAL_REQUEST_AUX_RECEIVER);
+  if (aux) {
+    gchar *pname;
+    GstPad *auxsink;
+    GstPadLinkReturn ret;
 
-  /* connect to the new-ssrc-pad signal of the SSRC demuxer */
-  session->demux_newpad_sig = g_signal_connect (session->demux,
-      "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session);
-  session->demux_padremoved_sig = g_signal_connect (session->demux,
-      "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session);
+    GST_DEBUG_OBJECT (rtpbin, "linking AUX receiver");
 
-  GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
-  session->recv_rtp_sink_ghost =
-      gst_ghost_pad_new_from_template (name, decsink, templ);
-  gst_object_unref (decsink);
-  gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
-  gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
+    pname = g_strdup_printf ("sink_%d", sessid);
+    auxsink = gst_element_get_static_pad (aux, pname);
+    g_free (pname);
+    if (auxsink == NULL)
+      goto aux_sink_failed;
 
+    ret = gst_pad_link (session->recv_rtp_src, auxsink);
+    gst_object_unref (auxsink);
+    if (ret != GST_PAD_LINK_OK)
+      goto aux_link_failed;
+
+    /* this can be NULL when this AUX element is not to be linked to
+     * an SSRC demuxer */
+    pname = g_strdup_printf ("src_%d", sessid);
+    recv_rtp_src = gst_element_get_static_pad (aux, pname);
+    g_free (pname);
+  } else {
+    recv_rtp_src = gst_object_ref (session->recv_rtp_src);
+  }
+
+  if (recv_rtp_src) {
+    GstPad *sinkdpad;
+
+    GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTP sink pad");
+    sinkdpad = gst_element_get_static_pad (session->demux, "sink");
+    GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
+    gst_pad_link_full (recv_rtp_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
+    gst_object_unref (recv_rtp_src);
+    gst_object_unref (sinkdpad);
+
+    /* connect to the new-ssrc-pad signal of the SSRC demuxer */
+    session->demux_newpad_sig = g_signal_connect (session->demux,
+        "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session);
+    session->demux_padremoved_sig = g_signal_connect (session->demux,
+        "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session);
+  }
   return session->recv_rtp_sink_ghost;
 
   /* ERRORS */
@@ -2963,32 +3078,24 @@ create_error:
     /* create_session already warned */
     return NULL;
   }
-pad_failed:
+session_sink_failed:
   {
-    g_warning ("rtpbin: failed to get session rtp_sink pad");
+    /* warning already done */
     return NULL;
   }
-dec_sink_failed:
-  {
-    g_warning ("rtpbin: failed to get decoder sink pad for session %d", sessid);
-    return NULL;
-  }
-dec_src_failed:
+pad_failed:
   {
-    g_warning ("rtpbin: failed to get decoder src pad for session %d", sessid);
-    gst_object_unref (decsink);
+    g_warning ("rtpbin: failed to get session recv_rtp_src pad");
     return NULL;
   }
-dec_link_failed:
+aux_sink_failed:
   {
-    g_warning ("rtpbin: failed to link rtp decoder for session %d", sessid);
-    gst_object_unref (decsink);
+    g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
     return NULL;
   }
-src_pad_failed:
+aux_link_failed:
   {
-    g_warning ("rtpbin: failed to get session rtp_src pad");
-    gst_object_unref (decsink);
+    g_warning ("rtpbin: failed to link AUX pad to session %d", sessid);
     return NULL;
   }
 }
@@ -3168,46 +3275,15 @@ remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session)
   }
 }
 
-/* Create a pad for sending RTP for the session in @name. Must be called with
- * RTP_BIN_LOCK.
- */
-static GstPad *
-create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+static gboolean
+complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
 {
   gchar *gname;
-  guint sessid;
-  GstPad *encsrc;
+  guint sessid = session->id;
+  GstPad *send_rtp_src;
   GstElement *encoder;
-  GstRtpBinSession *session;
   GstElementClass *klass;
-
-  /* first get the session number */
-  if (name == NULL || sscanf (name, "send_rtp_sink_%u", &sessid) != 1)
-    goto no_name;
-
-  /* get or create session */
-  session = find_session_by_id (rtpbin, sessid);
-  if (!session) {
-    /* create session now */
-    session = create_session (rtpbin, sessid);
-    if (session == NULL)
-      goto create_error;
-  }
-
-  /* check if pad was requested */
-  if (session->send_rtp_sink_ghost != NULL)
-    return session->send_rtp_sink_ghost;
-
-  /* get send_rtp pad and store */
-  session->send_rtp_sink =
-      gst_element_get_request_pad (session->session, "send_rtp_sink");
-  if (session->send_rtp_sink == NULL)
-    goto pad_failed;
-
-  session->send_rtp_sink_ghost =
-      gst_ghost_pad_new_from_template (name, session->send_rtp_sink, templ);
-  gst_pad_set_active (session->send_rtp_sink_ghost, TRUE);
-  gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_sink_ghost);
+  GstPadTemplate *templ;
 
   /* get srcpad */
   session->send_rtp_src =
@@ -3219,13 +3295,10 @@ create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
   encoder = session_request_element (session, SIGNAL_REQUEST_RTP_ENCODER);
   if (encoder) {
     gchar *ename;
-    GstPad *encsink;
+    GstPad *encsrc, *encsink;
     GstPadLinkReturn ret;
 
     GST_DEBUG_OBJECT (rtpbin, "linking RTP encoder");
-    ename = g_strdup_printf ("rtp_sink_%d", sessid);
-    encsink = gst_element_get_static_pad (encoder, ename);
-    g_free (ename);
     ename = g_strdup_printf ("rtp_src_%d", sessid);
     encsrc = gst_element_get_static_pad (encoder, ename);
     g_free (ename);
@@ -3233,6 +3306,11 @@ create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
     if (encsrc == NULL)
       goto enc_src_failed;
 
+    send_rtp_src = encsrc;
+
+    ename = g_strdup_printf ("rtp_sink_%d", sessid);
+    encsink = gst_element_get_static_pad (encoder, ename);
+    g_free (ename);
     if (encsink == NULL)
       goto enc_sink_failed;
 
@@ -3243,7 +3321,7 @@ create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
       goto enc_link_failed;
   } else {
     GST_DEBUG_OBJECT (rtpbin, "no RTP encoder given");
-    encsrc = gst_object_ref (session->send_rtp_src);
+    send_rtp_src = gst_object_ref (session->send_rtp_src);
   }
 
   /* ghost the new source pad */
@@ -3251,12 +3329,195 @@ create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
   gname = g_strdup_printf ("send_rtp_src_%u", sessid);
   templ = gst_element_class_get_pad_template (klass, "send_rtp_src_%u");
   session->send_rtp_src_ghost =
-      gst_ghost_pad_new_from_template (gname, encsrc, templ);
-  gst_object_unref (encsrc);
+      gst_ghost_pad_new_from_template (gname, send_rtp_src, templ);
+  gst_object_unref (send_rtp_src);
   gst_pad_set_active (session->send_rtp_src_ghost, TRUE);
   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_src_ghost);
   g_free (gname);
 
+  return TRUE;
+
+  /* ERRORS */
+no_srcpad:
+  {
+    g_warning ("rtpbin: failed to get rtp source pad for session %d", sessid);
+    return FALSE;
+  }
+enc_src_failed:
+  {
+    g_warning ("rtpbin: failed to get encoder src pad for session %d", sessid);
+    return FALSE;
+  }
+enc_sink_failed:
+  {
+    g_warning ("rtpbin: failed to get encoder sink pad for session %d", sessid);
+    gst_object_unref (send_rtp_src);
+    return FALSE;
+  }
+enc_link_failed:
+  {
+    g_warning ("rtpbin: failed to link rtp encoder for session %d", sessid);
+    gst_object_unref (send_rtp_src);
+    return FALSE;
+  }
+}
+
+static gboolean
+setup_aux_sender_fold (const GValue * item, GValue * result, gpointer user_data)
+{
+  GstPad *pad;
+  gchar *name;
+  guint sessid;
+  GstRtpBinSession *session = user_data, *newsess;
+  GstRtpBin *rtpbin = session->bin;
+  GstPadLinkReturn ret;
+
+  pad = g_value_get_object (item);
+  name = gst_pad_get_name (pad);
+
+  if (name == NULL || sscanf (name, "src_%u", &sessid) != 1)
+    goto no_name;
+
+  g_free (name);
+
+  newsess = find_session_by_id (rtpbin, sessid);
+  if (newsess == NULL) {
+    /* create new session */
+    newsess = create_session (rtpbin, sessid);
+    if (newsess == NULL)
+      goto create_error;
+  } else if (newsess->send_rtp_sink != NULL)
+    goto existing_session;
+
+  /* get send_rtp pad and store */
+  newsess->send_rtp_sink =
+      gst_element_get_request_pad (newsess->session, "send_rtp_sink");
+  if (newsess->send_rtp_sink == NULL)
+    goto pad_failed;
+
+  ret = gst_pad_link (pad, newsess->send_rtp_sink);
+  if (ret != GST_PAD_LINK_OK)
+    goto aux_link_failed;
+
+  if (!complete_session_src (rtpbin, newsess))
+    goto session_src_failed;
+
+  return TRUE;
+
+  /* ERRORS */
+no_name:
+  {
+    GST_WARNING ("ignoring invalid pad name %s", GST_STR_NULL (name));
+    g_free (name);
+    return TRUE;
+  }
+create_error:
+  {
+    /* create_session already warned */
+    return FALSE;
+  }
+existing_session:
+  {
+    g_warning ("rtpbin: session %d is already a sender", sessid);
+    return FALSE;
+  }
+pad_failed:
+  {
+    g_warning ("rtpbin: failed to get session pad for session %d", sessid);
+    return FALSE;
+  }
+aux_link_failed:
+  {
+    g_warning ("rtpbin: failed to link AUX for session %d", sessid);
+    return FALSE;
+  }
+session_src_failed:
+  {
+    g_warning ("rtpbin: failed to complete AUX for session %d", sessid);
+    return FALSE;
+  }
+}
+
+static gboolean
+setup_aux_sender (GstRtpBin * rtpbin, GstRtpBinSession * session,
+    GstElement * aux)
+{
+  GstIterator *it;
+  GValue result = { 0, };
+  GstIteratorResult res;
+
+  it = gst_element_iterate_src_pads (aux);
+  res = gst_iterator_fold (it, setup_aux_sender_fold, &result, session);
+  gst_iterator_free (it);
+
+  return res == GST_ITERATOR_DONE;
+}
+
+/* Create a pad for sending RTP for the session in @name. Must be called with
+ * RTP_BIN_LOCK.
+ */
+static GstPad *
+create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+{
+  gchar *pname;
+  guint sessid;
+  GstPad *send_rtp_sink;
+  GstElement *aux;
+  GstRtpBinSession *session;
+
+  /* first get the session number */
+  if (name == NULL || sscanf (name, "send_rtp_sink_%u", &sessid) != 1)
+    goto no_name;
+
+  /* get or create session */
+  session = find_session_by_id (rtpbin, sessid);
+  if (!session) {
+    /* create session now */
+    session = create_session (rtpbin, sessid);
+    if (session == NULL)
+      goto create_error;
+  }
+
+  /* check if pad was requested */
+  if (session->send_rtp_sink_ghost != NULL)
+    return session->send_rtp_sink_ghost;
+
+  /* check if we are already using this session as a sender */
+  if (session->send_rtp_sink != NULL)
+    goto existing_session;
+
+  GST_DEBUG_OBJECT (rtpbin, "getting RTP AUX sender");
+  aux = session_request_element (session, SIGNAL_REQUEST_AUX_SENDER);
+  if (aux) {
+    GST_DEBUG_OBJECT (rtpbin, "linking AUX sender");
+    if (!setup_aux_sender (rtpbin, session, aux))
+      goto aux_session_failed;
+
+    pname = g_strdup_printf ("sink_%d", sessid);
+    send_rtp_sink = gst_element_get_static_pad (aux, pname);
+    g_free (pname);
+
+    if (send_rtp_sink == NULL)
+      goto aux_sink_failed;
+  } else {
+    /* get send_rtp pad and store */
+    session->send_rtp_sink =
+        gst_element_get_request_pad (session->session, "send_rtp_sink");
+    if (session->send_rtp_sink == NULL)
+      goto pad_failed;
+
+    if (!complete_session_src (rtpbin, session))
+      goto session_src_failed;
+
+    send_rtp_sink = gst_object_ref (session->send_rtp_sink);
+  }
+
+  session->send_rtp_sink_ghost =
+      gst_ghost_pad_new_from_template (name, send_rtp_sink, templ);
+  gst_object_unref (send_rtp_sink);
+  gst_pad_set_active (session->send_rtp_sink_ghost, TRUE);
+  gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_sink_ghost);
+
   return session->send_rtp_sink_ghost;
 
   /* ERRORS */
@@ -3270,31 +3531,29 @@ create_error:
     /* create_session already warned */
     return NULL;
   }
-pad_failed:
+existing_session:
   {
-    g_warning ("rtpbin: failed to get session pad for session %d", sessid);
+    g_warning ("rtpbin: session %d is already in use", sessid);
     return NULL;
   }
-no_srcpad:
+aux_session_failed:
   {
-    g_warning ("rtpbin: failed to get rtp source pad for session %d", sessid);
+    g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
     return NULL;
   }
-enc_src_failed:
+aux_sink_failed:
   {
-    g_warning ("rtpbin: failed to get encoder src pad for session %d", sessid);
+    g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
     return NULL;
   }
-enc_sink_failed:
+pad_failed:
   {
-    g_warning ("rtpbin: failed to get encoder sink pad for session %d", sessid);
-    gst_object_unref (encsrc);
+    g_warning ("rtpbin: failed to get session pad for session %d", sessid);
     return NULL;
   }
-enc_link_failed:
+session_src_failed:
   {
-    g_warning ("rtpbin: failed to link rtp encoder for session %d", sessid);
-    gst_object_unref (encsrc);
+    g_warning ("rtpbin: failed to setup source pads for session %d", sessid);
     return NULL;
   }
 }
index 4bfe353..0ac8060 100644 (file)
@@ -103,6 +103,9 @@ struct _GstRtpBinClass {
   GstElement* (*request_rtp_decoder)  (GstRtpBin *rtpbin, guint session);
   GstElement* (*request_rtcp_encoder) (GstRtpBin *rtpbin, guint session);
   GstElement* (*request_rtcp_decoder) (GstRtpBin *rtpbin, guint session);
+
+  GstElement* (*request_aux_sender)   (GstRtpBin *rtpbin, guint session);
+  GstElement* (*request_aux_receiver) (GstRtpBin *rtpbin, guint session);
 };
 
 GType gst_rtp_bin_get_type (void);