stream-transport: add method to get/set url
[platform/upstream/gstreamer.git] / gst / rtsp-server / rtsp-stream-transport.c
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  * Last reviewed on 2013-07-16 (1.0.0)
39  */
40
41 #include <string.h>
42 #include <stdlib.h>
43
44 #include "rtsp-stream-transport.h"
45
46 #define GST_RTSP_STREAM_TRANSPORT_GET_PRIVATE(obj)  \
47        (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_STREAM_TRANSPORT, GstRTSPStreamTransportPrivate))
48
49 struct _GstRTSPStreamTransportPrivate
50 {
51   GstRTSPStream *stream;
52
53   GstRTSPSendFunc send_rtp;
54   GstRTSPSendFunc send_rtcp;
55   gpointer user_data;
56   GDestroyNotify notify;
57
58   GstRTSPKeepAliveFunc keep_alive;
59   gpointer ka_user_data;
60   GDestroyNotify ka_notify;
61   gboolean active;
62   gboolean timed_out;
63
64   GstRTSPTransport *transport;
65   GstRTSPUrl *url;
66
67   GObject *rtpsource;
68 };
69
70 enum
71 {
72   PROP_0,
73   PROP_LAST
74 };
75
76 GST_DEBUG_CATEGORY_STATIC (rtsp_stream_transport_debug);
77 #define GST_CAT_DEFAULT rtsp_stream_transport_debug
78
79 static void gst_rtsp_stream_transport_finalize (GObject * obj);
80
81 G_DEFINE_TYPE (GstRTSPStreamTransport, gst_rtsp_stream_transport,
82     G_TYPE_OBJECT);
83
84 static void
85 gst_rtsp_stream_transport_class_init (GstRTSPStreamTransportClass * klass)
86 {
87   GObjectClass *gobject_class;
88
89   g_type_class_add_private (klass, sizeof (GstRTSPStreamTransportPrivate));
90
91   gobject_class = G_OBJECT_CLASS (klass);
92
93   gobject_class->finalize = gst_rtsp_stream_transport_finalize;
94
95   GST_DEBUG_CATEGORY_INIT (rtsp_stream_transport_debug, "rtspmediatransport",
96       0, "GstRTSPStreamTransport");
97 }
98
99 static void
100 gst_rtsp_stream_transport_init (GstRTSPStreamTransport * trans)
101 {
102   GstRTSPStreamTransportPrivate *priv =
103       GST_RTSP_STREAM_TRANSPORT_GET_PRIVATE (trans);
104
105   trans->priv = priv;
106 }
107
108 static void
109 gst_rtsp_stream_transport_finalize (GObject * obj)
110 {
111   GstRTSPStreamTransportPrivate *priv;
112   GstRTSPStreamTransport *trans;
113
114   trans = GST_RTSP_STREAM_TRANSPORT (obj);
115   priv = trans->priv;
116
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);
120
121   if (priv->transport)
122     gst_rtsp_transport_free (priv->transport);
123
124   G_OBJECT_CLASS (gst_rtsp_stream_transport_parent_class)->finalize (obj);
125 }
126
127 /**
128  * gst_rtsp_stream_transport_new:
129  * @stream: a #GstRTSPStream
130  * @tr: (transfer full): a GstRTSPTransport
131  *
132  * Create a new #GstRTSPStreamTransport that can be used to manage
133  * @stream with transport @tr.
134  *
135  * Returns: a new #GstRTSPStreamTransport
136  */
137 GstRTSPStreamTransport *
138 gst_rtsp_stream_transport_new (GstRTSPStream * stream, GstRTSPTransport * tr)
139 {
140   GstRTSPStreamTransportPrivate *priv;
141   GstRTSPStreamTransport *trans;
142
143   g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
144   g_return_val_if_fail (tr != NULL, NULL);
145
146   trans = g_object_new (GST_TYPE_RTSP_STREAM_TRANSPORT, NULL);
147   priv = trans->priv;
148   priv->stream = stream;
149   priv->transport = tr;
150
151   return trans;
152 }
153
154 /**
155  * gst_rtsp_stream_transport_get_stream:
156  * @trans: a #GstRTSPStreamTransport
157  *
158  * Get the #GstRTSPStream used when constructing @trans.
159  *
160  * Returns: (transfer none): the stream used when constructing @trans.
161  */
162 GstRTSPStream *
163 gst_rtsp_stream_transport_get_stream (GstRTSPStreamTransport * trans)
164 {
165   g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
166
167   return trans->priv->stream;
168 }
169
170 /**
171  * gst_rtsp_stream_transport_set_callbacks:
172  * @trans: a #GstRTSPStreamTransport
173  * @send_rtp: (scope notified): a callback called when RTP should be sent
174  * @send_rtcp: (scope notified): a callback called when RTCP should be sent
175  * @user_data: user data passed to callbacks
176  * @notify: called with the user_data when no longer needed.
177  *
178  * Install callbacks that will be called when data for a stream should be sent
179  * to a client. This is usually used when sending RTP/RTCP over TCP.
180  */
181 void
182 gst_rtsp_stream_transport_set_callbacks (GstRTSPStreamTransport * trans,
183     GstRTSPSendFunc send_rtp, GstRTSPSendFunc send_rtcp,
184     gpointer user_data, GDestroyNotify notify)
185 {
186   GstRTSPStreamTransportPrivate *priv;
187
188   g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
189
190   priv = trans->priv;
191
192   priv->send_rtp = send_rtp;
193   priv->send_rtcp = send_rtcp;
194   if (priv->notify)
195     priv->notify (priv->user_data);
196   priv->user_data = user_data;
197   priv->notify = notify;
198 }
199
200 /**
201  * gst_rtsp_stream_transport_set_keepalive:
202  * @trans: a #GstRTSPStreamTransport
203  * @keep_alive: a callback called when the receiver is active
204  * @user_data: user data passed to callback
205  * @notify: called with the user_data when no longer needed.
206  *
207  * Install callbacks that will be called when RTCP packets are received from the
208  * receiver of @trans.
209  */
210 void
211 gst_rtsp_stream_transport_set_keepalive (GstRTSPStreamTransport * trans,
212     GstRTSPKeepAliveFunc keep_alive, gpointer user_data, GDestroyNotify notify)
213 {
214   GstRTSPStreamTransportPrivate *priv;
215
216   g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
217
218   priv = trans->priv;
219
220   priv->keep_alive = keep_alive;
221   if (priv->ka_notify)
222     priv->ka_notify (priv->ka_user_data);
223   priv->ka_user_data = user_data;
224   priv->ka_notify = notify;
225 }
226
227
228 /**
229  * gst_rtsp_stream_transport_set_transport:
230  * @trans: a #GstRTSPStreamTransport
231  * @tr: (transfer full): a client #GstRTSPTransport
232  *
233  * Set @tr as the client transport. This function takes ownership of the
234  * passed @tr.
235  */
236 void
237 gst_rtsp_stream_transport_set_transport (GstRTSPStreamTransport * trans,
238     GstRTSPTransport * tr)
239 {
240   GstRTSPStreamTransportPrivate *priv;
241
242   g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
243   g_return_if_fail (tr != NULL);
244
245   priv = trans->priv;
246
247   /* keep track of the transports in the stream. */
248   if (priv->transport)
249     gst_rtsp_transport_free (priv->transport);
250   priv->transport = tr;
251 }
252
253 /**
254  * gst_rtsp_stream_transport_get_transport:
255  * @trans: a #GstRTSPStreamTransport
256  *
257  * Get the transport configured in @trans.
258  *
259  * Returns: (transfer none): the transport configured in @trans. It remains
260  *     valid for as long as @trans is valid.
261  */
262 const GstRTSPTransport *
263 gst_rtsp_stream_transport_get_transport (GstRTSPStreamTransport * trans)
264 {
265   g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
266
267   return trans->priv->transport;
268 }
269
270 /**
271  * gst_rtsp_stream_transport_set_url:
272  * @trans: a #GstRTSPStreamTransport
273  * @url: (transfer none): a client #GstRTSPUrl
274  *
275  * Set @url as the client url.
276  */
277 void
278 gst_rtsp_stream_transport_set_url (GstRTSPStreamTransport * trans,
279     const GstRTSPUrl * url)
280 {
281   GstRTSPStreamTransportPrivate *priv;
282
283   g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
284
285   priv = trans->priv;
286
287   /* keep track of the transports in the stream. */
288   if (priv->url)
289     gst_rtsp_url_free (priv->url);
290   priv->url = (url ? gst_rtsp_url_copy (url) : NULL);
291 }
292
293 /**
294  * gst_rtsp_stream_transport_get_url:
295  * @trans: a #GstRTSPStreamTransport
296  *
297  * Get the url configured in @trans.
298  *
299  * Returns: (transfer none): the url configured in @trans. It remains
300  *     valid for as long as @trans is valid.
301  */
302 const GstRTSPUrl *
303 gst_rtsp_stream_transport_get_url (GstRTSPStreamTransport * trans)
304 {
305   g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
306
307   return trans->priv->url;
308 }
309
310 /**
311  * gst_rtsp_stream_transport_set_active:
312  * @trans: a #GstRTSPStreamTransport
313  * @active: new state of @trans
314  *
315  * Activate or deactivate datatransfer configured in @trans.
316  *
317  * Returns: %TRUE when the state was changed.
318  */
319 gboolean
320 gst_rtsp_stream_transport_set_active (GstRTSPStreamTransport * trans,
321     gboolean active)
322 {
323   GstRTSPStreamTransportPrivate *priv;
324   gboolean res;
325
326   g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
327
328   priv = trans->priv;
329
330   if (priv->active == active)
331     return FALSE;
332
333   if (active)
334     res = gst_rtsp_stream_add_transport (priv->stream, trans);
335   else
336     res = gst_rtsp_stream_remove_transport (priv->stream, trans);
337
338   if (res)
339     priv->active = active;
340
341   return res;
342 }
343
344 /**
345  * gst_rtsp_stream_transport_set_timed_out:
346  * @trans: a #GstRTSPStreamTransport
347  * @timedout: timed out value
348  *
349  * Set the timed out state of @trans to @timedout
350  */
351 void
352 gst_rtsp_stream_transport_set_timed_out (GstRTSPStreamTransport * trans,
353     gboolean timedout)
354 {
355   g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
356
357   trans->priv->timed_out = timedout;
358 }
359
360 /**
361  * gst_rtsp_stream_transport_is_timed_out:
362  * @trans: a #GstRTSPStreamTransport
363  *
364  * Check if @trans is timed out.
365  *
366  * Returns: %TRUE if @trans timed out.
367  */
368 gboolean
369 gst_rtsp_stream_transport_is_timed_out (GstRTSPStreamTransport * trans)
370 {
371   g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), FALSE);
372
373   return trans->priv->timed_out;
374 }
375
376 /**
377  * gst_rtsp_stream_transport_send_rtp:
378  * @trans: a #GstRTSPStreamTransport
379  * @buffer: a #GstBuffer
380  *
381  * Send @buffer to the installed RTP callback for @trans.
382  *
383  * Returns: %TRUE on success
384  */
385 gboolean
386 gst_rtsp_stream_transport_send_rtp (GstRTSPStreamTransport * trans,
387     GstBuffer * buffer)
388 {
389   GstRTSPStreamTransportPrivate *priv;
390   gboolean res = FALSE;
391
392   priv = trans->priv;
393
394   if (priv->send_rtp)
395     res =
396         priv->send_rtp (buffer, priv->transport->interleaved.min,
397         priv->user_data);
398
399   return res;
400 }
401
402 /**
403  * gst_rtsp_stream_transport_send_rtcp:
404  * @trans: a #GstRTSPStreamTransport
405  * @buffer: a #GstBuffer
406  *
407  * Send @buffer to the installed RTCP callback for @trans.
408  *
409  * Returns: %TRUE on success
410  */
411 gboolean
412 gst_rtsp_stream_transport_send_rtcp (GstRTSPStreamTransport * trans,
413     GstBuffer * buffer)
414 {
415   GstRTSPStreamTransportPrivate *priv;
416   gboolean res = FALSE;
417
418   priv = trans->priv;
419
420   if (priv->send_rtcp)
421     res =
422         priv->send_rtcp (buffer, priv->transport->interleaved.max,
423         priv->user_data);
424
425   return res;
426 }
427
428 /**
429  * gst_rtsp_stream_transport_keep_alive:
430  * @trans: a #GstRTSPStreamTransport
431  *
432  * Signal the installed keep_alive callback for @trans.
433  */
434 void
435 gst_rtsp_stream_transport_keep_alive (GstRTSPStreamTransport * trans)
436 {
437   GstRTSPStreamTransportPrivate *priv;
438
439   priv = trans->priv;
440
441   if (priv->keep_alive)
442     priv->keep_alive (priv->ka_user_data);
443 }