2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 * SECTION:rtsp-stream-transport
21 * @short_description: A media stream transport configuration
22 * @see_also: #GstRTSPStream, #GstRTSPSessionMedia
24 * The #GstRTSPStreamTransport configures the transport used by a
25 * #GstRTSPStream. It is usually manages by a #GstRTSPSessionMedia object.
27 * With gst_rtsp_stream_transport_set_callbacks(), callbacks can be configured
28 * to handle the RTP and RTCP packets from the stream, for example when they
29 * need to be sent over TCP.
31 * With gst_rtsp_stream_transport_set_active() the transports are added and
32 * removed from the stream.
34 * A #GstRTSPStream will call gst_rtsp_stream_transport_keep_alive() when RTCP
35 * is received from the client. It will also call
36 * gst_rtsp_stream_transport_set_timed_out() when a receiver has timed out.
38 * Last reviewed on 2013-07-16 (1.0.0)
44 #include "rtsp-stream-transport.h"
46 #define GST_RTSP_STREAM_TRANSPORT_GET_PRIVATE(obj) \
47 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_STREAM_TRANSPORT, GstRTSPStreamTransportPrivate))
49 struct _GstRTSPStreamTransportPrivate
51 GstRTSPStream *stream;
53 GstRTSPSendFunc send_rtp;
54 GstRTSPSendFunc send_rtcp;
56 GDestroyNotify notify;
58 GstRTSPKeepAliveFunc keep_alive;
59 gpointer ka_user_data;
60 GDestroyNotify ka_notify;
64 GstRTSPTransport *transport;
76 GST_DEBUG_CATEGORY_STATIC (rtsp_stream_transport_debug);
77 #define GST_CAT_DEFAULT rtsp_stream_transport_debug
79 static void gst_rtsp_stream_transport_finalize (GObject * obj);
81 G_DEFINE_TYPE (GstRTSPStreamTransport, gst_rtsp_stream_transport,
85 gst_rtsp_stream_transport_class_init (GstRTSPStreamTransportClass * klass)
87 GObjectClass *gobject_class;
89 g_type_class_add_private (klass, sizeof (GstRTSPStreamTransportPrivate));
91 gobject_class = G_OBJECT_CLASS (klass);
93 gobject_class->finalize = gst_rtsp_stream_transport_finalize;
95 GST_DEBUG_CATEGORY_INIT (rtsp_stream_transport_debug, "rtspmediatransport",
96 0, "GstRTSPStreamTransport");
100 gst_rtsp_stream_transport_init (GstRTSPStreamTransport * trans)
102 GstRTSPStreamTransportPrivate *priv =
103 GST_RTSP_STREAM_TRANSPORT_GET_PRIVATE (trans);
109 gst_rtsp_stream_transport_finalize (GObject * obj)
111 GstRTSPStreamTransportPrivate *priv;
112 GstRTSPStreamTransport *trans;
114 trans = GST_RTSP_STREAM_TRANSPORT (obj);
117 /* remove callbacks now */
118 gst_rtsp_stream_transport_set_callbacks (trans, NULL, NULL, NULL, NULL);
119 gst_rtsp_stream_transport_set_keepalive (trans, NULL, NULL, NULL);
122 g_object_unref (priv->stream);
125 gst_rtsp_transport_free (priv->transport);
128 gst_rtsp_url_free (priv->url);
130 G_OBJECT_CLASS (gst_rtsp_stream_transport_parent_class)->finalize (obj);
134 * gst_rtsp_stream_transport_new:
135 * @stream: a #GstRTSPStream
136 * @tr: (transfer full): a GstRTSPTransport
138 * Create a new #GstRTSPStreamTransport that can be used to manage
139 * @stream with transport @tr.
141 * Returns: (transfer full): a new #GstRTSPStreamTransport
143 GstRTSPStreamTransport *
144 gst_rtsp_stream_transport_new (GstRTSPStream * stream, GstRTSPTransport * tr)
146 GstRTSPStreamTransportPrivate *priv;
147 GstRTSPStreamTransport *trans;
149 g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
150 g_return_val_if_fail (tr != NULL, NULL);
152 trans = g_object_new (GST_TYPE_RTSP_STREAM_TRANSPORT, NULL);
154 priv->stream = stream;
155 priv->stream = g_object_ref (priv->stream);
156 priv->transport = tr;
162 * gst_rtsp_stream_transport_get_stream:
163 * @trans: a #GstRTSPStreamTransport
165 * Get the #GstRTSPStream used when constructing @trans.
167 * Returns: (transfer none) (nullable): the stream used when constructing @trans.
170 gst_rtsp_stream_transport_get_stream (GstRTSPStreamTransport * trans)
172 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
174 return trans->priv->stream;
178 * gst_rtsp_stream_transport_set_callbacks:
179 * @trans: a #GstRTSPStreamTransport
180 * @send_rtp: (scope notified): a callback called when RTP should be sent
181 * @send_rtcp: (scope notified): a callback called when RTCP should be sent
182 * @user_data: (closure): user data passed to callbacks
183 * @notify: (allow-none): called with the user_data when no longer needed.
185 * Install callbacks that will be called when data for a stream should be sent
186 * to a client. This is usually used when sending RTP/RTCP over TCP.
189 gst_rtsp_stream_transport_set_callbacks (GstRTSPStreamTransport * trans,
190 GstRTSPSendFunc send_rtp, GstRTSPSendFunc send_rtcp,
191 gpointer user_data, GDestroyNotify notify)
193 GstRTSPStreamTransportPrivate *priv;
195 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
199 priv->send_rtp = send_rtp;
200 priv->send_rtcp = send_rtcp;
202 priv->notify (priv->user_data);
203 priv->user_data = user_data;
204 priv->notify = notify;
208 * gst_rtsp_stream_transport_set_keepalive:
209 * @trans: a #GstRTSPStreamTransport
210 * @keep_alive: (scope notified): a callback called when the receiver is active
211 * @user_data: (closure): user data passed to callback
212 * @notify: (allow-none): called with the user_data when no longer needed.
214 * Install callbacks that will be called when RTCP packets are received from the
215 * receiver of @trans.
218 gst_rtsp_stream_transport_set_keepalive (GstRTSPStreamTransport * trans,
219 GstRTSPKeepAliveFunc keep_alive, gpointer user_data, GDestroyNotify notify)
221 GstRTSPStreamTransportPrivate *priv;
223 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
227 priv->keep_alive = keep_alive;
229 priv->ka_notify (priv->ka_user_data);
230 priv->ka_user_data = user_data;
231 priv->ka_notify = notify;
236 * gst_rtsp_stream_transport_set_transport:
237 * @trans: a #GstRTSPStreamTransport
238 * @tr: (transfer full): a client #GstRTSPTransport
240 * Set @tr as the client transport. This function takes ownership of the
244 gst_rtsp_stream_transport_set_transport (GstRTSPStreamTransport * trans,
245 GstRTSPTransport * tr)
247 GstRTSPStreamTransportPrivate *priv;
249 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
250 g_return_if_fail (tr != NULL);
254 /* keep track of the transports in the stream. */
256 gst_rtsp_transport_free (priv->transport);
257 priv->transport = tr;
261 * gst_rtsp_stream_transport_get_transport:
262 * @trans: a #GstRTSPStreamTransport
264 * Get the transport configured in @trans.
266 * Returns: (transfer none) (nullable): the transport configured in @trans. It remains
267 * valid for as long as @trans is valid.
269 const GstRTSPTransport *
270 gst_rtsp_stream_transport_get_transport (GstRTSPStreamTransport * trans)
272 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
274 return trans->priv->transport;
278 * gst_rtsp_stream_transport_set_url:
279 * @trans: a #GstRTSPStreamTransport
280 * @url: (transfer none) (nullable): a client #GstRTSPUrl
282 * Set @url as the client url.
285 gst_rtsp_stream_transport_set_url (GstRTSPStreamTransport * trans,
286 const GstRTSPUrl * url)
288 GstRTSPStreamTransportPrivate *priv;
290 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
294 /* keep track of the transports in the stream. */
296 gst_rtsp_url_free (priv->url);
297 priv->url = (url ? gst_rtsp_url_copy (url) : NULL);
301 * gst_rtsp_stream_transport_get_url:
302 * @trans: a #GstRTSPStreamTransport
304 * Get the url configured in @trans.
306 * Returns: (transfer none) (nullable): the url configured in @trans.
307 * It remains valid for as long as @trans is valid.
310 gst_rtsp_stream_transport_get_url (GstRTSPStreamTransport * trans)
312 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
314 return trans->priv->url;
318 * gst_rtsp_stream_transport_get_rtpinfo:
319 * @trans: a #GstRTSPStreamTransport
320 * @start_time: a star time
322 * Get the RTP-Info string for @trans and @start_time.
324 * Returns: (transfer full) (nullable): the RTPInfo string for @trans
325 * and @start_time or %NULL when the RTP-Info could not be
326 * determined. g_free() after usage.
329 gst_rtsp_stream_transport_get_rtpinfo (GstRTSPStreamTransport * trans,
330 GstClockTime start_time)
332 GstRTSPStreamTransportPrivate *priv;
335 guint rtptime, seq, clock_rate;
336 GstClockTime running_time = GST_CLOCK_TIME_NONE;
338 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
342 if (!gst_rtsp_stream_is_sender (priv->stream))
344 if (!gst_rtsp_stream_get_rtpinfo (priv->stream, &rtptime, &seq, &clock_rate,
348 GST_DEBUG ("RTP time %u, seq %u, rate %u, running-time %" GST_TIME_FORMAT,
349 rtptime, seq, clock_rate, GST_TIME_ARGS (running_time));
351 if (GST_CLOCK_TIME_IS_VALID (running_time)
352 && GST_CLOCK_TIME_IS_VALID (start_time)) {
353 if (running_time > start_time) {
355 gst_util_uint64_scale_int (running_time - start_time, clock_rate,
359 gst_util_uint64_scale_int (start_time - running_time, clock_rate,
363 GST_DEBUG ("RTP time %u, for start-time %" GST_TIME_FORMAT,
364 rtptime, GST_TIME_ARGS (start_time));
366 rtpinfo = g_string_new ("");
368 url_str = gst_rtsp_url_get_request_uri (trans->priv->url);
369 g_string_append_printf (rtpinfo, "url=%s;seq=%u;rtptime=%u",
370 url_str, seq, rtptime);
373 return g_string_free (rtpinfo, FALSE);
377 * gst_rtsp_stream_transport_set_active:
378 * @trans: a #GstRTSPStreamTransport
379 * @active: new state of @trans
381 * Activate or deactivate datatransfer configured in @trans.
383 * Returns: %TRUE when the state was changed.
386 gst_rtsp_stream_transport_set_active (GstRTSPStreamTransport * trans,
389 GstRTSPStreamTransportPrivate *priv;
392 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
396 if (priv->active == active)
400 res = gst_rtsp_stream_add_transport (priv->stream, trans);
402 res = gst_rtsp_stream_remove_transport (priv->stream, trans);
405 priv->active = active;
411 * gst_rtsp_stream_transport_set_timed_out:
412 * @trans: a #GstRTSPStreamTransport
413 * @timedout: timed out value
415 * Set the timed out state of @trans to @timedout
418 gst_rtsp_stream_transport_set_timed_out (GstRTSPStreamTransport * trans,
421 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
423 trans->priv->timed_out = timedout;
427 * gst_rtsp_stream_transport_is_timed_out:
428 * @trans: a #GstRTSPStreamTransport
430 * Check if @trans is timed out.
432 * Returns: %TRUE if @trans timed out.
435 gst_rtsp_stream_transport_is_timed_out (GstRTSPStreamTransport * trans)
437 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
439 return trans->priv->timed_out;
443 * gst_rtsp_stream_transport_send_rtp:
444 * @trans: a #GstRTSPStreamTransport
445 * @buffer: (transfer none): a #GstBuffer
447 * Send @buffer to the installed RTP callback for @trans.
449 * Returns: %TRUE on success
452 gst_rtsp_stream_transport_send_rtp (GstRTSPStreamTransport * trans,
455 GstRTSPStreamTransportPrivate *priv;
456 gboolean res = FALSE;
458 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
464 priv->send_rtp (buffer, priv->transport->interleaved.min,
468 gst_rtsp_stream_transport_keep_alive (trans);
474 * gst_rtsp_stream_transport_send_rtcp:
475 * @trans: a #GstRTSPStreamTransport
476 * @buffer: (transfer none): a #GstBuffer
478 * Send @buffer to the installed RTCP callback for @trans.
480 * Returns: %TRUE on success
483 gst_rtsp_stream_transport_send_rtcp (GstRTSPStreamTransport * trans,
486 GstRTSPStreamTransportPrivate *priv;
487 gboolean res = FALSE;
489 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
495 priv->send_rtcp (buffer, priv->transport->interleaved.max,
499 gst_rtsp_stream_transport_keep_alive (trans);
505 * gst_rtsp_stream_transport_keep_alive:
506 * @trans: a #GstRTSPStreamTransport
508 * Signal the installed keep_alive callback for @trans.
511 gst_rtsp_stream_transport_keep_alive (GstRTSPStreamTransport * trans)
513 GstRTSPStreamTransportPrivate *priv;
517 if (priv->keep_alive)
518 priv->keep_alive (priv->ka_user_data);
522 * gst_rtsp_stream_transport_recv_data:
523 * @trans: a #GstRTSPStreamTransport
524 * @channel: a channel
525 * @buffer: (transfer full): a #GstBuffer
527 * Receive @buffer on @channel @trans.
529 * Returns: a #GstFlowReturn. Returns GST_FLOW_NOT_LINKED when @channel is not
530 * configured in the transport of @trans.
533 gst_rtsp_stream_transport_recv_data (GstRTSPStreamTransport * trans,
534 guint channel, GstBuffer * buffer)
536 GstRTSPStreamTransportPrivate *priv;
537 const GstRTSPTransport *tr;
540 g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
543 tr = priv->transport;
545 if (tr->interleaved.min == channel) {
546 res = gst_rtsp_stream_recv_rtp (priv->stream, buffer);
547 } else if (tr->interleaved.max == channel) {
548 res = gst_rtsp_stream_recv_rtcp (priv->stream, buffer);
550 res = GST_FLOW_NOT_LINKED;