Add support for live streams
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 6 Mar 2009 18:34:14 +0000 (19:34 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 6 Mar 2009 18:34:14 +0000 (19:34 +0100)
Add support for live streams and ranges
Start on handling TCP data transfer.

examples/test-readme.c
gst/rtsp-server/rtsp-client.c
gst/rtsp-server/rtsp-media.c
gst/rtsp-server/rtsp-media.h

index 880b6d2..e23c55a 100644 (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);
index 585b5d8..811ae03 100644 (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 */
index 3b3d241..6284612 100644 (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);
+
+  oldcaps = stream->caps;
+  stream->caps = newcaps;
 
-  capsstr = gst_caps_to_string (stream->caps);
+  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);
index e613925..f746be6 100644 (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;