1 /* GStreamer
2 * Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
3 *
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.
8 *
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.
13 *
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.
18 */
19 /**
20 * SECTION:rtsp-stream-transport
21 * @short_description: A media stream transport configuration
22 * @see_also: #GstRTSPStream, #GstRTSPSessionMedia
23 *
24 * The #GstRTSPStreamTransport configures the transport used by a
25 * #GstRTSPStream. It is usually manages by a #GstRTSPSessionMedia object.
26 *
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.
30 *
31 * With gst_rtsp_stream_transport_set_active() the transports are added and
32 * removed from the stream.
33 *
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.
37 *
38 * A #GstRTSPClient will call gst_rtsp_stream_transport_message_sent() when it
39 * has sent a data message for the transport.
40 *
41 * Last reviewed on 2013-07-16 (1.0.0)
42 */
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47 #include <string.h>
48 #include <stdlib.h>
49
50 #include "rtsp-stream-transport.h"
51
52 struct _GstRTSPStreamTransportPrivate
53 {
54 GstRTSPStream *stream;
55
56 GstRTSPSendFunc send_rtp;
57 GstRTSPSendFunc send_rtcp;
58 gpointer user_data;
59 GDestroyNotify notify;
60
61 GstRTSPSendListFunc send_rtp_list;
62 GstRTSPSendListFunc send_rtcp_list;
63 gpointer list_user_data;
64 GDestroyNotify list_notify;
65
66 GstRTSPKeepAliveFunc keep_alive;
67 gpointer ka_user_data;
68 GDestroyNotify ka_notify;
69 gboolean active;
70 gboolean timed_out;
71
72 GstRTSPMessageSentFunc message_sent;
73 gpointer ms_user_data;
74 GDestroyNotify ms_notify;
75
76 GstRTSPTransport *transport;
77 GstRTSPUrl *url;
78
79 GObject *rtpsource;
80 };
81
82 enum
83 {
84 PROP_0,
85 PROP_LAST
86 };
87
88 GST_DEBUG_CATEGORY_STATIC (rtsp_stream_transport_debug);
89 #define GST_CAT_DEFAULT rtsp_stream_transport_debug
90
91 static void gst_rtsp_stream_transport_finalize (GObject * obj);
92
93 G_DEFINE_TYPE_WITH_PRIVATE (GstRTSPStreamTransport, gst_rtsp_stream_transport,
94 G_TYPE_OBJECT);
95
96 static void
gst_rtsp_stream_transport_class_init(GstRTSPStreamTransportClass * klass)97 gst_rtsp_stream_transport_class_init (GstRTSPStreamTransportClass * klass)
98 {
99 GObjectClass *gobject_class;
100
101 gobject_class = G_OBJECT_CLASS (klass);
102
103 gobject_class->finalize = gst_rtsp_stream_transport_finalize;
104
105 GST_DEBUG_CATEGORY_INIT (rtsp_stream_transport_debug, "rtspmediatransport",
106 0, "GstRTSPStreamTransport");
107 }
108
109 static void
gst_rtsp_stream_transport_init(GstRTSPStreamTransport * trans)110 gst_rtsp_stream_transport_init (GstRTSPStreamTransport * trans)
111 {
112 trans->priv = gst_rtsp_stream_transport_get_instance_private (trans);
113 }
114
115 static void
gst_rtsp_stream_transport_finalize(GObject * obj)116 gst_rtsp_stream_transport_finalize (GObject * obj)
117 {
118 GstRTSPStreamTransportPrivate *priv;
119 GstRTSPStreamTransport *trans;
120
121 trans = GST_RTSP_STREAM_TRANSPORT (obj);
122 priv = trans->priv;
123
124 /* remove callbacks now */
125 gst_rtsp_stream_transport_set_callbacks (trans, NULL, NULL, NULL, NULL);
126 gst_rtsp_stream_transport_set_keepalive (trans, NULL, NULL, NULL);
127 gst_rtsp_stream_transport_set_message_sent (trans, NULL, NULL, NULL);
128
129 if (priv->stream)
130 g_object_unref (priv->stream);
131
132 if (priv->transport)
133 gst_rtsp_transport_free (priv->transport);
134
135 if (priv->url)
136 gst_rtsp_url_free (priv->url);
137
138 G_OBJECT_CLASS (gst_rtsp_stream_transport_parent_class)->finalize (obj);
139 }
140
141 /**
142 * gst_rtsp_stream_transport_new:
143 * @stream: a #GstRTSPStream
144 * @tr: (transfer full): a GstRTSPTransport
145 *
146 * Create a new #GstRTSPStreamTransport that can be used to manage
147 * @stream with transport @tr.
148 *
149 * Returns: (transfer full): a new #GstRTSPStreamTransport
150 */
151 GstRTSPStreamTransport *
gst_rtsp_stream_transport_new(GstRTSPStream * stream,GstRTSPTransport * tr)152 gst_rtsp_stream_transport_new (GstRTSPStream * stream, GstRTSPTransport * tr)
153 {
154 GstRTSPStreamTransportPrivate *priv;
155 GstRTSPStreamTransport *trans;
156
157 g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
158 g_return_val_if_fail (tr != NULL, NULL);
159
160 trans = g_object_new (GST_TYPE_RTSP_STREAM_TRANSPORT, NULL);
161 priv = trans->priv;
162 priv->stream = stream;
163 priv->stream = g_object_ref (priv->stream);
164 priv->transport = tr;
165
166 return trans;
167 }
168
169 /**
170 * gst_rtsp_stream_transport_get_stream:
171 * @trans: a #GstRTSPStreamTransport
172 *
173 * Get the #GstRTSPStream used when constructing @trans.
174 *
175 * Returns: (transfer none) (nullable): the stream used when constructing @trans.
176 */
177 GstRTSPStream *
gst_rtsp_stream_transport_get_stream(GstRTSPStreamTransport * trans)178 gst_rtsp_stream_transport_get_stream (GstRTSPStreamTransport * trans)
179 {
180 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
181
182 return trans->priv->stream;
183 }
184
185 /**
186 * gst_rtsp_stream_transport_set_callbacks:
187 * @trans: a #GstRTSPStreamTransport
188 * @send_rtp: (scope notified): a callback called when RTP should be sent
189 * @send_rtcp: (scope notified): a callback called when RTCP should be sent
190 * @user_data: (closure): user data passed to callbacks
191 * @notify: (allow-none): called with the user_data when no longer needed.
192 *
193 * Install callbacks that will be called when data for a stream should be sent
194 * to a client. This is usually used when sending RTP/RTCP over TCP.
195 */
196 void
gst_rtsp_stream_transport_set_callbacks(GstRTSPStreamTransport * trans,GstRTSPSendFunc send_rtp,GstRTSPSendFunc send_rtcp,gpointer user_data,GDestroyNotify notify)197 gst_rtsp_stream_transport_set_callbacks (GstRTSPStreamTransport * trans,
198 GstRTSPSendFunc send_rtp, GstRTSPSendFunc send_rtcp,
199 gpointer user_data, GDestroyNotify notify)
200 {
201 GstRTSPStreamTransportPrivate *priv;
202
203 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
204
205 priv = trans->priv;
206
207 priv->send_rtp = send_rtp;
208 priv->send_rtcp = send_rtcp;
209 if (priv->notify)
210 priv->notify (priv->user_data);
211 priv->user_data = user_data;
212 priv->notify = notify;
213 }
214
215 /**
216 * gst_rtsp_stream_transport_set_list_callbacks:
217 * @trans: a #GstRTSPStreamTransport
218 * @send_rtp_list: (scope notified): a callback called when RTP should be sent
219 * @send_rtcp_list: (scope notified): a callback called when RTCP should be sent
220 * @user_data: (closure): user data passed to callbacks
221 * @notify: (allow-none): called with the user_data when no longer needed.
222 *
223 * Install callbacks that will be called when data for a stream should be sent
224 * to a client. This is usually used when sending RTP/RTCP over TCP.
225 *
226 * Since: 1.16
227 */
228 void
gst_rtsp_stream_transport_set_list_callbacks(GstRTSPStreamTransport * trans,GstRTSPSendListFunc send_rtp_list,GstRTSPSendListFunc send_rtcp_list,gpointer user_data,GDestroyNotify notify)229 gst_rtsp_stream_transport_set_list_callbacks (GstRTSPStreamTransport * trans,
230 GstRTSPSendListFunc send_rtp_list, GstRTSPSendListFunc send_rtcp_list,
231 gpointer user_data, GDestroyNotify notify)
232 {
233 GstRTSPStreamTransportPrivate *priv;
234
235 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
236
237 priv = trans->priv;
238
239 priv->send_rtp_list = send_rtp_list;
240 priv->send_rtcp_list = send_rtcp_list;
241 if (priv->list_notify)
242 priv->list_notify (priv->list_user_data);
243 priv->list_user_data = user_data;
244 priv->list_notify = notify;
245 }
246
247 /**
248 * gst_rtsp_stream_transport_set_keepalive:
249 * @trans: a #GstRTSPStreamTransport
250 * @keep_alive: (scope notified): a callback called when the receiver is active
251 * @user_data: (closure): user data passed to callback
252 * @notify: (allow-none): called with the user_data when no longer needed.
253 *
254 * Install callbacks that will be called when RTCP packets are received from the
255 * receiver of @trans.
256 */
257 void
gst_rtsp_stream_transport_set_keepalive(GstRTSPStreamTransport * trans,GstRTSPKeepAliveFunc keep_alive,gpointer user_data,GDestroyNotify notify)258 gst_rtsp_stream_transport_set_keepalive (GstRTSPStreamTransport * trans,
259 GstRTSPKeepAliveFunc keep_alive, gpointer user_data, GDestroyNotify notify)
260 {
261 GstRTSPStreamTransportPrivate *priv;
262
263 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
264
265 priv = trans->priv;
266
267 priv->keep_alive = keep_alive;
268 if (priv->ka_notify)
269 priv->ka_notify (priv->ka_user_data);
270 priv->ka_user_data = user_data;
271 priv->ka_notify = notify;
272 }
273
274 /**
275 * gst_rtsp_stream_transport_set_message_sent:
276 * @trans: a #GstRTSPStreamTransport
277 * @message_sent: (scope notified): a callback called when a message has been sent
278 * @user_data: (closure): user data passed to callback
279 * @notify: (allow-none): called with the user_data when no longer needed
280 *
281 * Install a callback that will be called when a message has been sent on @trans.
282 */
283 void
gst_rtsp_stream_transport_set_message_sent(GstRTSPStreamTransport * trans,GstRTSPMessageSentFunc message_sent,gpointer user_data,GDestroyNotify notify)284 gst_rtsp_stream_transport_set_message_sent (GstRTSPStreamTransport * trans,
285 GstRTSPMessageSentFunc message_sent, gpointer user_data,
286 GDestroyNotify notify)
287 {
288 GstRTSPStreamTransportPrivate *priv;
289
290 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
291
292 priv = trans->priv;
293
294 priv->message_sent = message_sent;
295 if (priv->ms_notify)
296 priv->ms_notify (priv->ms_user_data);
297 priv->ms_user_data = user_data;
298 priv->ms_notify = notify;
299 }
300
301
302 /**
303 * gst_rtsp_stream_transport_set_transport:
304 * @trans: a #GstRTSPStreamTransport
305 * @tr: (transfer full): a client #GstRTSPTransport
306 *
307 * Set @tr as the client transport. This function takes ownership of the
308 * passed @tr.
309 */
310 void
gst_rtsp_stream_transport_set_transport(GstRTSPStreamTransport * trans,GstRTSPTransport * tr)311 gst_rtsp_stream_transport_set_transport (GstRTSPStreamTransport * trans,
312 GstRTSPTransport * tr)
313 {
314 GstRTSPStreamTransportPrivate *priv;
315
316 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
317 g_return_if_fail (tr != NULL);
318
319 priv = trans->priv;
320
321 /* keep track of the transports in the stream. */
322 if (priv->transport)
323 gst_rtsp_transport_free (priv->transport);
324 priv->transport = tr;
325 }
326
327 /**
328 * gst_rtsp_stream_transport_get_transport:
329 * @trans: a #GstRTSPStreamTransport
330 *
331 * Get the transport configured in @trans.
332 *
333 * Returns: (transfer none) (nullable): the transport configured in @trans. It remains
334 * valid for as long as @trans is valid.
335 */
336 const GstRTSPTransport *
gst_rtsp_stream_transport_get_transport(GstRTSPStreamTransport * trans)337 gst_rtsp_stream_transport_get_transport (GstRTSPStreamTransport * trans)
338 {
339 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
340
341 return trans->priv->transport;
342 }
343
344 /**
345 * gst_rtsp_stream_transport_set_url:
346 * @trans: a #GstRTSPStreamTransport
347 * @url: (transfer none) (nullable): a client #GstRTSPUrl
348 *
349 * Set @url as the client url.
350 */
351 void
gst_rtsp_stream_transport_set_url(GstRTSPStreamTransport * trans,const GstRTSPUrl * url)352 gst_rtsp_stream_transport_set_url (GstRTSPStreamTransport * trans,
353 const GstRTSPUrl * url)
354 {
355 GstRTSPStreamTransportPrivate *priv;
356
357 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
358
359 priv = trans->priv;
360
361 /* keep track of the transports in the stream. */
362 if (priv->url)
363 gst_rtsp_url_free (priv->url);
364 priv->url = (url ? gst_rtsp_url_copy (url) : NULL);
365 }
366
367 /**
368 * gst_rtsp_stream_transport_get_url:
369 * @trans: a #GstRTSPStreamTransport
370 *
371 * Get the url configured in @trans.
372 *
373 * Returns: (transfer none) (nullable): the url configured in @trans.
374 * It remains valid for as long as @trans is valid.
375 */
376 const GstRTSPUrl *
gst_rtsp_stream_transport_get_url(GstRTSPStreamTransport * trans)377 gst_rtsp_stream_transport_get_url (GstRTSPStreamTransport * trans)
378 {
379 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
380
381 return trans->priv->url;
382 }
383
384 /**
385 * gst_rtsp_stream_transport_get_rtpinfo:
386 * @trans: a #GstRTSPStreamTransport
387 * @start_time: a star time
388 *
389 * Get the RTP-Info string for @trans and @start_time.
390 *
391 * Returns: (transfer full) (nullable): the RTPInfo string for @trans
392 * and @start_time or %NULL when the RTP-Info could not be
393 * determined. g_free() after usage.
394 */
395 gchar *
gst_rtsp_stream_transport_get_rtpinfo(GstRTSPStreamTransport * trans,GstClockTime start_time)396 gst_rtsp_stream_transport_get_rtpinfo (GstRTSPStreamTransport * trans,
397 GstClockTime start_time)
398 {
399 GstRTSPStreamTransportPrivate *priv;
400 gchar *url_str;
401 GString *rtpinfo;
402 guint rtptime, seq, clock_rate;
403 GstClockTime running_time = GST_CLOCK_TIME_NONE;
404
405 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
406
407 priv = trans->priv;
408
409 if (!gst_rtsp_stream_is_sender (priv->stream))
410 return NULL;
411 if (!gst_rtsp_stream_get_rtpinfo (priv->stream, &rtptime, &seq, &clock_rate,
412 &running_time))
413 return NULL;
414
415 GST_DEBUG ("RTP time %u, seq %u, rate %u, running-time %" GST_TIME_FORMAT,
416 rtptime, seq, clock_rate, GST_TIME_ARGS (running_time));
417
418 if (GST_CLOCK_TIME_IS_VALID (running_time)
419 && GST_CLOCK_TIME_IS_VALID (start_time)) {
420 if (running_time > start_time) {
421 rtptime -=
422 gst_util_uint64_scale_int (running_time - start_time, clock_rate,
423 GST_SECOND);
424 } else {
425 rtptime +=
426 gst_util_uint64_scale_int (start_time - running_time, clock_rate,
427 GST_SECOND);
428 }
429 }
430 GST_DEBUG ("RTP time %u, for start-time %" GST_TIME_FORMAT,
431 rtptime, GST_TIME_ARGS (start_time));
432
433 rtpinfo = g_string_new ("");
434
435 url_str = gst_rtsp_url_get_request_uri (trans->priv->url);
436 g_string_append_printf (rtpinfo, "url=%s;seq=%u;rtptime=%u",
437 url_str, seq, rtptime);
438 g_free (url_str);
439
440 return g_string_free (rtpinfo, FALSE);
441 }
442
443 /**
444 * gst_rtsp_stream_transport_set_active:
445 * @trans: a #GstRTSPStreamTransport
446 * @active: new state of @trans
447 *
448 * Activate or deactivate datatransfer configured in @trans.
449 *
450 * Returns: %TRUE when the state was changed.
451 */
452 gboolean
gst_rtsp_stream_transport_set_active(GstRTSPStreamTransport * trans,gboolean active)453 gst_rtsp_stream_transport_set_active (GstRTSPStreamTransport * trans,
454 gboolean active)
455 {
456 GstRTSPStreamTransportPrivate *priv;
457 gboolean res;
458
459 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
460
461 priv = trans->priv;
462
463 if (priv->active == active)
464 return FALSE;
465
466 if (active)
467 res = gst_rtsp_stream_add_transport (priv->stream, trans);
468 else
469 res = gst_rtsp_stream_remove_transport (priv->stream, trans);
470
471 if (res)
472 priv->active = active;
473
474 return res;
475 }
476
477 /**
478 * gst_rtsp_stream_transport_set_timed_out:
479 * @trans: a #GstRTSPStreamTransport
480 * @timedout: timed out value
481 *
482 * Set the timed out state of @trans to @timedout
483 */
484 void
gst_rtsp_stream_transport_set_timed_out(GstRTSPStreamTransport * trans,gboolean timedout)485 gst_rtsp_stream_transport_set_timed_out (GstRTSPStreamTransport * trans,
486 gboolean timedout)
487 {
488 g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
489
490 trans->priv->timed_out = timedout;
491 }
492
493 /**
494 * gst_rtsp_stream_transport_is_timed_out:
495 * @trans: a #GstRTSPStreamTransport
496 *
497 * Check if @trans is timed out.
498 *
499 * Returns: %TRUE if @trans timed out.
500 */
501 gboolean
gst_rtsp_stream_transport_is_timed_out(GstRTSPStreamTransport * trans)502 gst_rtsp_stream_transport_is_timed_out (GstRTSPStreamTransport * trans)
503 {
504 g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
505
506 return trans->priv->timed_out;
507 }
508
509 /**
510 * gst_rtsp_stream_transport_send_rtp:
511 * @trans: a #GstRTSPStreamTransport
512 * @buffer: (transfer none): a #GstBuffer
513 *
514 * Send @buffer to the installed RTP callback for @trans.
515 *
516 * Returns: %TRUE on success
517 */
518 gboolean
gst_rtsp_stream_transport_send_rtp(GstRTSPStreamTransport * trans,GstBuffer * buffer)519 gst_rtsp_stream_transport_send_rtp (GstRTSPStreamTransport * trans,
520 GstBuffer * buffer)
521 {
522 GstRTSPStreamTransportPrivate *priv;
523 gboolean res = FALSE;
524
525 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
526
527 priv = trans->priv;
528
529 if (priv->send_rtp)
530 res =
531 priv->send_rtp (buffer, priv->transport->interleaved.min,
532 priv->user_data);
533
534 if (res)
535 gst_rtsp_stream_transport_keep_alive (trans);
536
537 return res;
538 }
539
540 /**
541 * gst_rtsp_stream_transport_send_rtcp:
542 * @trans: a #GstRTSPStreamTransport
543 * @buffer: (transfer none): a #GstBuffer
544 *
545 * Send @buffer to the installed RTCP callback for @trans.
546 *
547 * Returns: %TRUE on success
548 */
549 gboolean
gst_rtsp_stream_transport_send_rtcp(GstRTSPStreamTransport * trans,GstBuffer * buffer)550 gst_rtsp_stream_transport_send_rtcp (GstRTSPStreamTransport * trans,
551 GstBuffer * buffer)
552 {
553 GstRTSPStreamTransportPrivate *priv;
554 gboolean res = FALSE;
555
556 g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
557
558 priv = trans->priv;
559
560 if (priv->send_rtcp)
561 res =
562 priv->send_rtcp (buffer, priv->transport->interleaved.max,
563 priv->user_data);
564
565 if (res)
566 gst_rtsp_stream_transport_keep_alive (trans);
567
568 return res;
569 }
570
571 /**
572 * gst_rtsp_stream_transport_send_rtp_list:
573 * @trans: a #GstRTSPStreamTransport
574 * @buffer_list: (transfer none): a #GstBufferList
575 *
576 * Send @buffer_list to the installed RTP callback for @trans.
577 *
578 * Returns: %TRUE on success
579 *
580 * Since: 1.16
581 */
582 gboolean
gst_rtsp_stream_transport_send_rtp_list(GstRTSPStreamTransport * trans,GstBufferList * buffer_list)583 gst_rtsp_stream_transport_send_rtp_list (GstRTSPStreamTransport * trans,
584 GstBufferList * buffer_list)
585 {
586 GstRTSPStreamTransportPrivate *priv;
587 gboolean res = FALSE;
588
589 g_return_val_if_fail (GST_IS_BUFFER_LIST (buffer_list), FALSE);
590
591 priv = trans->priv;
592
593 if (priv->send_rtp_list) {
594 res =
595 priv->send_rtp_list (buffer_list, priv->transport->interleaved.min,
596 priv->list_user_data);
597 } else if (priv->send_rtp) {
598 guint n = gst_buffer_list_length (buffer_list), i;
599
600 for (i = 0; i < n; i++) {
601 GstBuffer *buffer = gst_buffer_list_get (buffer_list, i);
602
603 res =
604 priv->send_rtp (buffer, priv->transport->interleaved.min,
605 priv->user_data);
606 if (!res)
607 break;
608 }
609 }
610
611 if (res)
612 gst_rtsp_stream_transport_keep_alive (trans);
613
614 return res;
615 }
616
617 /**
618 * gst_rtsp_stream_transport_send_rtcp_list:
619 * @trans: a #GstRTSPStreamTransport
620 * @buffer_list: (transfer none): a #GstBuffer
621 *
622 * Send @buffer_list to the installed RTCP callback for @trans.
623 *
624 * Returns: %TRUE on success
625 *
626 * Since: 1.16
627 */
628 gboolean
gst_rtsp_stream_transport_send_rtcp_list(GstRTSPStreamTransport * trans,GstBufferList * buffer_list)629 gst_rtsp_stream_transport_send_rtcp_list (GstRTSPStreamTransport * trans,
630 GstBufferList * buffer_list)
631 {
632 GstRTSPStreamTransportPrivate *priv;
633 gboolean res = FALSE;
634
635 g_return_val_if_fail (GST_IS_BUFFER_LIST (buffer_list), FALSE);
636
637 priv = trans->priv;
638
639 if (priv->send_rtcp_list) {
640 res =
641 priv->send_rtcp_list (buffer_list, priv->transport->interleaved.max,
642 priv->list_user_data);
643 } else if (priv->send_rtcp) {
644 guint n = gst_buffer_list_length (buffer_list), i;
645
646 for (i = 0; i < n; i++) {
647 GstBuffer *buffer = gst_buffer_list_get (buffer_list, i);
648
649 res =
650 priv->send_rtcp (buffer, priv->transport->interleaved.max,
651 priv->user_data);
652 if (!res)
653 break;
654 }
655 }
656
657 if (res)
658 gst_rtsp_stream_transport_keep_alive (trans);
659
660 return res;
661 }
662
663 /**
664 * gst_rtsp_stream_transport_keep_alive:
665 * @trans: a #GstRTSPStreamTransport
666 *
667 * Signal the installed keep_alive callback for @trans.
668 */
669 void
gst_rtsp_stream_transport_keep_alive(GstRTSPStreamTransport * trans)670 gst_rtsp_stream_transport_keep_alive (GstRTSPStreamTransport * trans)
671 {
672 GstRTSPStreamTransportPrivate *priv;
673
674 priv = trans->priv;
675
676 if (priv->keep_alive)
677 priv->keep_alive (priv->ka_user_data);
678 }
679
680 /**
681 * gst_rtsp_stream_transport_message_sent:
682 * @trans: a #GstRTSPStreamTransport
683 *
684 * Signal the installed message_sent callback for @trans.
685 *
686 * Since: 1.16
687 */
688 void
gst_rtsp_stream_transport_message_sent(GstRTSPStreamTransport * trans)689 gst_rtsp_stream_transport_message_sent (GstRTSPStreamTransport * trans)
690 {
691 GstRTSPStreamTransportPrivate *priv;
692
693 priv = trans->priv;
694
695 if (priv->message_sent)
696 priv->message_sent (priv->ms_user_data);
697 }
698
699 /**
700 * gst_rtsp_stream_transport_recv_data:
701 * @trans: a #GstRTSPStreamTransport
702 * @channel: a channel
703 * @buffer: (transfer full): a #GstBuffer
704 *
705 * Receive @buffer on @channel @trans.
706 *
707 * Returns: a #GstFlowReturn. Returns GST_FLOW_NOT_LINKED when @channel is not
708 * configured in the transport of @trans.
709 */
710 GstFlowReturn
gst_rtsp_stream_transport_recv_data(GstRTSPStreamTransport * trans,guint channel,GstBuffer * buffer)711 gst_rtsp_stream_transport_recv_data (GstRTSPStreamTransport * trans,
712 guint channel, GstBuffer * buffer)
713 {
714 GstRTSPStreamTransportPrivate *priv;
715 const GstRTSPTransport *tr;
716 GstFlowReturn res;
717
718 g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
719
720 priv = trans->priv;
721 tr = priv->transport;
722
723 if (tr->interleaved.min == channel) {
724 res = gst_rtsp_stream_recv_rtp (priv->stream, buffer);
725 } else if (tr->interleaved.max == channel) {
726 res = gst_rtsp_stream_recv_rtcp (priv->stream, buffer);
727 } else {
728 res = GST_FLOW_NOT_LINKED;
729 }
730 return res;
731 }
732