+/* Create a pad for receiving RTP for the session in @name
+ */
+static GstPad *
+create_recv_rtp (GstRTPBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+{
+ GstPad *result;
+ guint sessid;
+ GstRTPBinSession *session;
+
+ /* first get the session number */
+ if (name == NULL || sscanf (name, "recv_rtp_sink_%d", &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->recv_rtp_sink != NULL)
+ goto existed;
+
+ /* get recv_rtp pad and store */
+ session->recv_rtp_sink =
+ gst_element_get_request_pad (session->session, "recv_rtp_sink");
+ if (session->recv_rtp_sink == NULL)
+ goto pad_failed;
+
+ result =
+ gst_ghost_pad_new_from_template (name, session->recv_rtp_sink, templ);
+ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
+
+ /* FIXME, get srcpad, link to SSRCDemux */
+
+ return result;
+
+ /* ERRORS */
+no_name:
+ {
+ g_warning ("rtpbin: invalid name given");
+ return NULL;
+ }
+create_error:
+ {
+ /* create_session already warned */
+ return NULL;
+ }
+existed:
+ {
+ g_warning ("rtpbin: recv_rtp pad already requested for session %d", sessid);
+ return NULL;
+ }
+pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session pad");
+ return NULL;
+ }
+}
+
+/* Create a pad for receiving RTCP for the session in @name
+ */
+static GstPad *
+create_recv_rtcp (GstRTPBin * rtpbin, GstPadTemplate * templ,
+ const gchar * name)
+{
+ GstPad *result;
+ guint sessid;
+ GstRTPBinSession *session;
+
+ /* first get the session number */
+ if (name == NULL || sscanf (name, "recv_rtcp_sink_%d", &sessid) != 1)
+ goto no_name;
+
+ /* get the session, it must exist or we error */
+ session = find_session_by_id (rtpbin, sessid);
+ if (!session)
+ goto no_session;
+
+ /* check if pad was requested */
+ if (session->recv_rtcp_sink != NULL)
+ goto existed;
+
+ /* get recv_rtp pad and store */
+ session->recv_rtcp_sink =
+ gst_element_get_request_pad (session->session, "recv_rtcp_sink");
+ if (session->recv_rtcp_sink == NULL)
+ goto pad_failed;
+
+ result =
+ gst_ghost_pad_new_from_template (name, session->recv_rtcp_sink, templ);
+ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
+
+ /* FIXME, get srcpad, link to SSRCDemux */
+
+ return result;
+
+ /* ERRORS */
+no_name:
+ {
+ g_warning ("rtpbin: invalid name given");
+ return NULL;
+ }
+no_session:
+ {
+ g_warning ("rtpbin: no session with id %d", sessid);
+ return NULL;
+ }
+existed:
+ {
+ g_warning ("rtpbin: recv_rtcp pad already requested for session %d",
+ sessid);
+ return NULL;
+ }
+pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session pad");
+ return NULL;
+ }
+}
+
+/* Create a pad for sending RTP for the session in @name
+ */
+static GstPad *
+create_send_rtp (GstRTPBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+{
+ GstPad *result, *srcpad, *srcghost;
+ gchar *gname;
+ guint sessid;
+ GstRTPBinSession *session;
+ GstElementClass *klass;
+
+ /* first get the session number */
+ if (name == NULL || sscanf (name, "send_rtp_sink_%d", &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 != NULL)
+ goto existed;
+
+ /* get recv_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;
+
+ result =
+ gst_ghost_pad_new_from_template (name, session->send_rtp_sink, templ);
+ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
+
+ /* get srcpad */
+ srcpad = gst_element_get_pad (session->session, "send_rtp_src");
+ if (srcpad == NULL)
+ goto no_srcpad;
+
+ /* ghost the new source pad */
+ klass = GST_ELEMENT_GET_CLASS (rtpbin);
+ gname = g_strdup_printf ("send_rtp_src_%d", sessid);
+ templ = gst_element_class_get_pad_template (klass, "send_rtp_src_%d");
+ srcghost =
+ gst_ghost_pad_new_from_template (gname, session->send_rtp_sink, templ);
+ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), srcghost);
+ g_free (gname);
+
+ return result;
+
+ /* ERRORS */
+no_name:
+ {
+ g_warning ("rtpbin: invalid name given");
+ return NULL;
+ }
+create_error:
+ {
+ /* create_session already warned */
+ return NULL;
+ }
+existed:
+ {
+ g_warning ("rtpbin: send_rtp pad already requested for session %d", sessid);
+ return NULL;
+ }
+pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session pad for session %d", sessid);
+ return NULL;
+ }
+no_srcpad:
+ {
+ g_warning ("rtpbin: failed to get rtp source pad for session %d", sessid);
+ return NULL;
+ }
+}
+
+/* Create a pad for sending RTCP for the session in @name
+ */
+static GstPad *
+create_rtcp (GstRTPBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+{
+ GstPad *result;
+ guint sessid;
+ GstRTPBinSession *session;
+
+ /* first get the session number */
+ if (name == NULL || sscanf (name, "send_rtp_sink_%d", &sessid) != 1)
+ goto no_name;
+
+ /* get or create session */
+ session = find_session_by_id (rtpbin, sessid);
+ if (!session)
+ goto no_session;
+
+ /* check if pad was requested */
+ if (session->rtcp_src != NULL)
+ goto existed;
+
+ /* get rtcp_src pad and store */
+ session->rtcp_src =
+ gst_element_get_request_pad (session->session, "rtcp_src");
+ if (session->rtcp_src == NULL)
+ goto pad_failed;
+
+ result = gst_ghost_pad_new_from_template (name, session->rtcp_src, templ);
+ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
+
+ return result;
+
+ /* ERRORS */
+no_name:
+ {
+ g_warning ("rtpbin: invalid name given");
+ return NULL;
+ }
+no_session:
+ {
+ g_warning ("rtpbin: session with id %d does not exist", sessid);
+ return NULL;
+ }
+existed:
+ {
+ g_warning ("rtpbin: rtcp_src pad already requested for session %d", sessid);
+ return NULL;
+ }
+pad_failed:
+ {
+ g_warning ("rtpbin: failed to get rtcp pad for session %d", sessid);
+ return NULL;
+ }
+}
+