stream: fix docs for recently-added get/set_buffer_size API
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-stream.c
index abdeeaa..4417c43 100644 (file)
@@ -55,6 +55,8 @@
 #include <gst/app/gstappsrc.h>
 #include <gst/app/gstappsink.h>
 
+#include <gst/rtp/gstrtpbuffer.h>
+
 #include "rtsp-stream.h"
 
 #define GST_RTSP_STREAM_GET_PRIVATE(obj)  \
@@ -1387,8 +1389,8 @@ gst_rtsp_stream_set_retransmission_time (GstRTSPStream * stream,
 }
 
 /**
- * gst_rtsp_media_get_retransmission_time:
- * @media: a #GstRTSPMedia
+ * gst_rtsp_stream_get_retransmission_time:
+ * @stream: a #GstRTSPStream
  *
  * Get the amount of time to store retransmission data.
  *
@@ -1408,6 +1410,13 @@ gst_rtsp_stream_get_retransmission_time (GstRTSPStream * stream)
   return ret;
 }
 
+/**
+ * gst_rtsp_stream_set_retransmission_pt:
+ * @stream: a #GstRTSPStream
+ * @rtx_pt: a #guint
+ *
+ * Set the payload type (pt) for retransmission of this stream.
+ */
 void
 gst_rtsp_stream_set_retransmission_pt (GstRTSPStream * stream, guint rtx_pt)
 {
@@ -1429,6 +1438,14 @@ gst_rtsp_stream_set_retransmission_pt (GstRTSPStream * stream, guint rtx_pt)
   g_mutex_unlock (&stream->priv->lock);
 }
 
+/**
+ * gst_rtsp_stream_get_retransmission_pt:
+ * @stream: a #GstRTSPStream
+ *
+ * Get the payload-type used for retransmission of this stream
+ *
+ * Returns: The retransmission PT.
+ */
 guint
 gst_rtsp_stream_get_retransmission_pt (GstRTSPStream * stream)
 {
@@ -1443,6 +1460,46 @@ gst_rtsp_stream_get_retransmission_pt (GstRTSPStream * stream)
   return rtx_pt;
 }
 
+/**
+ * gst_rtsp_stream_set_buffer_size:
+ * @stream: a #GstRTSPStream
+ * @size: the buffer size
+ *
+ * Set the size of the UDP transmission buffer (in bytes)
+ * Needs to be set before the stream is joined to a bin.
+ *
+ * Since: 1.6
+ */
+void
+gst_rtsp_stream_set_buffer_size (GstRTSPStream * stream, guint size)
+{
+  g_mutex_lock (&stream->priv->lock);
+  stream->priv->buffer_size = size;
+  g_mutex_unlock (&stream->priv->lock);
+}
+
+/**
+ * gst_rtsp_stream_get_buffer_size:
+ * @stream: a #GstRTSPStream
+ *
+ * Get the size of the UDP transmission buffer (in bytes)
+ *
+ * Returns: the size of the UDP TX buffer
+ *
+ * Since: 1.6
+ */
+guint
+gst_rtsp_stream_get_buffer_size (GstRTSPStream * stream)
+{
+  guint buffer_size;
+
+  g_mutex_lock (&stream->priv->lock);
+  buffer_size = stream->priv->buffer_size;
+  g_mutex_unlock (&stream->priv->lock);
+
+  return buffer_size;
+}
+
 /* executed from streaming thread */
 static void
 caps_notify (GstPad * pad, GParamSpec * unused, GstRTSPStream * stream)
@@ -1815,8 +1872,19 @@ request_rtp_rtcp_decoder (GstElement * rtpbin, guint session,
   return gst_object_ref (priv->srtpdec);
 }
 
-static GstElement *
-request_aux_sender (GstElement * rtpbin, guint sessid, GstRTSPStream * stream)
+/**
+ * gst_rtsp_stream_request_aux_sender:
+ * @stream: a #GstRTSPStream
+ * @sessid: the session id
+ *
+ * Creating a rtxsend bin
+ *
+ * Returns: (transfer full): a #GstElement.
+ *
+ * Since: 1.6
+ */
+GstElement *
+gst_rtsp_stream_request_aux_sender (GstRTSPStream * stream, guint sessid)
 {
   GstElement *bin;
   GstPad *pad;
@@ -1825,6 +1893,8 @@ request_aux_sender (GstElement * rtpbin, guint sessid, GstRTSPStream * stream)
   guint pt, rtx_pt;
   gchar *pt_s;
 
+  g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
+
   pt = gst_rtsp_stream_get_pt (stream);
   pt_s = g_strdup_printf ("%u", pt);
   rtx_pt = stream->priv->rtx_pt;
@@ -2010,11 +2080,6 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
         (GCallback) request_rtp_rtcp_decoder, stream);
   }
 
