rtsp: Handle the blocksize parameter
authorOgnyan Tonchev <ognyan@axis.com>
Tue, 3 Jul 2012 11:26:30 +0000 (13:26 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 10 Jul 2012 09:26:01 +0000 (11:26 +0200)
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=679325

gst/rtsp-server/rtsp-client.c
gst/rtsp-server/rtsp-media.c
gst/rtsp-server/rtsp-media.h

index c1194da..57d1441 100644 (file)
@@ -818,6 +818,31 @@ do_keepalive (GstRTSPSession * session)
 }
 
 static gboolean
+handle_blocksize (GstRTSPMedia * media, GstRTSPMessage * request)
+{
+  gchar *blocksize_str;
+  gboolean ret = TRUE;
+
+  if (gst_rtsp_message_get_header (request, GST_RTSP_HDR_BLOCKSIZE,
+      &blocksize_str, 0) == GST_RTSP_OK) {
+    guint64 blocksize;
+    gchar *end;
+
+    blocksize = g_ascii_strtoull (blocksize_str, &end, 10);
+    if (end == blocksize_str) {
+      GST_ERROR ("failed to parse blocksize");
+      ret = FALSE;
+    } else {
+      if (blocksize > G_MAXUINT)
+        blocksize = G_MAXUINT;
+      gst_rtsp_media_handle_mtu (media, (guint)blocksize);
+    }
+  }
+
+  return ret;
+}
+
+static gboolean
 handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
 {
   GstRTSPResult res;
@@ -944,6 +969,9 @@ handle_setup_request (GstRTSPClient * client, GstRTSPClientState * state)
 
   state->sessmedia = media;
 
+  if (!handle_blocksize (media->media, state->request))
+    goto invalid_blocksize;
+
   /* we have a valid transport now, set the destination of the client. */
   g_free (ct->destination);
   if (ct->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
@@ -1015,6 +1043,13 @@ not_found:
     gst_rtsp_transport_free (ct);
     return FALSE;
   }
+invalid_blocksize:
+  {
+    send_generic_response (client, GST_RTSP_STS_BAD_REQUEST, state);
+    g_object_unref (session);
+    gst_rtsp_transport_free (ct);
+    return FALSE;
+  }
 no_stream:
   {
     send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
index 43290cf..18f2e85 100644 (file)
@@ -72,6 +72,7 @@ static gboolean default_handle_message (GstRTSPMedia * media,
     GstMessage * message);
 static gboolean default_unprepare (GstRTSPMedia * media);
 static void unlock_streams (GstRTSPMedia * media);
+static void default_handle_mtu (GstRTSPMedia * media, guint mtu);
 
 static guint gst_rtsp_media_signals[SIGNAL_LAST] = { 0 };
 
@@ -142,6 +143,7 @@ gst_rtsp_media_class_init (GstRTSPMediaClass * klass)
 
   klass->handle_message = default_handle_message;
   klass->unprepare = default_unprepare;
+  klass->handle_mtu = default_handle_mtu;
 
   ssrc_stream_map_key = g_quark_from_static_string ("GstRTSPServer.stream");
 }
@@ -2078,3 +2080,37 @@ gst_rtsp_media_remove_elements (GstRTSPMedia * media)
   gst_object_unref (media->pipeline);
   media->pipeline = NULL;
 }
+
+static void
+default_handle_mtu (GstRTSPMedia * media, guint mtu)
+{
+  gint i;
+
+  for (i = 0; i < media->streams->len; i++) {
+    GstRTSPMediaStream *stream;
+
+    GST_INFO ("Setting mtu %d for stream %d", mtu, i);
+
+    stream = g_array_index (media->streams, GstRTSPMediaStream *, i);
+
+    g_object_set (G_OBJECT (stream->payloader), "mtu", mtu, NULL);
+  }
+}
+
+/**
+ * gst_rtsp_media_handle_mtu:
+ * @media: a #GstRTSPMedia
+ * @mtu: the mtu
+ *
+ * Set maximum size of one RTP packet on the payloaders.
+ */
+void
+gst_rtsp_media_handle_mtu (GstRTSPMedia * media, guint mtu)
+{
+  GstRTSPMediaClass *klass;
+
+  klass = GST_RTSP_MEDIA_GET_CLASS (media);
+
+  if (klass->handle_mtu)
+    klass->handle_mtu (media, mtu);
+}
index e48b013..fb86a28 100644 (file)
@@ -238,6 +238,7 @@ struct _GstRTSPMedia {
  * @handle_message: handle a message
  * @unprepare: the default implementation sets the pipeline's state
  *             to GST_STATE_NULL.
+ * @handle_mtu: handle a mtu
  *
  * The RTSP media class
  */
@@ -252,6 +253,7 @@ struct _GstRTSPMediaClass {
   /* vmethods */
   gboolean     (*handle_message)  (GstRTSPMedia *media, GstMessage *message);
   gboolean     (*unprepare)       (GstRTSPMedia *media);
+  void         (*handle_mtu)      (GstRTSPMedia *media, guint mtu);
 
   /* signals */
   gboolean     (*prepared)        (GstRTSPMedia *media);
@@ -306,6 +308,8 @@ gboolean              gst_rtsp_media_set_state        (GstRTSPMedia *media, GstS
 
 void                  gst_rtsp_media_remove_elements  (GstRTSPMedia *media);
 
+void                  gst_rtsp_media_handle_mtu       (GstRTSPMedia *media, guint mtu);
+
 void                  gst_rtsp_media_trans_cleanup    (GstRTSPMediaTrans *trans);
 
 G_END_DECLS