summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatricia Muscalu <patricia@axis.com>2015-11-19 14:09:25 +0100
committerSebastian Dröge <sebastian@centricular.com>2016-02-23 17:05:15 +0200
commit89bc8009dd6b8a7e5d82d02a6794622a929268c0 (patch)
tree1263113883b4bf9eeb0d74faa5e2abf6631ef8bd
parent457c00dc0a9fcd7ea7aa271f2a2f26d977720e53 (diff)
rtsp-stream: added helper function for creating the sender/receiver parts
Code refactoring: introduced helper function for creating the receiver and the sender parts of the streaming pipeline. https://bugzilla.gnome.org/show_bug.cgi?id=757488
-rw-r--r--gst/rtsp-server/rtsp-stream.c293
1 files changed, 166 insertions, 127 deletions
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c
index 4034a5c..83f2256 100644
--- a/gst/rtsp-server/rtsp-stream.c
+++ b/gst/rtsp-server/rtsp-stream.c
@@ -2112,132 +2112,26 @@ on_npt_stop (GstElement * rtpbin, guint session, guint ssrc,
gst_pad_send_event (stream->priv->sinkpad, gst_event_new_eos ());
}
-/**
- * gst_rtsp_stream_join_bin:
- * @stream: a #GstRTSPStream
- * @bin: (transfer none): a #GstBin to join
- * @rtpbin: (transfer none): a rtpbin element in @bin
- * @state: the target state of the new elements
- *
- * Join the #GstBin @bin that contains the element @rtpbin.
- *
- * @stream will link to @rtpbin, which must be inside @bin. The elements
- * added to @bin will be set to the state given in @state.
- *
- * Returns: %TRUE on success.
- */
-gboolean
-gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
- GstElement * rtpbin, GstState state)
+
+/* must be called with lock */
+static void
+create_sender_part (GstRTSPStream * stream, GstBin * bin,
+ GstState state)
{
GstRTSPStreamPrivate *priv;
- gint i;
- guint idx;
- gchar *name;
- GstPad *pad, *sinkpad = NULL, *selpad;
- GstPadLinkReturn ret;
+ GstPad *pad, *sinkpad = NULL;
gboolean is_tcp = FALSE, is_udp = FALSE;
-
- g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
- g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
- g_return_val_if_fail (GST_IS_ELEMENT (rtpbin), FALSE);
+ gint i;
priv = stream->priv;
- g_mutex_lock (&priv->lock);
- if (priv->is_joined)
- goto was_joined;
-
- /* create a session with the same index as the stream */
- idx = priv->idx;
-
- GST_INFO ("stream %p joining bin as session %u", stream, idx);
-
is_tcp = priv->protocols & GST_RTSP_LOWER_TRANS_TCP;
-
is_udp = ((priv->protocols & GST_RTSP_LOWER_TRANS_UDP) ||
(priv->protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST));
- if (is_udp && !alloc_ports (stream))
- goto no_ports;
-
- /* update the dscp qos field in the sinks */
- update_dscp_qos (stream);
-
- if (priv->profiles & GST_RTSP_PROFILE_SAVP
- || priv->profiles & GST_RTSP_PROFILE_SAVPF) {
- /* For SRTP */
- g_signal_connect (rtpbin, "request-rtp-encoder",
- (GCallback) request_rtp_encoder, stream);
- g_signal_connect (rtpbin, "request-rtcp-encoder",
- (GCallback) request_rtcp_encoder, stream);
- g_signal_connect (rtpbin, "request-rtp-decoder",
- (GCallback) request_rtp_rtcp_decoder, stream);
- g_signal_connect (rtpbin, "request-rtcp-decoder",
- (GCallback) request_rtp_rtcp_decoder, stream);
- }
-
- if (priv->sinkpad) {
- g_signal_connect (rtpbin, "request-pt-map",
- (GCallback) request_pt_map, stream);
- }
-
- /* get pads from the RTP session element for sending and receiving
- * RTP/RTCP*/
- if (priv->srcpad) {
- /* get a pad for sending RTP */
- name = g_strdup_printf ("send_rtp_sink_%u", idx);
- priv->send_rtp_sink = gst_element_get_request_pad (rtpbin, name);
- g_free (name);
-
- /* link the RTP pad to the session manager, it should not really fail unless
- * this is not really an RTP pad */
- ret = gst_pad_link (priv->srcpad, priv->send_rtp_sink);
- if (ret != GST_PAD_LINK_OK)
- goto link_failed;
-
- name = g_strdup_printf ("send_rtp_src_%u", idx);
- priv->send_src[0] = gst_element_get_static_pad (rtpbin, name);
- g_free (name);
- } else {
- /* Need to connect our sinkpad from here */
- g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added, stream);
- /* EOS */
- g_signal_connect (rtpbin, "on-npt-stop", (GCallback) on_npt_stop, stream);
-
- name = g_strdup_printf ("recv_rtp_sink_%u", idx);
- priv->recv_sink[0] = gst_element_get_request_pad (rtpbin, name);
- g_free (name);
- }
-
- name = g_strdup_printf ("send_rtcp_src_%u", idx);
- priv->send_src[1] = gst_element_get_request_pad (rtpbin, name);
- g_free (name);
- name = g_strdup_printf ("recv_rtcp_sink_%u", idx);
- priv->recv_sink[1] = gst_element_get_request_pad (rtpbin, name);
- g_free (name);
-
- /* get the session */
- g_signal_emit_by_name (rtpbin, "get-internal-session", idx, &priv->session);
-
- g_signal_connect (priv->session, "on-new-ssrc", (GCallback) on_new_ssrc,
- stream);
- g_signal_connect (priv->session, "on-ssrc-sdes", (GCallback) on_ssrc_sdes,
- stream);
- g_signal_connect (priv->session, "on-ssrc-active",
- (GCallback) on_ssrc_active, stream);
- g_signal_connect (priv->session, "on-bye-ssrc", (GCallback) on_bye_ssrc,
- stream);
- g_signal_connect (priv->session, "on-bye-timeout",
- (GCallback) on_bye_timeout, stream);
- g_signal_connect (priv->session, "on-timeout", (GCallback) on_timeout,
- stream);
-
- /* signal for sender ssrc */
- g_signal_connect (priv->session, "on-new-sender-ssrc",
- (GCallback) on_new_sender_ssrc, stream);
- g_signal_connect (priv->session, "on-sender-ssrc-active",
- (GCallback) on_sender_ssrc_active, stream);
+ if (is_udp)
+ /* update the dscp qos field in the sinks */
+ update_dscp_qos (stream);
for (i = 0; i < 2; i++) {
GstPad *teepad, *queuepad;
@@ -2261,7 +2155,6 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
* and link the udpsink (for UDP) or appsink (for TCP) directly to
* the session.
*/
-
/* Only link the RTP send src if we're going to send RTP, link
* the RTCP send src always */
if (priv->srcpad || i == 1) {
@@ -2347,6 +2240,37 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
}
}
+ /* check if we need to set to a special state */
+ if (state != GST_STATE_NULL) {
+ if (priv->udpsink[i] && (priv->srcpad || i == 1))
+ gst_element_set_state (priv->udpsink[i], state);
+ if (priv->appsink[i] && (priv->srcpad || i == 1))
+ gst_element_set_state (priv->appsink[i], state);
+ if (priv->appqueue[i] && (priv->srcpad || i == 1))
+ gst_element_set_state (priv->appqueue[i], state);
+ if (priv->udpqueue[i] && (priv->srcpad || i == 1))
+ gst_element_set_state (priv->udpqueue[i], state);
+ if (priv->tee[i] && (priv->srcpad || i == 1))
+ gst_element_set_state (priv->tee[i], state);
+ }
+ }
+}
+
+/* must be called with lock */
+static void
+create_receiver_part (GstRTSPStream * stream, GstBin * bin,
+ GstState state)
+{
+ GstRTSPStreamPrivate *priv;
+ GstPad *pad, *selpad;
+ gboolean is_tcp;
+ gint i;
+
+ priv = stream->priv;
+
+ is_tcp = priv->protocols & GST_RTSP_LOWER_TRANS_TCP;
+
+ for (i = 0; i < 2; i++) {
/* Only connect recv RTP sink if we expect to receive RTP. Connect recv
* RTCP sink always */
if (priv->sinkpad || i == 1) {
@@ -2421,22 +2345,137 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
/* check if we need to set to a special state */
if (state != GST_STATE_NULL) {
- if (priv->udpsink[i] && (priv->srcpad || i == 1))
- gst_element_set_state (priv->udpsink[i], state);
- if (priv->appsink[i] && (priv->srcpad || i == 1))
- gst_element_set_state (priv->appsink[i], state);
- if (priv->appqueue[i] && (priv->srcpad || i == 1))
- gst_element_set_state (priv->appqueue[i], state);
- if (priv->udpqueue[i] && (priv->srcpad || i == 1))
- gst_element_set_state (priv->udpqueue[i], state);
- if (priv->tee[i] && (priv->srcpad || i == 1))
- gst_element_set_state (priv->tee[i], state);
if (priv->funnel[i] && (priv->sinkpad || i == 1))
gst_element_set_state (priv->funnel[i], state);
if (priv->appsrc[i] && (priv->sinkpad || i == 1))
gst_element_set_state (priv->appsrc[i], state);
}
}
+}
+
+/**
+ * gst_rtsp_stream_join_bin:
+ * @stream: a #GstRTSPStream
+ * @bin: (transfer none): a #GstBin to join
+ * @rtpbin: (transfer none): a rtpbin element in @bin
+ * @state: the target state of the new elements
+ *
+ * Join the #GstBin @bin that contains the element @rtpbin.
+ *
+ * @stream will link to @rtpbin, which must be inside @bin. The elements
+ * added to @bin will be set to the state given in @state.
+ *
+ * Returns: %TRUE on success.
+ */
+gboolean
+gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
+ GstElement * rtpbin, GstState state)
+{
+ GstRTSPStreamPrivate *priv;
+ guint idx;
+ gchar *name;
+ GstPadLinkReturn ret;
+ gboolean is_udp;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
+ g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
+ g_return_val_if_fail (GST_IS_ELEMENT (rtpbin), FALSE);
+
+ priv = stream->priv;
+
+ g_mutex_lock (&priv->lock);
+ if (priv->is_joined)
+ goto was_joined;
+
+ /* create a session with the same index as the stream */
+ idx = priv->idx;
+
+ GST_INFO ("stream %p joining bin as session %u", stream, idx);
+
+ is_udp = ((priv->protocols & GST_RTSP_LOWER_TRANS_UDP) ||
+ (priv->protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST));
+
+ if (is_udp && !alloc_ports (stream))
+ goto no_ports;
+
+ if (priv->profiles & GST_RTSP_PROFILE_SAVP
+ || priv->profiles & GST_RTSP_PROFILE_SAVPF) {
+ /* For SRTP */
+ g_signal_connect (rtpbin, "request-rtp-encoder",
+ (GCallback) request_rtp_encoder, stream);
+ g_signal_connect (rtpbin, "request-rtcp-encoder",
+ (GCallback) request_rtcp_encoder, stream);
+ g_signal_connect (rtpbin, "request-rtp-decoder",
+ (GCallback) request_rtp_rtcp_decoder, stream);
+ g_signal_connect (rtpbin, "request-rtcp-decoder",
+ (GCallback) request_rtp_rtcp_decoder, stream);
+ }
+
+ if (priv->sinkpad) {
+ g_signal_connect (rtpbin, "request-pt-map",
+ (GCallback) request_pt_map, stream);
+ }
+
+ /* get pads from the RTP session element for sending and receiving
+ * RTP/RTCP*/
+ if (priv->srcpad) {
+ /* get a pad for sending RTP */
+ name = g_strdup_printf ("send_rtp_sink_%u", idx);
+ priv->send_rtp_sink = gst_element_get_request_pad (rtpbin, name);
+ g_free (name);
+
+ /* link the RTP pad to the session manager, it should not really fail unless
+ * this is not really an RTP pad */
+ ret = gst_pad_link (priv->srcpad, priv->send_rtp_sink);
+ if (ret != GST_PAD_LINK_OK)
+ goto link_failed;
+
+ name = g_strdup_printf ("send_rtp_src_%u", idx);
+ priv->send_src[0] = gst_element_get_static_pad (rtpbin, name);
+ g_free (name);
+ } else {
+ /* Need to connect our sinkpad from here */
+ g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added, stream);
+ /* EOS */
+ g_signal_connect (rtpbin, "on-npt-stop", (GCallback) on_npt_stop, stream);
+
+ name = g_strdup_printf ("recv_rtp_sink_%u", idx);
+ priv->recv_sink[0] = gst_element_get_request_pad (rtpbin, name);
+ g_free (name);
+ }
+
+ name = g_strdup_printf ("send_rtcp_src_%u", idx);
+ priv->send_src[1] = gst_element_get_request_pad (rtpbin, name);
+ g_free (name);
+ name = g_strdup_printf ("recv_rtcp_sink_%u", idx);
+ priv->recv_sink[1] = gst_element_get_request_pad (rtpbin, name);
+ g_free (name);
+
+ /* get the session */
+ g_signal_emit_by_name (rtpbin, "get-internal-session", idx, &priv->session);
+
+ g_signal_connect (priv->session, "on-new-ssrc", (GCallback) on_new_ssrc,
+ stream);
+ g_signal_connect (priv->session, "on-ssrc-sdes", (GCallback) on_ssrc_sdes,
+ stream);
+ g_signal_connect (priv->session, "on-ssrc-active",
+ (GCallback) on_ssrc_active, stream);
+ g_signal_connect (priv->session, "on-bye-ssrc", (GCallback) on_bye_ssrc,
+ stream);
+ g_signal_connect (priv->session, "on-bye-timeout",
+ (GCallback) on_bye_timeout, stream);
+ g_signal_connect (priv->session, "on-timeout", (GCallback) on_timeout,
+ stream);
+
+ /* signal for sender ssrc */
+ g_signal_connect (priv->session, "on-new-sender-ssrc",
+ (GCallback) on_new_sender_ssrc, stream);
+ g_signal_connect (priv->session, "on-sender-ssrc-active",
+ (GCallback) on_sender_ssrc_active, stream);
+
+ create_sender_part (stream, bin, state);
+
+ create_receiver_part (stream, bin, state);
if (priv->srcpad) {
/* be notified of caps changes */