From de1ebbc21be20ab1ac6a6888e9830e084264e4d5 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 6 Mar 2009 19:34:14 +0100 Subject: [PATCH] Add support for live streams Add support for live streams and ranges Start on handling TCP data transfer. --- examples/test-readme.c | 2 +- gst/rtsp-server/rtsp-client.c | 8 +++- gst/rtsp-server/rtsp-media.c | 80 +++++++++++++++++++++++++---------- gst/rtsp-server/rtsp-media.h | 1 + 4 files changed, 66 insertions(+), 25 deletions(-) diff --git a/examples/test-readme.c b/examples/test-readme.c index 880b6d2102..e23c55ae76 100644 --- a/examples/test-readme.c +++ b/examples/test-readme.c @@ -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); diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index 585b5d83c8..811ae032e3 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -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 */ diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 3b3d241d20..6284612d74 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -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); diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h index e613925fbc..f746be6e43 100644 --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -91,6 +91,7 @@ struct _GstRTSPMediaStream { * sockets */ GstElement *udpsrc[2]; GstElement *udpsink[2]; + GstElement *appsrc[2]; /* server ports for sending/receiving */ GstRTSPRange server_port;