-  if (priv->rtx_time > 0 && priv->srcpad) {
-    /* enable retransmission by setting rtprtxsend as the "aux" element of rtpbin */
-    g_signal_connect (rtpbin, "request-aux-sender",
-        (GCallback) request_aux_sender, stream);
-  }
   if (priv->sinkpad) {
     g_signal_connect (rtpbin, "request-pt-map",
         (GCallback) request_pt_map, stream);
@@ -2074,14 +2139,14 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
     GstPad *teepad, *queuepad;
     /* For the sender we create this bit of pipeline for both
      * RTP and RTCP. Sync and preroll are enabled on udpsink so
-     * we need to add a queue before appsink to make the pipeline
-     * not block. For the TCP case, we want to pump data to the
-     * client as fast as possible anyway.
+     * we need to add a queue before appsink and udpsink to make
+     * the pipeline not block. For the TCP case, we want to pump
+     * data to the client as fast as possible.
      *
-     * .--------.      .-----.    .---------.
-     * | rtpbin |      | tee |    | udpsink |
-     * |       send->sink   src->sink       |
-     * '--------'      |     |    '---------'
+     * .--------.      .-----.    .---------.    .---------.
+     * | rtpbin |      | tee |    |  queue  |    | udpsink |
+     * |       send->sink   src->sink      src->sink       |
+     * '--------'      |     |    '---------'    '---------'
      *                 |     |    .---------.    .---------.
      *                 |     |    |  queue  |    | appsink |
      *                 |    src->sink      src->sink       |
@@ -2105,6 +2170,8 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
       gst_object_unref (pad);
 
       priv->udpqueue[i] = gst_element_factory_make ("queue", NULL);
+      g_object_set (priv->udpqueue[i], "max-size-buffers",
+          1, "max-size-bytes", 0, "max-size-time", G_GINT64_CONSTANT (0), NULL);
       gst_bin_add (bin, priv->udpqueue[i]);
       /* link tee to udpqueue */
       teepad = gst_element_get_request_pad (priv->tee[i], "src_%u");
@@ -2120,6 +2187,8 @@ gst_rtsp_stream_join_bin (GstRTSPStream * stream, GstBin * bin,
 
       /* make queue */
       priv->appqueue[i] = gst_element_factory_make ("queue", NULL);
+      g_object_set (priv->appqueue[i], "max-size-buffers",
+          1, "max-size-bytes", 0, "max-size-time", G_GINT64_CONSTANT (0), NULL);
       gst_bin_add (bin, priv->appqueue[i]);
       /* and link to tee */
       teepad = gst_element_get_request_pad (priv->tee[i], "src_%u");
@@ -2457,6 +2526,62 @@ gst_rtsp_stream_get_rtpinfo (GstRTSPStream * stream,
 
   g_mutex_lock (&priv->lock);
 
+  /* First try to extract the information from the last buffer on the sinks.
+   * This will have a more accurate sequence number and timestamp, as between
+   * the payloader and the sink there can be some queues
+   */
+  if (priv->udpsink[0] || priv->appsink[0]) {
+    GstSample *last_sample;
+
+    if (priv->udpsink[0])
+      g_object_get (priv->udpsink[0], "last-sample", &last_sample, NULL);
+    else
+      g_object_get (priv->appsink[0], "last-sample", &last_sample, NULL);
+
+    if (last_sample) {
+      GstCaps *caps;
+      GstBuffer *buffer;
+      GstSegment *segment;
+      GstRTPBuffer rtp_buffer = GST_RTP_BUFFER_INIT;
+
+      caps = gst_sample_get_caps (last_sample);
+      buffer = gst_sample_get_buffer (last_sample);
+      segment = gst_sample_get_segment (last_sample);
+
+      if (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp_buffer)) {
+        if (seq) {
+          *seq = gst_rtp_buffer_get_seq (&rtp_buffer);
+        }
+
+        if (rtptime) {
+          *rtptime = gst_rtp_buffer_get_timestamp (&rtp_buffer);
+        }
+
+        gst_rtp_buffer_unmap (&rtp_buffer);
+
+        if (running_time) {
+          *running_time =
+              gst_segment_to_running_time (segment, GST_FORMAT_TIME,
+              GST_BUFFER_TIMESTAMP (buffer));
+        }
+
+        if (clock_rate) {
+          GstStructure *s = gst_caps_get_structure (caps, 0);
+
+          gst_structure_get_int (s, "clock-rate", (gint *) clock_rate);
+
+          if (*clock_rate == 0 && running_time)
+            *running_time = GST_CLOCK_TIME_NONE;
+        }
+        gst_sample_unref (last_sample);
+
+        goto done;
+      } else {
+        gst_sample_unref (last_sample);
+      }
+    }
+  }
+
   if (g_object_class_find_property (payobjclass, "stats")) {
     g_object_get (priv->payloader, "stats", &stats, NULL);
     if (stats == NULL)
@@ -2491,6 +2616,8 @@ gst_rtsp_stream_get_rtpinfo (GstRTSPStream * stream,
     if (running_time)
       *running_time = GST_CLOCK_TIME_NONE;
   }
+
+done:
   g_mutex_unlock (&priv->lock);
 
   return TRUE;