Add support for live streams

Add support for live streams and ranges
Start on handling TCP data transfer.
This commit is contained in:
Wim Taymans 2009-03-06 19:34:14 +01:00
parent cd3ed91553
commit de1ebbc21b
4 changed files with 66 additions and 25 deletions

View file

@ -46,7 +46,7 @@ main (int argc, char *argv[])
* element with pay%d names will be a stream */
factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_launch (factory,
"( videotestsrc ! x264enc ! rtph264pay name=pay0 pt=96 )");
"( videotestsrc is-live=1 ! x264enc ! rtph264pay name=pay0 pt=96 )");
/* attach the test factory to the /test url */
gst_rtsp_media_mapping_add_factory (mapping, "/test", factory);

View file

@ -542,7 +542,8 @@ handle_setup_request (GstRTSPClient *client, GstRTSPUrl *uri, GstRTSPSession *se
goto unsupported_transports;
supported = GST_RTSP_LOWER_TRANS_UDP |
GST_RTSP_LOWER_TRANS_UDP_MCAST;
GST_RTSP_LOWER_TRANS_UDP_MCAST |
GST_RTSP_LOWER_TRANS_TCP;
if (!(ct->lower_transport & supported))
goto unsupported_transports;
@ -594,6 +595,11 @@ handle_setup_request (GstRTSPClient *client, GstRTSPUrl *uri, GstRTSPSession *se
goto no_stream;
/* setup the server transport from the client transport */
if (ct->lower_transport == GST_RTSP_LOWER_TRANS_TCP) {
ct->port.min = gst_rtsp_connection_get_readfd (client->connection);
ct->port.max = gst_rtsp_connection_get_writefd (client->connection);
}
st = gst_rtsp_session_stream_set_transport (stream, ct);
/* serialize the server transport */

View file

@ -415,13 +415,18 @@ static void
caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPMediaStream * stream)
{
gchar *capsstr;
GstCaps *newcaps, *oldcaps;
if (stream->caps)
gst_caps_unref (stream->caps);
if ((stream->caps = GST_PAD_CAPS (pad)))
gst_caps_ref (stream->caps);
if ((newcaps = GST_PAD_CAPS (pad)))
gst_caps_ref (newcaps);
capsstr = gst_caps_to_string (stream->caps);
oldcaps = stream->caps;
stream->caps = newcaps;
if (oldcaps)
gst_caps_unref (oldcaps);
capsstr = gst_caps_to_string (newcaps);
g_message ("stream %p received caps %s", stream, capsstr);
g_free (capsstr);
}
@ -553,21 +558,30 @@ collect_media_stats (GstRTSPMedia *media)
gint64 duration;
media->range.unit = GST_RTSP_RANGE_NPT;
media->range.min.type = GST_RTSP_TIME_SECONDS;
media->range.min.seconds = 0.0;
/* get the duration */
format = GST_FORMAT_TIME;
if (!gst_element_query_duration (media->pipeline, &format, &duration))
duration = -1;
if (duration == -1) {
if (media->is_live) {
media->range.min.type = GST_RTSP_TIME_NOW;
media->range.min.seconds = -1;
media->range.max.type = GST_RTSP_TIME_END;
media->range.max.seconds = -1;
}
else {
media->range.max.type = GST_RTSP_TIME_SECONDS;
media->range.max.seconds = ((gdouble)duration) / GST_SECOND;
media->range.min.type = GST_RTSP_TIME_SECONDS;
media->range.min.seconds = 0.0;
/* get the duration */
format = GST_FORMAT_TIME;
if (!gst_element_query_duration (media->pipeline, &format, &duration))
duration = -1;
if (duration == -1) {
media->range.max.type = GST_RTSP_TIME_END;
media->range.max.seconds = -1;
}
else {
media->range.max.type = GST_RTSP_TIME_SECONDS;
media->range.max.seconds = ((gdouble)duration) / GST_SECOND;
}
}
}
@ -799,11 +813,21 @@ gst_rtsp_media_play (GstRTSPMedia *media, GArray *transports)
/* get the stream and add the destinations */
stream = gst_rtsp_media_get_stream (media, tr->idx);
switch (trans->lower_transport) {
case GST_RTSP_LOWER_TRANS_UDP:
case GST_RTSP_LOWER_TRANS_UDP_MCAST:
g_message ("adding %s:%d-%d", trans->destination, trans->client_port.min, trans->client_port.max);
g_message ("adding %s:%d-%d", trans->destination, trans->client_port.min, trans->client_port.max);
g_signal_emit_by_name (stream->udpsink[0], "add", trans->destination, trans->client_port.min, NULL);
g_signal_emit_by_name (stream->udpsink[1], "add", trans->destination, trans->client_port.max, NULL);
g_signal_emit_by_name (stream->udpsink[0], "add", trans->destination, trans->client_port.min, NULL);
g_signal_emit_by_name (stream->udpsink[1], "add", trans->destination, trans->client_port.max, NULL);
break;
case GST_RTSP_LOWER_TRANS_TCP:
g_message ("TCP transport not yet implemented");
break;
default:
g_message ("Unknown transport %d", trans->lower_transport);
break;
}
}
g_message ("playing media %p", media);
@ -852,12 +876,22 @@ gst_rtsp_media_pause (GstRTSPMedia *media, GArray *transports)
/* get the stream and add the destinations */
stream = gst_rtsp_media_get_stream (media, tr->idx);
g_message ("removing %s:%d-%d", trans->destination, trans->client_port.min, trans->client_port.max);
switch (trans->lower_transport) {
case GST_RTSP_LOWER_TRANS_UDP:
case GST_RTSP_LOWER_TRANS_UDP_MCAST:
g_message ("removing %s:%d-%d", trans->destination, trans->client_port.min, trans->client_port.max);
g_signal_emit_by_name (stream->udpsink[0], "remove", trans->destination, trans->client_port.min, NULL);
g_signal_emit_by_name (stream->udpsink[1], "remove", trans->destination, trans->client_port.max, NULL);
g_signal_emit_by_name (stream->udpsink[0], "remove", trans->destination, trans->client_port.min, NULL);
g_signal_emit_by_name (stream->udpsink[1], "remove", trans->destination, trans->client_port.max, NULL);
break;
case GST_RTSP_LOWER_TRANS_TCP:
g_message ("TCP transport not yet implemented");
break;
default:
g_message ("Unknown transport %d", trans->lower_transport);
break;
}
}
g_message ("pause media %p", media);
media->target_state = GST_STATE_PAUSED;
ret = gst_element_set_state (media->pipeline, GST_STATE_PAUSED);

View file

@ -91,6 +91,7 @@ struct _GstRTSPMediaStream {
* sockets */
GstElement *udpsrc[2];
GstElement *udpsink[2];
GstElement *appsrc[2];
/* server ports for sending/receiving */
GstRTSPRange server_port;