rtsp-server: add support for buffer lists
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 29 Dec 2010 15:26:41 +0000 (16:26 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 29 Dec 2010 15:26:41 +0000 (16:26 +0100)
Add support for sending bufferlists received from appsink.

Fixes #635832

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

index b352378..2c168bd 100644 (file)
@@ -350,13 +350,34 @@ do_send_data (GstBuffer * buffer, guint8 channel, GstRTSPClient * client)
   return TRUE;
 }
 
+static gboolean
+do_send_data_list (GstBufferList * blist, guint8 channel,
+    GstRTSPClient * client)
+{
+  GstBufferListIterator *it;
+
+  it = gst_buffer_list_iterate (blist);
+  while (gst_buffer_list_iterator_next_group (it)) {
+    GstBuffer *group = gst_buffer_list_iterator_merge_group (it);
+
+    if (group == NULL)
+      continue;
+
+    do_send_data (group, channel, client);
+  }
+  gst_buffer_list_iterator_free (it);
+
+  return TRUE;
+}
+
 static void
 link_stream (GstRTSPClient * client, GstRTSPSession * session,
     GstRTSPSessionStream * stream)
 {
   GST_DEBUG ("client %p: linking stream %p", client, stream);
   gst_rtsp_session_stream_set_callbacks (stream, (GstRTSPSendFunc) do_send_data,
-      (GstRTSPSendFunc) do_send_data, client, NULL);
+      (GstRTSPSendFunc) do_send_data, (GstRTSPSendListFunc) do_send_data_list,
+      (GstRTSPSendListFunc) do_send_data_list, client, NULL);
   client->streams = g_list_prepend (client->streams, stream);
   /* make sure our session can't expire */
   gst_rtsp_session_prevent_expire (session);
@@ -367,7 +388,8 @@ unlink_stream (GstRTSPClient * client, GstRTSPSession * session,
     GstRTSPSessionStream * stream)
 {
   GST_DEBUG ("client %p: unlinking stream %p", client, stream);
-  gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL);
+  gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL, NULL,
+      NULL);
   client->streams = g_list_remove (client->streams, stream);
   /* our session can now expire */
   gst_rtsp_session_allow_expire (session);
index 21dfa45..8922d42 100644 (file)
@@ -1108,10 +1108,42 @@ handle_new_buffer (GstAppSink * sink, gpointer user_data)
   return GST_FLOW_OK;
 }
 
+static GstFlowReturn
+handle_new_buffer_list (GstAppSink * sink, gpointer user_data)
+{
+  GList *walk;
+  GstBufferList *blist;
+  GstRTSPMediaStream *stream;
+
+  blist = gst_app_sink_pull_buffer_list (sink);
+  if (!blist)
+    return GST_FLOW_OK;
+
+  stream = (GstRTSPMediaStream *) user_data;
+
+  for (walk = stream->transports; walk; walk = g_list_next (walk)) {
+    GstRTSPMediaTrans *tr = (GstRTSPMediaTrans *) walk->data;
+
+    if (GST_ELEMENT_CAST (sink) == stream->appsink[0]) {
+      if (tr->send_rtp_list)
+        tr->send_rtp_list (blist, tr->transport->interleaved.min,
+            tr->user_data);
+    } else {
+      if (tr->send_rtcp_list)
+        tr->send_rtcp_list (blist, tr->transport->interleaved.max,
+            tr->user_data);
+    }
+  }
+  gst_buffer_list_unref (blist);
+
+  return GST_FLOW_OK;
+}
+
 static GstAppSinkCallbacks sink_cb = {
   NULL,                         /* not interested in EOS */
   NULL,                         /* not interested in preroll buffers */
-  handle_new_buffer
+  handle_new_buffer,
+  handle_new_buffer_list
 };
 
 /* prepare the pipeline objects to handle @stream in @media */
index 2c83f76..c5208e9 100644 (file)
@@ -42,6 +42,7 @@ typedef struct _GstRTSPMediaClass GstRTSPMediaClass;
 typedef struct _GstRTSPMediaTrans GstRTSPMediaTrans;
 
 typedef gboolean (*GstRTSPSendFunc)      (GstBuffer *buffer, guint8 channel, gpointer user_data);
+typedef gboolean (*GstRTSPSendListFunc)  (GstBufferList *blist, guint8 channel, gpointer user_data);
 typedef void     (*GstRTSPKeepAliveFunc) (gpointer user_data);
 
 /**
@@ -66,6 +67,8 @@ struct _GstRTSPMediaTrans {
 
   GstRTSPSendFunc      send_rtp;
   GstRTSPSendFunc      send_rtcp;
+  GstRTSPSendListFunc  send_rtp_list;
+  GstRTSPSendListFunc  send_rtcp_list;
   gpointer             user_data;
   GDestroyNotify       notify;
 
index e87f096..8d507e5 100644 (file)
@@ -79,7 +79,8 @@ gst_rtsp_session_free_stream (GstRTSPSessionStream * stream)
   GST_INFO ("free session stream %p", stream);
 
   /* remove callbacks now */
-  gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL);
+  gst_rtsp_session_stream_set_callbacks (stream, NULL, NULL, NULL, NULL, NULL,
+      NULL);
   gst_rtsp_session_stream_set_keepalive (stream, NULL, NULL, NULL);
 
   gst_rtsp_media_trans_cleanup (&stream->trans);
@@ -549,6 +550,8 @@ gst_rtsp_session_stream_set_transport (GstRTSPSessionStream * stream,
  * @stream: a #GstRTSPSessionStream
  * @send_rtp: a callback called when RTP should be sent
  * @send_rtcp: a callback called when RTCP should be sent
+ * @send_rtp_list: a callback called when RTP should be sent
+ * @send_rtcp_list: a callback called when RTCP should be sent
  * @user_data: user data passed to callbacks
  * @notify: called with the user_data when no longer needed.
  *
@@ -557,11 +560,14 @@ gst_rtsp_session_stream_set_transport (GstRTSPSessionStream * stream,
  */
 void
 gst_rtsp_session_stream_set_callbacks (GstRTSPSessionStream * stream,
-    GstRTSPSendFunc send_rtp, GstRTSPSendFunc send_rtcp, gpointer user_data,
-    GDestroyNotify notify)
+    GstRTSPSendFunc send_rtp, GstRTSPSendFunc send_rtcp,
+    GstRTSPSendListFunc send_rtp_list, GstRTSPSendListFunc send_rtcp_list,
+    gpointer user_data, GDestroyNotify notify)
 {
   stream->trans.send_rtp = send_rtp;
   stream->trans.send_rtcp = send_rtcp;
+  stream->trans.send_rtp_list = send_rtp_list;
+  stream->trans.send_rtcp_list = send_rtcp_list;
   if (stream->trans.notify)
     stream->trans.notify (stream->trans.user_data);
   stream->trans.user_data = user_data;
index cfd75c6..00bc3f3 100644 (file)
@@ -154,6 +154,8 @@ GstRTSPTransport *     gst_rtsp_session_stream_set_transport (GstRTSPSessionStre
 void                   gst_rtsp_session_stream_set_callbacks (GstRTSPSessionStream *stream,
                                                               GstRTSPSendFunc send_rtp,
                                                               GstRTSPSendFunc send_rtcp,
+                                                              GstRTSPSendListFunc send_rtp_list,
+                                                              GstRTSPSendListFunc send_rtcp_list,
                                                               gpointer user_data,
                                                               GDestroyNotify  notify);
 void                   gst_rtsp_session_stream_set_keepalive (GstRTSPSessionStream *stream,