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.
This commit is contained in:
Wim Taymans 2013-12-26 15:41:14 +01:00
parent dd4c04f1b8
commit 4ca0b23a3f
5 changed files with 143 additions and 53 deletions

View file

@ -657,6 +657,32 @@ link_transport (GstRTSPClient * client, GstRTSPSession * session,
gst_rtsp_session_prevent_expire (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;
}
}

View file

@ -232,6 +232,74 @@ gst_rtsp_session_media_get_base_time (GstRTSPSessionMedia * media)
return gst_rtsp_media_get_base_time (media->priv->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

View file

@ -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__ */

View file

@ -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

View file

@ -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,