From 4ca0b23a3fcf1a3ecb3559bd931e162ab5921cdc Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 26 Dec 2013 15:41:14 +0100 Subject: [PATCH] session-media: let the session-media make the RTPInfo Add method to create the RTPInfo for a stream-transport. Add method to create the RTPInfo for all stream-transports in a session-media. Use the session-media RTPInfo code in client. This allows us to refactor another method to link the TCP callbacks. --- gst/rtsp-server/rtsp-client.c | 89 +++++++++++++-------------------- gst/rtsp-server/rtsp-session-media.c | 68 +++++++++++++++++++++++++ gst/rtsp-server/rtsp-session-media.h | 2 + gst/rtsp-server/rtsp-stream-transport.c | 34 +++++++++++++ gst/rtsp-server/rtsp-stream-transport.h | 3 ++ 5 files changed, 143 insertions(+), 53 deletions(-) diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index e87a8de..1a1de6c 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -658,6 +658,32 @@ link_transport (GstRTSPClient * client, GstRTSPSession * session, } static void +link_session_transports (GstRTSPClient * client, GstRTSPSession * session, + GstRTSPSessionMedia * sessmedia) +{ + guint n_streams, i; + + n_streams = + gst_rtsp_media_n_streams (gst_rtsp_session_media_get_media (sessmedia)); + for (i = 0; i < n_streams; i++) { + GstRTSPStreamTransport *trans; + const GstRTSPTransport *tr; + + /* get the transport, if there is no transport configured, skip this stream */ + trans = gst_rtsp_session_media_get_transport (sessmedia, i); + if (trans == NULL) + continue; + + tr = gst_rtsp_stream_transport_get_transport (trans); + + if (tr->lower_transport == GST_RTSP_LOWER_TRANS_TCP) { + /* for TCP, link the stream to the TCP connection of the client */ + link_transport (client, session, trans); + } + } +} + +static void unlink_transport (GstRTSPClient * client, GstRTSPSession * session, GstRTSPStreamTransport * trans) { @@ -1042,14 +1068,12 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) GstRTSPMedia *media; GstRTSPStatusCode code; GstRTSPUrl *uri; - GString *rtpinfo; - guint n_streams, i, infocount; gchar *str; GstRTSPTimeRange *range; GstRTSPResult res; GstRTSPState rtspstate; GstRTSPRangeUnit unit = GST_RTSP_RANGE_NPT; - gchar *path; + gchar *path, *rtpinfo; gint matched; if (!(session = ctx->session)) @@ -1069,6 +1093,8 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) if (path[matched] != '\0') goto no_aggregate; + g_free (path); + ctx->sessmedia = sessmedia; ctx->media = media = gst_rtsp_session_media_get_media (sessmedia); @@ -1092,49 +1118,11 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) } } - /* grab RTPInfo from the payloaders now */ - rtpinfo = g_string_new (""); + /* link the all TCP callbacks */ + link_session_transports (client, session, sessmedia); - n_streams = gst_rtsp_media_n_streams (media); - for (i = 0, infocount = 0; i < n_streams; i++) { - GstRTSPStreamTransport *trans; - GstRTSPStream *stream; - const GstRTSPTransport *tr; - guint rtptime, seq; - - /* get the transport, if there is no transport configured, skip this stream */ - trans = gst_rtsp_session_media_get_transport (sessmedia, i); - if (trans == NULL) { - GST_INFO ("stream %d is not configured", i); - continue; - } - tr = gst_rtsp_stream_transport_get_transport (trans); - - if (tr->lower_transport == GST_RTSP_LOWER_TRANS_TCP) { - /* for TCP, link the stream to the TCP connection of the client */ - link_transport (client, session, trans); - } - - stream = gst_rtsp_stream_transport_get_stream (trans); - if (gst_rtsp_stream_get_rtpinfo (stream, &rtptime, &seq)) { - const GstRTSPUrl *url; - gchar *url_str; - - if (infocount > 0) - g_string_append (rtpinfo, ", "); - - url = gst_rtsp_stream_transport_get_url (trans); - url_str = gst_rtsp_url_get_request_uri (url); - g_string_append_printf (rtpinfo, "url=%s;seq=%u;rtptime=%u", - url_str, seq, rtptime); - g_free (url_str); - - infocount++; - } else { - GST_WARNING ("RTP-Info cannot be determined for stream %d", i); - } - } - g_free (path); + /* grab RTPInfo from the media now */ + rtpinfo = gst_rtsp_session_media_get_rtpinfo (sessmedia); /* construct the response now */ code = GST_RTSP_STS_OK; @@ -1142,12 +1130,9 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx) gst_rtsp_status_as_text (code), ctx->request); /* add the RTP-Info header */ - if (infocount > 0) { - str = g_string_free (rtpinfo, FALSE); - gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_RTP_INFO, str); - } else { - g_string_free (rtpinfo, TRUE); - } + if (rtpinfo) + gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_RTP_INFO, + rtpinfo); /* add the range */ str = gst_rtsp_media_get_range_string (media, TRUE, unit); @@ -1197,14 +1182,12 @@ invalid_state: GST_ERROR ("client %p: not PLAYING or READY", client); send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE, ctx); - g_free (path); return FALSE; } unsuspend_failed: { GST_ERROR ("client %p: unsuspend failed", client); send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx); - g_free (path); return FALSE; } } diff --git a/gst/rtsp-server/rtsp-session-media.c b/gst/rtsp-server/rtsp-session-media.c index d042ea0..e49e426 100644 --- a/gst/rtsp-server/rtsp-session-media.c +++ b/gst/rtsp-server/rtsp-session-media.c @@ -233,6 +233,74 @@ gst_rtsp_session_media_get_base_time (GstRTSPSessionMedia * media) } /** + * gst_rtsp_session_media_get_rtpinfo: + * @media: a #GstRTSPSessionMedia + * + * Retrieve the RTP-Info header string for all streams in @media + * with configured transports. + * + * Returns: (transfer full): The RTP-Info as a string, g_free() + * after usage. + */ +gchar * +gst_rtsp_session_media_get_rtpinfo (GstRTSPSessionMedia * media) +{ + GstRTSPSessionMediaPrivate *priv; + GString *rtpinfo = NULL; + GstRTSPStreamTransport *transport; + guint i, n_streams; + + g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), NULL); + + priv = media->priv; + g_mutex_lock (&priv->lock); + + n_streams = priv->transports->len; + + GST_LOG_OBJECT (media, "collecting RTP info for %d transports", n_streams); + + for (i = 0; i < n_streams; i++) { + gchar *stream_rtpinfo; + + transport = g_ptr_array_index (priv->transports, i); + if (transport == NULL) { + GST_DEBUG_OBJECT (media, "ignoring unconfigured transport %d", i); + continue; + } + + stream_rtpinfo = gst_rtsp_stream_transport_get_rtpinfo (transport); + if (stream_rtpinfo == NULL) + goto stream_rtpinfo_missing; + + if (rtpinfo == NULL) + rtpinfo = g_string_new (""); + else + g_string_append (rtpinfo, ", "); + + g_string_append (rtpinfo, stream_rtpinfo); + g_free (stream_rtpinfo); + } + + if (rtpinfo == NULL) { + GST_INFO_OBJECT (media, "no transports configured, RTP info is empty"); + rtpinfo = g_string_new (""); + } + + g_mutex_unlock (&priv->lock); + + return g_string_free (rtpinfo, FALSE); + + /* ERRORS */ +stream_rtpinfo_missing: + { + g_mutex_unlock (&priv->lock); + g_string_free (rtpinfo, TRUE); + GST_ERROR_OBJECT (media, "could not get stream %d rtpinfo", i); + return NULL; + } +} + +/** * gst_rtsp_session_media_set_transport: * @media: a #GstRTSPSessionMedia * @stream: a #GstRTSPStream diff --git a/gst/rtsp-server/rtsp-session-media.h b/gst/rtsp-server/rtsp-session-media.h index 0b7c8c8..e2af5ad 100644 --- a/gst/rtsp-server/rtsp-session-media.h +++ b/gst/rtsp-server/rtsp-session-media.h @@ -90,6 +90,8 @@ GstRTSPStreamTransport * gst_rtsp_session_media_get_transport (GstRTSPSessionMe gboolean gst_rtsp_session_media_alloc_channels (GstRTSPSessionMedia *media, GstRTSPRange *range); +gchar * gst_rtsp_session_media_get_rtpinfo (GstRTSPSessionMedia * media); + G_END_DECLS #endif /* __GST_RTSP_SESSION_MEDIA_H__ */ diff --git a/gst/rtsp-server/rtsp-stream-transport.c b/gst/rtsp-server/rtsp-stream-transport.c index 90e6310..cf8eb64 100644 --- a/gst/rtsp-server/rtsp-stream-transport.c +++ b/gst/rtsp-server/rtsp-stream-transport.c @@ -310,6 +310,40 @@ gst_rtsp_stream_transport_get_url (GstRTSPStreamTransport * trans) return trans->priv->url; } + /** + * gst_rtsp_stream_transport_get_rtpinfo: + * @trans: a #GstRTSPStreamTransport + * + * Get the RTPInfo string for @trans. + * + * Returns: the RTPInfo string for @trans. g_free() after + * usage. + */ +gchar * +gst_rtsp_stream_transport_get_rtpinfo (GstRTSPStreamTransport * trans) +{ + GstRTSPStreamTransportPrivate *priv; + gchar *url_str; + GString *rtpinfo; + guint rtptime, seq; + + g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL); + + priv = trans->priv; + + if (!gst_rtsp_stream_get_rtpinfo (priv->stream, &rtptime, &seq)) + return NULL; + + rtpinfo = g_string_new (""); + + url_str = gst_rtsp_url_get_request_uri (trans->priv->url); + g_string_append_printf (rtpinfo, "url=%s;seq=%u;rtptime=%u", + url_str, seq, rtptime); + g_free (url_str); + + return g_string_free (rtpinfo, FALSE); +} + /** * gst_rtsp_stream_transport_set_active: * @trans: a #GstRTSPStreamTransport diff --git a/gst/rtsp-server/rtsp-stream-transport.h b/gst/rtsp-server/rtsp-stream-transport.h index bc02df8..3a5e579 100644 --- a/gst/rtsp-server/rtsp-stream-transport.h +++ b/gst/rtsp-server/rtsp-stream-transport.h @@ -99,6 +99,9 @@ void gst_rtsp_stream_transport_set_url (GstRTSPStreamT const GstRTSPUrl * url); const GstRTSPUrl * gst_rtsp_stream_transport_get_url (GstRTSPStreamTransport *trans); + +gchar * gst_rtsp_stream_transport_get_rtpinfo (GstRTSPStreamTransport *trans); + void gst_rtsp_stream_transport_set_callbacks (GstRTSPStreamTransport *trans, GstRTSPSendFunc send_rtp, GstRTSPSendFunc send_rtcp, -- 2.7.4