88464e9a9b21d425c4253fbec8e6dd8c3807c800
[platform/upstream/gst-plugins-good.git] / gst / rtsp / gstrtspsrc.c
1 /* GStreamer
2  * Copyright (C) <2005,2006> Wim Taymans <wim at fluendo dot com>
3  *               <2006> Lutz Mueller <lutz at topfrose dot de>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 /*
21  * Unless otherwise indicated, Source Code is licensed under MIT license.
22  * See further explanation attached in License Statement (distributed in the file
23  * LICENSE).
24  *
25  * Permission is hereby granted, free of charge, to any person obtaining a copy of
26  * this software and associated documentation files (the "Software"), to deal in
27  * the Software without restriction, including without limitation the rights to
28  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
29  * of the Software, and to permit persons to whom the Software is furnished to do
30  * so, subject to the following conditions:
31  *
32  * The above copyright notice and this permission notice shall be included in all
33  * copies or substantial portions of the Software.
34  *
35  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
41  * SOFTWARE.
42  */
43 /**
44  * SECTION:element-rtspsrc
45  *
46  * Makes a connection to an RTSP server and read the data.
47  * rtspsrc strictly follows RFC 2326 and therefore does not (yet) support
48  * RealMedia/Quicktime/Microsoft extensions.
49  *
50  * RTSP supports transport over TCP or UDP in unicast or multicast mode. By
51  * default rtspsrc will negotiate a connection in the following order:
52  * UDP unicast/UDP multicast/TCP. The order cannot be changed but the allowed
53  * protocols can be controlled with the #GstRTSPSrc:protocols property.
54  *
55  * rtspsrc currently understands SDP as the format of the session description.
56  * For each stream listed in the SDP a new rtp_stream\%d pad will be created
57  * with caps derived from the SDP media description. This is a caps of mime type
58  * "application/x-rtp" that can be connected to any available RTP depayloader
59  * element.
60  *
61  * rtspsrc will internally instantiate an RTP session manager element
62  * that will handle the RTCP messages to and from the server, jitter removal,
63  * packet reordering along with providing a clock for the pipeline.
64  * This feature is implemented using the gstrtpbin element.
65  *
66  * rtspsrc acts like a live source and will therefore only generate data in the
67  * PLAYING state.
68  *
69  * <refsect2>
70  * <title>Example launch line</title>
71  * |[
72  * gst-launch-1.0 rtspsrc location=rtsp://some.server/url ! fakesink
73  * ]| Establish a connection to an RTSP server and send the raw RTP packets to a
74  * fakesink.
75  * </refsect2>
76  */
77
78 #ifdef HAVE_CONFIG_H
79 #include "config.h"
80 #endif
81
82 #ifdef HAVE_UNISTD_H
83 #include <unistd.h>
84 #endif /* HAVE_UNISTD_H */
85 #include <stdlib.h>
86 #include <string.h>
87 #include <stdio.h>
88 #include <stdarg.h>
89
90 #include <gst/net/gstnet.h>
91 #include <gst/sdp/gstsdpmessage.h>
92 #include <gst/sdp/gstmikey.h>
93 #include <gst/rtp/rtp.h>
94
95 #include "gst/gst-i18n-plugin.h"
96
97 #include "gstrtspsrc.h"
98
99 GST_DEBUG_CATEGORY_STATIC (rtspsrc_debug);
100 #define GST_CAT_DEFAULT (rtspsrc_debug)
101
102 static GstStaticPadTemplate rtptemplate = GST_STATIC_PAD_TEMPLATE ("stream_%u",
103     GST_PAD_SRC,
104     GST_PAD_SOMETIMES,
105     GST_STATIC_CAPS ("application/x-rtp; application/x-rdt"));
106
107 /* templates used internally */
108 static GstStaticPadTemplate anysrctemplate =
109 GST_STATIC_PAD_TEMPLATE ("internalsrc_%u",
110     GST_PAD_SRC,
111     GST_PAD_SOMETIMES,
112     GST_STATIC_CAPS_ANY);
113
114 static GstStaticPadTemplate anysinktemplate =
115 GST_STATIC_PAD_TEMPLATE ("internalsink_%u",
116     GST_PAD_SINK,
117     GST_PAD_SOMETIMES,
118     GST_STATIC_CAPS_ANY);
119
120 enum
121 {
122   SIGNAL_HANDLE_REQUEST,
123   SIGNAL_ON_SDP,
124   SIGNAL_SELECT_STREAM,
125   SIGNAL_NEW_MANAGER,
126   SIGNAL_REQUEST_RTCP_KEY,
127   LAST_SIGNAL
128 };
129
130 enum _GstRtspSrcRtcpSyncMode
131 {
132   RTCP_SYNC_ALWAYS,
133   RTCP_SYNC_INITIAL,
134   RTCP_SYNC_RTP
135 };
136
137 enum _GstRtspSrcBufferMode
138 {
139   BUFFER_MODE_NONE,
140   BUFFER_MODE_SLAVE,
141   BUFFER_MODE_BUFFER,
142   BUFFER_MODE_AUTO,
143   BUFFER_MODE_SYNCED
144 };
145
146 #define GST_TYPE_RTSP_SRC_BUFFER_MODE (gst_rtsp_src_buffer_mode_get_type())
147 static GType
148 gst_rtsp_src_buffer_mode_get_type (void)
149 {
150   static GType buffer_mode_type = 0;
151   static const GEnumValue buffer_modes[] = {
152     {BUFFER_MODE_NONE, "Only use RTP timestamps", "none"},
153     {BUFFER_MODE_SLAVE, "Slave receiver to sender clock", "slave"},
154     {BUFFER_MODE_BUFFER, "Do low/high watermark buffering", "buffer"},
155     {BUFFER_MODE_AUTO, "Choose mode depending on stream live", "auto"},
156     {BUFFER_MODE_SYNCED, "Synchronized sender and receiver clocks", "synced"},
157     {0, NULL, NULL},
158   };
159
160   if (!buffer_mode_type) {
161     buffer_mode_type =
162         g_enum_register_static ("GstRTSPSrcBufferMode", buffer_modes);
163   }
164   return buffer_mode_type;
165 }
166
167 enum _GstRtspSrcNtpTimeSource
168 {
169   NTP_TIME_SOURCE_NTP,
170   NTP_TIME_SOURCE_UNIX,
171   NTP_TIME_SOURCE_RUNNING_TIME,
172   NTP_TIME_SOURCE_CLOCK_TIME
173 };
174
175 #define GST_TYPE_RTSP_SRC_NTP_TIME_SOURCE (gst_rtsp_src_ntp_time_source_get_type())
176 static GType
177 gst_rtsp_src_ntp_time_source_get_type (void)
178 {
179   static GType ntp_time_source_type = 0;
180   static const GEnumValue ntp_time_source_values[] = {
181     {NTP_TIME_SOURCE_NTP, "NTP time based on realtime clock", "ntp"},
182     {NTP_TIME_SOURCE_UNIX, "UNIX time based on realtime clock", "unix"},
183     {NTP_TIME_SOURCE_RUNNING_TIME,
184           "Running time based on pipeline clock",
185         "running-time"},
186     {NTP_TIME_SOURCE_CLOCK_TIME, "Pipeline clock time", "clock-time"},
187     {0, NULL, NULL},
188   };
189
190   if (!ntp_time_source_type) {
191     ntp_time_source_type =
192         g_enum_register_static ("GstRTSPSrcNtpTimeSource",
193         ntp_time_source_values);
194   }
195   return ntp_time_source_type;
196 }
197
198 #define AES_128_KEY_LEN 16
199 #define AES_256_KEY_LEN 32
200
201 #define HMAC_32_KEY_LEN 4
202 #define HMAC_80_KEY_LEN 10
203
204 #define DEFAULT_LOCATION         NULL
205 #define DEFAULT_PROTOCOLS        GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | GST_RTSP_LOWER_TRANS_TCP
206 #define DEFAULT_DEBUG            FALSE
207 #define DEFAULT_RETRY            20
208 #define DEFAULT_TIMEOUT          5000000
209 #define DEFAULT_UDP_BUFFER_SIZE  0x80000
210 #define DEFAULT_TCP_TIMEOUT      20000000
211 #define DEFAULT_LATENCY_MS       2000
212 #define DEFAULT_DROP_ON_LATENCY  FALSE
213 #define DEFAULT_CONNECTION_SPEED 0
214 #define DEFAULT_NAT_METHOD       GST_RTSP_NAT_DUMMY
215 #define DEFAULT_DO_RTCP          TRUE
216 #define DEFAULT_DO_RTSP_KEEP_ALIVE       TRUE
217 #define DEFAULT_PROXY            NULL
218 #define DEFAULT_RTP_BLOCKSIZE    0
219 #define DEFAULT_USER_ID          NULL
220 #define DEFAULT_USER_PW          NULL
221 #define DEFAULT_BUFFER_MODE      BUFFER_MODE_AUTO
222 #define DEFAULT_PORT_RANGE       NULL
223 #define DEFAULT_SHORT_HEADER     FALSE
224 #define DEFAULT_PROBATION        2
225 #define DEFAULT_UDP_RECONNECT    TRUE
226 #define DEFAULT_MULTICAST_IFACE  NULL
227 #define DEFAULT_NTP_SYNC         FALSE
228 #define DEFAULT_USE_PIPELINE_CLOCK       FALSE
229 #define DEFAULT_TLS_VALIDATION_FLAGS     G_TLS_CERTIFICATE_VALIDATE_ALL
230 #define DEFAULT_TLS_DATABASE     NULL
231 #define DEFAULT_TLS_INTERACTION     NULL
232 #define DEFAULT_DO_RETRANSMISSION        TRUE
233 #define DEFAULT_NTP_TIME_SOURCE  NTP_TIME_SOURCE_NTP
234 #define DEFAULT_USER_AGENT       "GStreamer/" PACKAGE_VERSION
235 #define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
236
237 enum
238 {
239   PROP_0,
240   PROP_LOCATION,
241   PROP_PROTOCOLS,
242   PROP_DEBUG,
243   PROP_RETRY,
244   PROP_TIMEOUT,
245   PROP_TCP_TIMEOUT,
246   PROP_LATENCY,
247   PROP_DROP_ON_LATENCY,
248   PROP_CONNECTION_SPEED,
249   PROP_NAT_METHOD,
250   PROP_DO_RTCP,
251   PROP_DO_RTSP_KEEP_ALIVE,
252   PROP_PROXY,
253   PROP_PROXY_ID,
254   PROP_PROXY_PW,
255   PROP_RTP_BLOCKSIZE,
256   PROP_USER_ID,
257   PROP_USER_PW,
258   PROP_BUFFER_MODE,
259   PROP_PORT_RANGE,
260   PROP_UDP_BUFFER_SIZE,
261   PROP_SHORT_HEADER,
262   PROP_PROBATION,
263   PROP_UDP_RECONNECT,
264   PROP_MULTICAST_IFACE,
265   PROP_NTP_SYNC,
266   PROP_USE_PIPELINE_CLOCK,
267   PROP_SDES,
268   PROP_TLS_VALIDATION_FLAGS,
269   PROP_TLS_DATABASE,
270   PROP_TLS_INTERACTION,
271   PROP_DO_RETRANSMISSION,
272   PROP_NTP_TIME_SOURCE,
273   PROP_USER_AGENT,
274   PROP_MAX_RTCP_RTP_TIME_DIFF
275 };
276
277 #define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
278 static GType
279 gst_rtsp_nat_method_get_type (void)
280 {
281   static GType rtsp_nat_method_type = 0;
282   static const GEnumValue rtsp_nat_method[] = {
283     {GST_RTSP_NAT_NONE, "None", "none"},
284     {GST_RTSP_NAT_DUMMY, "Send Dummy packets", "dummy"},
285     {0, NULL, NULL},
286   };
287
288   if (!rtsp_nat_method_type) {
289     rtsp_nat_method_type =
290         g_enum_register_static ("GstRTSPNatMethod", rtsp_nat_method);
291   }
292   return rtsp_nat_method_type;
293 }
294
295 static void gst_rtspsrc_finalize (GObject * object);
296
297 static void gst_rtspsrc_set_property (GObject * object, guint prop_id,
298     const GValue * value, GParamSpec * pspec);
299 static void gst_rtspsrc_get_property (GObject * object, guint prop_id,
300     GValue * value, GParamSpec * pspec);
301
302 static GstClock *gst_rtspsrc_provide_clock (GstElement * element);
303
304 static void gst_rtspsrc_uri_handler_init (gpointer g_iface,
305     gpointer iface_data);
306
307 static void gst_rtspsrc_sdp_attributes_to_caps (GArray * attributes,
308     GstCaps * caps);
309
310 static gboolean gst_rtspsrc_set_proxy (GstRTSPSrc * rtsp, const gchar * proxy);
311 static void gst_rtspsrc_set_tcp_timeout (GstRTSPSrc * rtspsrc, guint64 timeout);
312
313 static GstCaps *gst_rtspsrc_media_to_caps (gint pt, const GstSDPMedia * media);
314
315 static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element,
316     GstStateChange transition);
317 static gboolean gst_rtspsrc_send_event (GstElement * element, GstEvent * event);
318 static void gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message);
319
320 static gboolean gst_rtspsrc_setup_auth (GstRTSPSrc * src,
321     GstRTSPMessage * response);
322
323 static gboolean gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd,
324     gint mask);
325 static GstRTSPResult gst_rtspsrc_send_cb (GstRTSPExtension * ext,
326     GstRTSPMessage * request, GstRTSPMessage * response, GstRTSPSrc * src);
327
328 static GstRTSPResult gst_rtspsrc_open (GstRTSPSrc * src, gboolean async);
329 static GstRTSPResult gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment,
330     gboolean async);
331 static GstRTSPResult gst_rtspsrc_pause (GstRTSPSrc * src, gboolean async);
332 static GstRTSPResult gst_rtspsrc_close (GstRTSPSrc * src, gboolean async,
333     gboolean only_close);
334
335 static gboolean gst_rtspsrc_uri_set_uri (GstURIHandler * handler,
336     const gchar * uri, GError ** error);
337 static gchar *gst_rtspsrc_uri_get_uri (GstURIHandler * handler);
338
339 static gboolean gst_rtspsrc_activate_streams (GstRTSPSrc * src);
340 static gboolean gst_rtspsrc_loop (GstRTSPSrc * src);
341 static gboolean gst_rtspsrc_stream_push_event (GstRTSPSrc * src,
342     GstRTSPStream * stream, GstEvent * event);
343 static gboolean gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event);
344 static void gst_rtspsrc_connection_flush (GstRTSPSrc * src, gboolean flush);
345
346 typedef struct
347 {
348   guint8 pt;
349   GstCaps *caps;
350 } PtMapItem;
351
352 /* commands we send to out loop to notify it of events */
353 #define CMD_OPEN        (1 << 0)
354 #define CMD_PLAY        (1 << 1)
355 #define CMD_PAUSE       (1 << 2)
356 #define CMD_CLOSE       (1 << 3)
357 #define CMD_WAIT        (1 << 4)
358 #define CMD_RECONNECT   (1 << 5)
359 #define CMD_LOOP        (1 << 6)
360
361 /* mask for all commands */
362 #define CMD_ALL         ((CMD_LOOP << 1) - 1)
363
364 #define GST_ELEMENT_PROGRESS(el, type, code, text)      \
365 G_STMT_START {                                          \
366   gchar *__txt = _gst_element_error_printf text;        \
367   gst_element_post_message (GST_ELEMENT_CAST (el),      \
368       gst_message_new_progress (GST_OBJECT_CAST (el),   \
369           GST_PROGRESS_TYPE_ ##type, code, __txt));     \
370   g_free (__txt);                                       \
371 } G_STMT_END
372
373 static guint gst_rtspsrc_signals[LAST_SIGNAL] = { 0 };
374
375 #define gst_rtspsrc_parent_class parent_class
376 G_DEFINE_TYPE_WITH_CODE (GstRTSPSrc, gst_rtspsrc, GST_TYPE_BIN,
377     G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_rtspsrc_uri_handler_init));
378
379 #ifndef GST_DISABLE_GST_DEBUG
380 static inline const char *
381 cmd_to_string (guint cmd)
382 {
383   switch (cmd) {
384     case CMD_OPEN:
385       return "OPEN";
386     case CMD_PLAY:
387       return "PLAY";
388     case CMD_PAUSE:
389       return "PAUSE";
390     case CMD_CLOSE:
391       return "CLOSE";
392     case CMD_WAIT:
393       return "WAIT";
394     case CMD_RECONNECT:
395       return "RECONNECT";
396     case CMD_LOOP:
397       return "LOOP";
398   }
399
400   return "unknown";
401 }
402 #endif
403
404 static gboolean
405 default_select_stream (GstRTSPSrc * src, guint id, GstCaps * caps)
406 {
407   GST_DEBUG_OBJECT (src, "default handler");
408   return TRUE;
409 }
410
411 static gboolean
412 select_stream_accum (GSignalInvocationHint * ihint,
413     GValue * return_accu, const GValue * handler_return, gpointer data)
414 {
415   gboolean myboolean;
416
417   myboolean = g_value_get_boolean (handler_return);
418   GST_DEBUG ("accum %d", myboolean);
419   g_value_set_boolean (return_accu, myboolean);
420
421   /* stop emission if FALSE */
422   return myboolean;
423 }
424
425 static void
426 gst_rtspsrc_class_init (GstRTSPSrcClass * klass)
427 {
428   GObjectClass *gobject_class;
429   GstElementClass *gstelement_class;
430   GstBinClass *gstbin_class;
431
432   gobject_class = (GObjectClass *) klass;
433   gstelement_class = (GstElementClass *) klass;
434   gstbin_class = (GstBinClass *) klass;
435
436   GST_DEBUG_CATEGORY_INIT (rtspsrc_debug, "rtspsrc", 0, "RTSP src");
437
438   gobject_class->set_property = gst_rtspsrc_set_property;
439   gobject_class->get_property = gst_rtspsrc_get_property;
440
441   gobject_class->finalize = gst_rtspsrc_finalize;
442
443   g_object_class_install_property (gobject_class, PROP_LOCATION,
444       g_param_spec_string ("location", "RTSP Location",
445           "Location of the RTSP url to read",
446           DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
447
448   g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
449       g_param_spec_flags ("protocols", "Protocols",
450           "Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
451           DEFAULT_PROTOCOLS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
452
453   g_object_class_install_property (gobject_class, PROP_DEBUG,
454       g_param_spec_boolean ("debug", "Debug",
455           "Dump request and response messages to stdout",
456           DEFAULT_DEBUG, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
457
458   g_object_class_install_property (gobject_class, PROP_RETRY,
459       g_param_spec_uint ("retry", "Retry",
460           "Max number of retries when allocating RTP ports.",
461           0, G_MAXUINT16, DEFAULT_RETRY,
462           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
463
464   g_object_class_install_property (gobject_class, PROP_TIMEOUT,
465       g_param_spec_uint64 ("timeout", "Timeout",
466           "Retry TCP transport after UDP timeout microseconds (0 = disabled)",
467           0, G_MAXUINT64, DEFAULT_TIMEOUT,
468           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
469
470   g_object_class_install_property (gobject_class, PROP_TCP_TIMEOUT,
471       g_param_spec_uint64 ("tcp-timeout", "TCP Timeout",
472           "Fail after timeout microseconds on TCP connections (0 = disabled)",
473           0, G_MAXUINT64, DEFAULT_TCP_TIMEOUT,
474           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
475
476   g_object_class_install_property (gobject_class, PROP_LATENCY,
477       g_param_spec_uint ("latency", "Buffer latency in ms",
478           "Amount of ms to buffer", 0, G_MAXUINT, DEFAULT_LATENCY_MS,
479           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
480
481   g_object_class_install_property (gobject_class, PROP_DROP_ON_LATENCY,
482       g_param_spec_boolean ("drop-on-latency",
483           "Drop buffers when maximum latency is reached",
484           "Tells the jitterbuffer to never exceed the given latency in size",
485           DEFAULT_DROP_ON_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
486
487   g_object_class_install_property (gobject_class, PROP_CONNECTION_SPEED,
488       g_param_spec_uint64 ("connection-speed", "Connection Speed",
489           "Network connection speed in kbps (0 = unknown)",
490           0, G_MAXUINT64 / 1000, DEFAULT_CONNECTION_SPEED,
491           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
492
493   g_object_class_install_property (gobject_class, PROP_NAT_METHOD,
494       g_param_spec_enum ("nat-method", "NAT Method",
495           "Method to use for traversing firewalls and NAT",
496           GST_TYPE_RTSP_NAT_METHOD, DEFAULT_NAT_METHOD,
497           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
498
499   /**
500    * GstRTSPSrc:do-rtcp:
501    *
502    * Enable RTCP support. Some old server don't like RTCP and then this property
503    * needs to be set to FALSE.
504    */
505   g_object_class_install_property (gobject_class, PROP_DO_RTCP,
506       g_param_spec_boolean ("do-rtcp", "Do RTCP",
507           "Send RTCP packets, disable for old incompatible server.",
508           DEFAULT_DO_RTCP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
509
510   /**
511    * GstRTSPSrc:do-rtsp-keep-alive:
512    *
513    * Enable RTSP keep alive support. Some old server don't like RTSP
514    * keep alive and then this property needs to be set to FALSE.
515    */
516   g_object_class_install_property (gobject_class, PROP_DO_RTSP_KEEP_ALIVE,
517       g_param_spec_boolean ("do-rtsp-keep-alive", "Do RTSP Keep Alive",
518           "Send RTSP keep alive packets, disable for old incompatible server.",
519           DEFAULT_DO_RTSP_KEEP_ALIVE,
520           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
521
522   /**
523    * GstRTSPSrc:proxy:
524    *
525    * Set the proxy parameters. This has to be a string of the format
526    * [http://][user:passwd@]host[:port].
527    */
528   g_object_class_install_property (gobject_class, PROP_PROXY,
529       g_param_spec_string ("proxy", "Proxy",
530           "Proxy settings for HTTP tunneling. Format: [http://][user:passwd@]host[:port]",
531           DEFAULT_PROXY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
532   /**
533    * GstRTSPSrc:proxy-id:
534    *
535    * Sets the proxy URI user id for authentication. If the URI set via the
536    * "proxy" property contains a user-id already, that will take precedence.
537    *
538    * Since: 1.2
539    */
540   g_object_class_install_property (gobject_class, PROP_PROXY_ID,
541       g_param_spec_string ("proxy-id", "proxy-id",
542           "HTTP proxy URI user id for authentication", "",
543           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
544   /**
545    * GstRTSPSrc:proxy-pw:
546    *
547    * Sets the proxy URI password for authentication. If the URI set via the
548    * "proxy" property contains a password already, that will take precedence.
549    *
550    * Since: 1.2
551    */
552   g_object_class_install_property (gobject_class, PROP_PROXY_PW,
553       g_param_spec_string ("proxy-pw", "proxy-pw",
554           "HTTP proxy URI user password for authentication", "",
555           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
556
557   /**
558    * GstRTSPSrc:rtp-blocksize:
559    *
560    * RTP package size to suggest to server.
561    */
562   g_object_class_install_property (gobject_class, PROP_RTP_BLOCKSIZE,
563       g_param_spec_uint ("rtp-blocksize", "RTP Blocksize",
564           "RTP package size to suggest to server (0 = disabled)",
565           0, 65536, DEFAULT_RTP_BLOCKSIZE,
566           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
567
568   g_object_class_install_property (gobject_class,
569       PROP_USER_ID,
570       g_param_spec_string ("user-id", "user-id",
571           "RTSP location URI user id for authentication", DEFAULT_USER_ID,
572           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
573   g_object_class_install_property (gobject_class, PROP_USER_PW,
574       g_param_spec_string ("user-pw", "user-pw",
575           "RTSP location URI user password for authentication", DEFAULT_USER_PW,
576           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
577
578   /**
579    * GstRTSPSrc:buffer-mode:
580    *
581    * Control the buffering and timestamping mode used by the jitterbuffer.
582    */
583   g_object_class_install_property (gobject_class, PROP_BUFFER_MODE,
584       g_param_spec_enum ("buffer-mode", "Buffer Mode",
585           "Control the buffering algorithm in use",
586           GST_TYPE_RTSP_SRC_BUFFER_MODE, DEFAULT_BUFFER_MODE,
587           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
588
589   /**
590    * GstRTSPSrc:port-range:
591    *
592    * Configure the client port numbers that can be used to recieve RTP and
593    * RTCP.
594    */
595   g_object_class_install_property (gobject_class, PROP_PORT_RANGE,
596       g_param_spec_string ("port-range", "Port range",
597           "Client port range that can be used to receive RTP and RTCP data, "
598           "eg. 3000-3005 (NULL = no restrictions)", DEFAULT_PORT_RANGE,
599           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
600
601   /**
602    * GstRTSPSrc:udp-buffer-size:
603    *
604    * Size of the kernel UDP receive buffer in bytes.
605    */
606   g_object_class_install_property (gobject_class, PROP_UDP_BUFFER_SIZE,
607       g_param_spec_int ("udp-buffer-size", "UDP Buffer Size",
608           "Size of the kernel UDP receive buffer in bytes, 0=default",
609           0, G_MAXINT, DEFAULT_UDP_BUFFER_SIZE,
610           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
611
612   /**
613    * GstRTSPSrc:short-header:
614    *
615    * Only send the basic RTSP headers for broken encoders.
616    */
617   g_object_class_install_property (gobject_class, PROP_SHORT_HEADER,
618       g_param_spec_boolean ("short-header", "Short Header",
619           "Only send the basic RTSP headers for broken encoders",
620           DEFAULT_SHORT_HEADER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
621
622   g_object_class_install_property (gobject_class, PROP_PROBATION,
623       g_param_spec_uint ("probation", "Number of probations",
624           "Consecutive packet sequence numbers to accept the source",
625           0, G_MAXUINT, DEFAULT_PROBATION,
626           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
627
628   g_object_class_install_property (gobject_class, PROP_UDP_RECONNECT,
629       g_param_spec_boolean ("udp-reconnect", "Reconnect to the server",
630           "Reconnect to the server if RTSP connection is closed when doing UDP",
631           DEFAULT_UDP_RECONNECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
632
633   g_object_class_install_property (gobject_class, PROP_MULTICAST_IFACE,
634       g_param_spec_string ("multicast-iface", "Multicast Interface",
635           "The network interface on which to join the multicast group",
636           DEFAULT_MULTICAST_IFACE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
637
638   g_object_class_install_property (gobject_class, PROP_NTP_SYNC,
639       g_param_spec_boolean ("ntp-sync", "Sync on NTP clock",
640           "Synchronize received streams to the NTP clock", DEFAULT_NTP_SYNC,
641           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
642
643   g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
644       g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
645           "Use the pipeline running-time to set the NTP time in the RTCP SR messages"
646           "(DEPRECATED: Use ntp-time-source property)",
647           DEFAULT_USE_PIPELINE_CLOCK,
648           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED));
649
650   g_object_class_install_property (gobject_class, PROP_SDES,
651       g_param_spec_boxed ("sdes", "SDES",
652           "The SDES items of this session",
653           GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
654
655   /**
656    * GstRTSPSrc::tls-validation-flags:
657    *
658    * TLS certificate validation flags used to validate server
659    * certificate.
660    *
661    * Since: 1.2.1
662    */
663   g_object_class_install_property (gobject_class, PROP_TLS_VALIDATION_FLAGS,
664       g_param_spec_flags ("tls-validation-flags", "TLS validation flags",
665           "TLS certificate validation flags used to validate the server certificate",
666           G_TYPE_TLS_CERTIFICATE_FLAGS, DEFAULT_TLS_VALIDATION_FLAGS,
667           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
668
669   /**
670    * GstRTSPSrc::tls-database:
671    *
672    * TLS database with anchor certificate authorities used to validate
673    * the server certificate.
674    *
675    * Since: 1.4
676    */
677   g_object_class_install_property (gobject_class, PROP_TLS_DATABASE,
678       g_param_spec_object ("tls-database", "TLS database",
679           "TLS database with anchor certificate authorities used to validate the server certificate",
680           G_TYPE_TLS_DATABASE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
681
682   /**
683    * GstRTSPSrc::tls-interaction:
684    *
685    * A #GTlsInteraction object to be used when the connection or certificate
686    * database need to interact with the user. This will be used to prompt the
687    * user for passwords where necessary.
688    *
689    * Since: 1.6
690    */
691   g_object_class_install_property (gobject_class, PROP_TLS_INTERACTION,
692       g_param_spec_object ("tls-interaction", "TLS interaction",
693           "A GTlsInteraction object to promt the user for password or certificate",
694           G_TYPE_TLS_INTERACTION, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
695
696   /**
697    * GstRTSPSrc::do-retransmission:
698    *
699    * Attempt to ask the server to retransmit lost packets according to RFC4588.
700    *
701    * Note: currently only works with SSRC-multiplexed retransmission streams
702    *
703    * Since: 1.6
704    */
705   g_object_class_install_property (gobject_class, PROP_DO_RETRANSMISSION,
706       g_param_spec_boolean ("do-retransmission", "Retransmission",
707           "Ask the server to retransmit lost packets",
708           DEFAULT_DO_RETRANSMISSION,
709           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
710
711   /**
712    * GstRTSPSrc::ntp-time-source:
713    *
714    * allows to select the time source that should be used
715    * for the NTP time in RTCP packets
716    *
717    * Since: 1.6
718    */
719   g_object_class_install_property (gobject_class, PROP_NTP_TIME_SOURCE,
720       g_param_spec_enum ("ntp-time-source", "NTP Time Source",
721           "NTP time source for RTCP packets",
722           GST_TYPE_RTSP_SRC_NTP_TIME_SOURCE, DEFAULT_NTP_TIME_SOURCE,
723           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
724
725   /**
726    * GstRTSPSrc::user-agent:
727    *
728    * The string to set in the User-Agent header.
729    *
730    * Since: 1.6
731    */
732   g_object_class_install_property (gobject_class, PROP_USER_AGENT,
733       g_param_spec_string ("user-agent", "User Agent",
734           "The User-Agent string to send to the server",
735           DEFAULT_USER_AGENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
736
737   g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
738       g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
739           "Maximum amount of time in ms that the RTP time in RTCP SRs "
740           "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
741           DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
742           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
743
744   /**
745    * GstRTSPSrc::handle-request:
746    * @rtspsrc: a #GstRTSPSrc
747    * @request: a #GstRTSPMessage
748    * @response: a #GstRTSPMessage
749    *
750    * Handle a server request in @request and prepare @response.
751    *
752    * This signal is called from the streaming thread, you should therefore not
753    * do any state changes on @rtspsrc because this might deadlock. If you want
754    * to modify the state as a result of this signal, post a
755    * #GST_MESSAGE_REQUEST_STATE message on the bus or signal the main thread
756    * in some other way.
757    *
758    * Since: 1.2
759    */
760   gst_rtspsrc_signals[SIGNAL_HANDLE_REQUEST] =
761       g_signal_new ("handle-request", G_TYPE_FROM_CLASS (klass), 0,
762       0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
763       G_TYPE_POINTER, G_TYPE_POINTER);
764
765   /**
766    * GstRTSPSrc::on-sdp:
767    * @rtspsrc: a #GstRTSPSrc
768    * @sdp: a #GstSDPMessage
769    *
770    * Emited when the client has retrieved the SDP and before it configures the
771    * streams in the SDP. @sdp can be inspected and modified.
772    *
773    * This signal is called from the streaming thread, you should therefore not
774    * do any state changes on @rtspsrc because this might deadlock. If you want
775    * to modify the state as a result of this signal, post a
776    * #GST_MESSAGE_REQUEST_STATE message on the bus or signal the main thread
777    * in some other way.
778    *
779    * Since: 1.2
780    */
781   gst_rtspsrc_signals[SIGNAL_ON_SDP] =
782       g_signal_new ("on-sdp", G_TYPE_FROM_CLASS (klass), 0,
783       0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1,
784       GST_TYPE_SDP_MESSAGE | G_SIGNAL_TYPE_STATIC_SCOPE);
785
786   /**
787    * GstRTSPSrc::select-stream:
788    * @rtspsrc: a #GstRTSPSrc
789    * @num: the stream number
790    * @caps: the stream caps
791    *
792    * Emited before the client decides to configure the stream @num with
793    * @caps.
794    *
795    * Returns: %TRUE when the stream should be selected, %FALSE when the stream
796    * is to be ignored.
797    *
798    * Since: 1.2
799    */
800   gst_rtspsrc_signals[SIGNAL_SELECT_STREAM] =
801       g_signal_new_class_handler ("select-stream", G_TYPE_FROM_CLASS (klass),
802       G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_CLEANUP,
803       (GCallback) default_select_stream, select_stream_accum, NULL,
804       g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 2, G_TYPE_UINT,
805       GST_TYPE_CAPS);
806   /**
807    * GstRTSPSrc::new-manager:
808    * @rtspsrc: a #GstRTSPSrc
809    * @manager: a #GstElement
810    *
811    * Emited after a new manager (like rtpbin) was created and the default
812    * properties were configured.
813    *
814    * Since: 1.4
815    */
816   gst_rtspsrc_signals[SIGNAL_NEW_MANAGER] =
817       g_signal_new_class_handler ("new-manager", G_TYPE_FROM_CLASS (klass),
818       G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_CLEANUP, 0, NULL, NULL,
819       g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
820
821   /**
822    * GstRTSPSrc::request-rtcp-key:
823    * @rtspsrc: a #GstRTSPSrc
824    * @num: the stream number
825    *
826    * Signal emited to get the crypto parameters relevant to the RTCP
827    * stream. User should provide the key and the RTCP encryption ciphers
828    * and authentication, and return them wrapped in a GstCaps.
829    *
830    * Since: 1.4
831    */
832   gst_rtspsrc_signals[SIGNAL_REQUEST_RTCP_KEY] =
833       g_signal_new ("request-rtcp-key", G_TYPE_FROM_CLASS (klass),
834       G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, GST_TYPE_CAPS, 1, G_TYPE_UINT);
835
836   gstelement_class->send_event = gst_rtspsrc_send_event;
837   gstelement_class->provide_clock = gst_rtspsrc_provide_clock;
838   gstelement_class->change_state = gst_rtspsrc_change_state;
839
840   gst_element_class_add_pad_template (gstelement_class,
841       gst_static_pad_template_get (&rtptemplate));
842
843   gst_element_class_set_static_metadata (gstelement_class,
844       "RTSP packet receiver", "Source/Network",
845       "Receive data over the network via RTSP (RFC 2326)",
846       "Wim Taymans <wim@fluendo.com>, "
847       "Thijs Vermeir <thijs.vermeir@barco.com>, "
848       "Lutz Mueller <lutz@topfrose.de>");
849
850   gstbin_class->handle_message = gst_rtspsrc_handle_message;
851
852   gst_rtsp_ext_list_init ();
853 }
854
855 static void
856 gst_rtspsrc_init (GstRTSPSrc * src)
857 {
858   src->conninfo.location = g_strdup (DEFAULT_LOCATION);
859   src->protocols = DEFAULT_PROTOCOLS;
860   src->debug = DEFAULT_DEBUG;
861   src->retry = DEFAULT_RETRY;
862   src->udp_timeout = DEFAULT_TIMEOUT;
863   gst_rtspsrc_set_tcp_timeout (src, DEFAULT_TCP_TIMEOUT);
864   src->latency = DEFAULT_LATENCY_MS;
865   src->drop_on_latency = DEFAULT_DROP_ON_LATENCY;
866   src->connection_speed = DEFAULT_CONNECTION_SPEED;
867   src->nat_method = DEFAULT_NAT_METHOD;
868   src->do_rtcp = DEFAULT_DO_RTCP;
869   src->do_rtsp_keep_alive = DEFAULT_DO_RTSP_KEEP_ALIVE;
870   gst_rtspsrc_set_proxy (src, DEFAULT_PROXY);
871   src->rtp_blocksize = DEFAULT_RTP_BLOCKSIZE;
872   src->user_id = g_strdup (DEFAULT_USER_ID);
873   src->user_pw = g_strdup (DEFAULT_USER_PW);
874   src->buffer_mode = DEFAULT_BUFFER_MODE;
875   src->client_port_range.min = 0;
876   src->client_port_range.max = 0;
877   src->udp_buffer_size = DEFAULT_UDP_BUFFER_SIZE;
878   src->short_header = DEFAULT_SHORT_HEADER;
879   src->probation = DEFAULT_PROBATION;
880   src->udp_reconnect = DEFAULT_UDP_RECONNECT;
881   src->multi_iface = g_strdup (DEFAULT_MULTICAST_IFACE);
882   src->ntp_sync = DEFAULT_NTP_SYNC;
883   src->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
884   src->sdes = NULL;
885   src->tls_validation_flags = DEFAULT_TLS_VALIDATION_FLAGS;
886   src->tls_database = DEFAULT_TLS_DATABASE;
887   src->tls_interaction = DEFAULT_TLS_INTERACTION;
888   src->do_retransmission = DEFAULT_DO_RETRANSMISSION;
889   src->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
890   src->user_agent = g_strdup (DEFAULT_USER_AGENT);
891   src->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
892
893   /* get a list of all extensions */
894   src->extensions = gst_rtsp_ext_list_get ();
895
896   /* connect to send signal */
897   gst_rtsp_ext_list_connect (src->extensions, "send",
898       (GCallback) gst_rtspsrc_send_cb, src);
899
900   /* protects the streaming thread in interleaved mode or the polling
901    * thread in UDP mode. */
902   g_rec_mutex_init (&src->stream_rec_lock);
903
904   /* protects our state changes from multiple invocations */
905   g_rec_mutex_init (&src->state_rec_lock);
906
907   src->state = GST_RTSP_STATE_INVALID;
908
909   GST_OBJECT_FLAG_SET (src, GST_ELEMENT_FLAG_SOURCE);
910 }
911
912 static void
913 gst_rtspsrc_finalize (GObject * object)
914 {
915   GstRTSPSrc *rtspsrc;
916
917   rtspsrc = GST_RTSPSRC (object);
918
919   gst_rtsp_ext_list_free (rtspsrc->extensions);
920   g_free (rtspsrc->conninfo.location);
921   gst_rtsp_url_free (rtspsrc->conninfo.url);
922   g_free (rtspsrc->conninfo.url_str);
923   g_free (rtspsrc->user_id);
924   g_free (rtspsrc->user_pw);
925   g_free (rtspsrc->multi_iface);
926   g_free (rtspsrc->user_agent);
927
928   if (rtspsrc->sdp) {
929     gst_sdp_message_free (rtspsrc->sdp);
930     rtspsrc->sdp = NULL;
931   }
932   if (rtspsrc->provided_clock)
933     gst_object_unref (rtspsrc->provided_clock);
934
935   if (rtspsrc->sdes)
936     gst_structure_free (rtspsrc->sdes);
937
938   if (rtspsrc->tls_database)
939     g_object_unref (rtspsrc->tls_database);
940
941   if (rtspsrc->tls_interaction)
942     g_object_unref (rtspsrc->tls_interaction);
943
944   /* free locks */
945   g_rec_mutex_clear (&rtspsrc->stream_rec_lock);
946   g_rec_mutex_clear (&rtspsrc->state_rec_lock);
947
948   G_OBJECT_CLASS (parent_class)->finalize (object);
949 }
950
951 static GstClock *
952 gst_rtspsrc_provide_clock (GstElement * element)
953 {
954   GstRTSPSrc *src = GST_RTSPSRC (element);
955   GstClock *clock;
956
957   if ((clock = src->provided_clock) != NULL)
958     gst_object_ref (clock);
959
960   return clock;
961 }
962
963 /* a proxy string of the format [user:passwd@]host[:port] */
964 static gboolean
965 gst_rtspsrc_set_proxy (GstRTSPSrc * rtsp, const gchar * proxy)
966 {
967   gchar *p, *at, *col;
968
969   g_free (rtsp->proxy_user);
970   rtsp->proxy_user = NULL;
971   g_free (rtsp->proxy_passwd);
972   rtsp->proxy_passwd = NULL;
973   g_free (rtsp->proxy_host);
974   rtsp->proxy_host = NULL;
975   rtsp->proxy_port = 0;
976
977   p = (gchar *) proxy;
978
979   if (p == NULL)
980     return TRUE;
981
982   /* we allow http:// in front but ignore it */
983   if (g_str_has_prefix (p, "http://"))
984     p += 7;
985
986   at = strchr (p, '@');
987   if (at) {
988     /* look for user:passwd */
989     col = strchr (proxy, ':');
990     if (col == NULL || col > at)
991       return FALSE;
992
993     rtsp->proxy_user = g_strndup (p, col - p);
994     col++;
995     rtsp->proxy_passwd = g_strndup (col, at - col);
996
997     /* move to host */
998     p = at + 1;
999   } else {
1000     if (rtsp->prop_proxy_id != NULL && *rtsp->prop_proxy_id != '\0')
1001       rtsp->proxy_user = g_strdup (rtsp->prop_proxy_id);
1002     if (rtsp->prop_proxy_pw != NULL && *rtsp->prop_proxy_pw != '\0')
1003       rtsp->proxy_passwd = g_strdup (rtsp->prop_proxy_pw);
1004     if (rtsp->proxy_user != NULL || rtsp->proxy_passwd != NULL) {
1005       GST_LOG_OBJECT (rtsp, "set proxy user/pw from properties: %s:%s",
1006           GST_STR_NULL (rtsp->proxy_user), GST_STR_NULL (rtsp->proxy_passwd));
1007     }
1008   }
1009   col = strchr (p, ':');
1010
1011   if (col) {
1012     /* everything before the colon is the hostname */
1013     rtsp->proxy_host = g_strndup (p, col - p);
1014     p = col + 1;
1015     rtsp->proxy_port = strtoul (p, (char **) &p, 10);
1016   } else {
1017     rtsp->proxy_host = g_strdup (p);
1018     rtsp->proxy_port = 8080;
1019   }
1020   return TRUE;
1021 }
1022
1023 static void
1024 gst_rtspsrc_set_tcp_timeout (GstRTSPSrc * rtspsrc, guint64 timeout)
1025 {
1026   rtspsrc->tcp_timeout.tv_sec = timeout / G_USEC_PER_SEC;
1027   rtspsrc->tcp_timeout.tv_usec = timeout % G_USEC_PER_SEC;
1028
1029   if (timeout != 0)
1030     rtspsrc->ptcp_timeout = &rtspsrc->tcp_timeout;
1031   else
1032     rtspsrc->ptcp_timeout = NULL;
1033 }
1034
1035 static void
1036 gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
1037     GParamSpec * pspec)
1038 {
1039   GstRTSPSrc *rtspsrc;
1040
1041   rtspsrc = GST_RTSPSRC (object);
1042
1043   switch (prop_id) {
1044     case PROP_LOCATION:
1045       gst_rtspsrc_uri_set_uri (GST_URI_HANDLER (rtspsrc),
1046           g_value_get_string (value), NULL);
1047       break;
1048     case PROP_PROTOCOLS:
1049       rtspsrc->protocols = g_value_get_flags (value);
1050       break;
1051     case PROP_DEBUG:
1052       rtspsrc->debug = g_value_get_boolean (value);
1053       break;
1054     case PROP_RETRY:
1055       rtspsrc->retry = g_value_get_uint (value);
1056       break;
1057     case PROP_TIMEOUT:
1058       rtspsrc->udp_timeout = g_value_get_uint64 (value);
1059       break;
1060     case PROP_TCP_TIMEOUT:
1061       gst_rtspsrc_set_tcp_timeout (rtspsrc, g_value_get_uint64 (value));
1062       break;
1063     case PROP_LATENCY:
1064       rtspsrc->latency = g_value_get_uint (value);
1065       break;
1066     case PROP_DROP_ON_LATENCY:
1067       rtspsrc->drop_on_latency = g_value_get_boolean (value);
1068       break;
1069     case PROP_CONNECTION_SPEED:
1070       rtspsrc->connection_speed = g_value_get_uint64 (value);
1071       break;
1072     case PROP_NAT_METHOD:
1073       rtspsrc->nat_method = g_value_get_enum (value);
1074       break;
1075     case PROP_DO_RTCP:
1076       rtspsrc->do_rtcp = g_value_get_boolean (value);
1077       break;
1078     case PROP_DO_RTSP_KEEP_ALIVE:
1079       rtspsrc->do_rtsp_keep_alive = g_value_get_boolean (value);
1080       break;
1081     case PROP_PROXY:
1082       gst_rtspsrc_set_proxy (rtspsrc, g_value_get_string (value));
1083       break;
1084     case PROP_PROXY_ID:
1085       if (rtspsrc->prop_proxy_id)
1086         g_free (rtspsrc->prop_proxy_id);
1087       rtspsrc->prop_proxy_id = g_value_dup_string (value);
1088       break;
1089     case PROP_PROXY_PW:
1090       if (rtspsrc->prop_proxy_pw)
1091         g_free (rtspsrc->prop_proxy_pw);
1092       rtspsrc->prop_proxy_pw = g_value_dup_string (value);
1093       break;
1094     case PROP_RTP_BLOCKSIZE:
1095       rtspsrc->rtp_blocksize = g_value_get_uint (value);
1096       break;
1097     case PROP_USER_ID:
1098       if (rtspsrc->user_id)
1099         g_free (rtspsrc->user_id);
1100       rtspsrc->user_id = g_value_dup_string (value);
1101       break;
1102     case PROP_USER_PW:
1103       if (rtspsrc->user_pw)
1104         g_free (rtspsrc->user_pw);
1105       rtspsrc->user_pw = g_value_dup_string (value);
1106       break;
1107     case PROP_BUFFER_MODE:
1108       rtspsrc->buffer_mode = g_value_get_enum (value);
1109       break;
1110     case PROP_PORT_RANGE:
1111     {
1112       const gchar *str;
1113
1114       str = g_value_get_string (value);
1115       if (str) {
1116         sscanf (str, "%u-%u",
1117             &rtspsrc->client_port_range.min, &rtspsrc->client_port_range.max);
1118       } else {
1119         rtspsrc->client_port_range.min = 0;
1120         rtspsrc->client_port_range.max = 0;
1121       }
1122       break;
1123     }
1124     case PROP_UDP_BUFFER_SIZE:
1125       rtspsrc->udp_buffer_size = g_value_get_int (value);
1126       break;
1127     case PROP_SHORT_HEADER:
1128       rtspsrc->short_header = g_value_get_boolean (value);
1129       break;
1130     case PROP_PROBATION:
1131       rtspsrc->probation = g_value_get_uint (value);
1132       break;
1133     case PROP_UDP_RECONNECT:
1134       rtspsrc->udp_reconnect = g_value_get_boolean (value);
1135       break;
1136     case PROP_MULTICAST_IFACE:
1137       g_free (rtspsrc->multi_iface);
1138
1139       if (g_value_get_string (value) == NULL)
1140         rtspsrc->multi_iface = g_strdup (DEFAULT_MULTICAST_IFACE);
1141       else
1142         rtspsrc->multi_iface = g_value_dup_string (value);
1143       break;
1144     case PROP_NTP_SYNC:
1145       rtspsrc->ntp_sync = g_value_get_boolean (value);
1146       break;
1147     case PROP_USE_PIPELINE_CLOCK:
1148       rtspsrc->use_pipeline_clock = g_value_get_boolean (value);
1149       break;
1150     case PROP_SDES:
1151       rtspsrc->sdes = g_value_dup_boxed (value);
1152       break;
1153     case PROP_TLS_VALIDATION_FLAGS:
1154       rtspsrc->tls_validation_flags = g_value_get_flags (value);
1155       break;
1156     case PROP_TLS_DATABASE:
1157       g_clear_object (&rtspsrc->tls_database);
1158       rtspsrc->tls_database = g_value_dup_object (value);
1159       break;
1160     case PROP_TLS_INTERACTION:
1161       g_clear_object (&rtspsrc->tls_interaction);
1162       rtspsrc->tls_interaction = g_value_dup_object (value);
1163       break;
1164     case PROP_DO_RETRANSMISSION:
1165       rtspsrc->do_retransmission = g_value_get_boolean (value);
1166       break;
1167     case PROP_NTP_TIME_SOURCE:
1168       rtspsrc->ntp_time_source = g_value_get_enum (value);
1169       break;
1170     case PROP_USER_AGENT:
1171       g_free (rtspsrc->user_agent);
1172       rtspsrc->user_agent = g_value_dup_string (value);
1173       break;
1174     case PROP_MAX_RTCP_RTP_TIME_DIFF:
1175       rtspsrc->max_rtcp_rtp_time_diff = g_value_get_int (value);
1176       break;
1177     default:
1178       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1179       break;
1180   }
1181 }
1182
1183 static void
1184 gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
1185     GParamSpec * pspec)
1186 {
1187   GstRTSPSrc *rtspsrc;
1188
1189   rtspsrc = GST_RTSPSRC (object);
1190
1191   switch (prop_id) {
1192     case PROP_LOCATION:
1193       g_value_set_string (value, rtspsrc->conninfo.location);
1194       break;
1195     case PROP_PROTOCOLS:
1196       g_value_set_flags (value, rtspsrc->protocols);
1197       break;
1198     case PROP_DEBUG:
1199       g_value_set_boolean (value, rtspsrc->debug);
1200       break;
1201     case PROP_RETRY:
1202       g_value_set_uint (value, rtspsrc->retry);
1203       break;
1204     case PROP_TIMEOUT:
1205       g_value_set_uint64 (value, rtspsrc->udp_timeout);
1206       break;
1207     case PROP_TCP_TIMEOUT:
1208     {
1209       guint64 timeout;
1210
1211       timeout = rtspsrc->tcp_timeout.tv_sec * G_USEC_PER_SEC +
1212           rtspsrc->tcp_timeout.tv_usec;
1213       g_value_set_uint64 (value, timeout);
1214       break;
1215     }
1216     case PROP_LATENCY:
1217       g_value_set_uint (value, rtspsrc->latency);
1218       break;
1219     case PROP_DROP_ON_LATENCY:
1220       g_value_set_boolean (value, rtspsrc->drop_on_latency);
1221       break;
1222     case PROP_CONNECTION_SPEED:
1223       g_value_set_uint64 (value, rtspsrc->connection_speed);
1224       break;
1225     case PROP_NAT_METHOD:
1226       g_value_set_enum (value, rtspsrc->nat_method);
1227       break;
1228     case PROP_DO_RTCP:
1229       g_value_set_boolean (value, rtspsrc->do_rtcp);
1230       break;
1231     case PROP_DO_RTSP_KEEP_ALIVE:
1232       g_value_set_boolean (value, rtspsrc->do_rtsp_keep_alive);
1233       break;
1234     case PROP_PROXY:
1235     {
1236       gchar *str;
1237
1238       if (rtspsrc->proxy_host) {
1239         str =
1240             g_strdup_printf ("%s:%d", rtspsrc->proxy_host, rtspsrc->proxy_port);
1241       } else {
1242         str = NULL;
1243       }
1244       g_value_take_string (value, str);
1245       break;
1246     }
1247     case PROP_PROXY_ID:
1248       g_value_set_string (value, rtspsrc->prop_proxy_id);
1249       break;
1250     case PROP_PROXY_PW:
1251       g_value_set_string (value, rtspsrc->prop_proxy_pw);
1252       break;
1253     case PROP_RTP_BLOCKSIZE:
1254       g_value_set_uint (value, rtspsrc->rtp_blocksize);
1255       break;
1256     case PROP_USER_ID:
1257       g_value_set_string (value, rtspsrc->user_id);
1258       break;
1259     case PROP_USER_PW:
1260       g_value_set_string (value, rtspsrc->user_pw);
1261       break;
1262     case PROP_BUFFER_MODE:
1263       g_value_set_enum (value, rtspsrc->buffer_mode);
1264       break;
1265     case PROP_PORT_RANGE:
1266     {
1267       gchar *str;
1268
1269       if (rtspsrc->client_port_range.min != 0) {
1270         str = g_strdup_printf ("%u-%u", rtspsrc->client_port_range.min,
1271             rtspsrc->client_port_range.max);
1272       } else {
1273         str = NULL;
1274       }
1275       g_value_take_string (value, str);
1276       break;
1277     }
1278     case PROP_UDP_BUFFER_SIZE:
1279       g_value_set_int (value, rtspsrc->udp_buffer_size);
1280       break;
1281     case PROP_SHORT_HEADER:
1282       g_value_set_boolean (value, rtspsrc->short_header);
1283       break;
1284     case PROP_PROBATION:
1285       g_value_set_uint (value, rtspsrc->probation);
1286       break;
1287     case PROP_UDP_RECONNECT:
1288       g_value_set_boolean (value, rtspsrc->udp_reconnect);
1289       break;
1290     case PROP_MULTICAST_IFACE:
1291       g_value_set_string (value, rtspsrc->multi_iface);
1292       break;
1293     case PROP_NTP_SYNC:
1294       g_value_set_boolean (value, rtspsrc->ntp_sync);
1295       break;
1296     case PROP_USE_PIPELINE_CLOCK:
1297       g_value_set_boolean (value, rtspsrc->use_pipeline_clock);
1298       break;
1299     case PROP_SDES:
1300       g_value_set_boxed (value, rtspsrc->sdes);
1301       break;
1302     case PROP_TLS_VALIDATION_FLAGS:
1303       g_value_set_flags (value, rtspsrc->tls_validation_flags);
1304       break;
1305     case PROP_TLS_DATABASE:
1306       g_value_set_object (value, rtspsrc->tls_database);
1307       break;
1308     case PROP_TLS_INTERACTION:
1309       g_value_set_object (value, rtspsrc->tls_interaction);
1310       break;
1311     case PROP_DO_RETRANSMISSION:
1312       g_value_set_boolean (value, rtspsrc->do_retransmission);
1313       break;
1314     case PROP_NTP_TIME_SOURCE:
1315       g_value_set_enum (value, rtspsrc->ntp_time_source);
1316       break;
1317     case PROP_USER_AGENT:
1318       g_value_set_string (value, rtspsrc->user_agent);
1319       break;
1320     case PROP_MAX_RTCP_RTP_TIME_DIFF:
1321       g_value_set_int (value, rtspsrc->max_rtcp_rtp_time_diff);
1322       break;
1323     default:
1324       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1325       break;
1326   }
1327 }
1328
1329 static gint
1330 find_stream_by_id (GstRTSPStream * stream, gint * id)
1331 {
1332   if (stream->id == *id)
1333     return 0;
1334
1335   return -1;
1336 }
1337
1338 static gint
1339 find_stream_by_channel (GstRTSPStream * stream, gint * channel)
1340 {
1341   if (stream->channel[0] == *channel || stream->channel[1] == *channel)
1342     return 0;
1343
1344   return -1;
1345 }
1346
1347 static gint
1348 find_stream_by_udpsrc (GstRTSPStream * stream, gconstpointer a)
1349 {
1350   GstElement *src = (GstElement *) a;
1351
1352   if (stream->udpsrc[0] == src)
1353     return 0;
1354   if (stream->udpsrc[1] == src)
1355     return 0;
1356
1357   return -1;
1358 }
1359
1360 static gint
1361 find_stream_by_setup (GstRTSPStream * stream, gconstpointer a)
1362 {
1363   if (stream->conninfo.location) {
1364     /* check qualified setup_url */
1365     if (!strcmp (stream->conninfo.location, (gchar *) a))
1366       return 0;
1367   }
1368   if (stream->control_url) {
1369     /* check original control_url */
1370     if (!strcmp (stream->control_url, (gchar *) a))
1371       return 0;
1372
1373     /* check if qualified setup_url ends with string */
1374     if (g_str_has_suffix (stream->control_url, (gchar *) a))
1375       return 0;
1376   }
1377
1378   return -1;
1379 }
1380
1381 static GstRTSPStream *
1382 find_stream (GstRTSPSrc * src, gconstpointer data, gconstpointer func)
1383 {
1384   GList *lstream;
1385
1386   /* find and get stream */
1387   if ((lstream = g_list_find_custom (src->streams, data, (GCompareFunc) func)))
1388     return (GstRTSPStream *) lstream->data;
1389
1390   return NULL;
1391 }
1392
1393 static const GstSDPBandwidth *
1394 gst_rtspsrc_get_bandwidth (GstRTSPSrc * src, const GstSDPMessage * sdp,
1395     const GstSDPMedia * media, const gchar * type)
1396 {
1397   guint i, len;
1398
1399   /* first look in the media specific section */
1400   len = gst_sdp_media_bandwidths_len (media);
1401   for (i = 0; i < len; i++) {
1402     const GstSDPBandwidth *bw = gst_sdp_media_get_bandwidth (media, i);
1403
1404     if (strcmp (bw->bwtype, type) == 0)
1405       return bw;
1406   }
1407   /* then look in the message specific section */
1408   len = gst_sdp_message_bandwidths_len (sdp);
1409   for (i = 0; i < len; i++) {
1410     const GstSDPBandwidth *bw = gst_sdp_message_get_bandwidth (sdp, i);
1411
1412     if (strcmp (bw->bwtype, type) == 0)
1413       return bw;
1414   }
1415   return NULL;
1416 }
1417
1418 static void
1419 gst_rtspsrc_collect_bandwidth (GstRTSPSrc * src, const GstSDPMessage * sdp,
1420     const GstSDPMedia * media, GstRTSPStream * stream)
1421 {
1422   const GstSDPBandwidth *bw;
1423
1424   if ((bw = gst_rtspsrc_get_bandwidth (src, sdp, media, GST_SDP_BWTYPE_AS)))
1425     stream->as_bandwidth = bw->bandwidth;
1426   else
1427     stream->as_bandwidth = -1;
1428
1429   if ((bw = gst_rtspsrc_get_bandwidth (src, sdp, media, GST_SDP_BWTYPE_RR)))
1430     stream->rr_bandwidth = bw->bandwidth;
1431   else
1432     stream->rr_bandwidth = -1;
1433
1434   if ((bw = gst_rtspsrc_get_bandwidth (src, sdp, media, GST_SDP_BWTYPE_RS)))
1435     stream->rs_bandwidth = bw->bandwidth;
1436   else
1437     stream->rs_bandwidth = -1;
1438 }
1439
1440 static void
1441 gst_rtspsrc_do_stream_connection (GstRTSPSrc * src, GstRTSPStream * stream,
1442     const GstSDPConnection * conn)
1443 {
1444   if (conn->nettype == NULL || strcmp (conn->nettype, "IN") != 0)
1445     return;
1446
1447   if (conn->addrtype == NULL)
1448     return;
1449
1450   /* check for IPV6 */
1451   if (strcmp (conn->addrtype, "IP4") == 0)
1452     stream->is_ipv6 = FALSE;
1453   else if (strcmp (conn->addrtype, "IP6") == 0)
1454     stream->is_ipv6 = TRUE;
1455   else
1456     return;
1457
1458   /* save address */
1459   g_free (stream->destination);
1460   stream->destination = g_strdup (conn->address);
1461
1462   /* check for multicast */
1463   stream->is_multicast =
1464       gst_sdp_address_is_multicast (conn->nettype, conn->addrtype,
1465       conn->address);
1466   stream->ttl = conn->ttl;
1467 }
1468
1469 /* Go over the connections for a stream.
1470  * - If we are dealing with IPV6, we will setup IPV6 sockets for sending and
1471  *   receiving.
1472  * - If we are dealing with a localhost address, we disable multicast
1473  */
1474 static void
1475 gst_rtspsrc_collect_connections (GstRTSPSrc * src, const GstSDPMessage * sdp,
1476     const GstSDPMedia * media, GstRTSPStream * stream)
1477 {
1478   const GstSDPConnection *conn;
1479   guint i, len;
1480
1481   /* first look in the media specific section */
1482   len = gst_sdp_media_connections_len (media);
1483   for (i = 0; i < len; i++) {
1484     conn = gst_sdp_media_get_connection (media, i);
1485
1486     gst_rtspsrc_do_stream_connection (src, stream, conn);
1487   }
1488   /* then look in the message specific section */
1489   if ((conn = gst_sdp_message_get_connection (sdp))) {
1490     gst_rtspsrc_do_stream_connection (src, stream, conn);
1491   }
1492 }
1493
1494 /*   m=<media> <UDP port> RTP/AVP <payload>
1495  */
1496 static void
1497 gst_rtspsrc_collect_payloads (GstRTSPSrc * src, const GstSDPMessage * sdp,
1498     const GstSDPMedia * media, GstRTSPStream * stream)
1499 {
1500   guint i, len;
1501   const gchar *proto;
1502   GstCaps *global_caps;
1503
1504   /* get proto */
1505   proto = gst_sdp_media_get_proto (media);
1506   if (proto == NULL)
1507     goto no_proto;
1508
1509   if (g_str_equal (proto, "RTP/AVP"))
1510     stream->profile = GST_RTSP_PROFILE_AVP;
1511   else if (g_str_equal (proto, "RTP/SAVP"))
1512     stream->profile = GST_RTSP_PROFILE_SAVP;
1513   else if (g_str_equal (proto, "RTP/AVPF"))
1514     stream->profile = GST_RTSP_PROFILE_AVPF;
1515   else if (g_str_equal (proto, "RTP/SAVPF"))
1516     stream->profile = GST_RTSP_PROFILE_SAVPF;
1517   else
1518     goto unknown_proto;
1519
1520   /* Parse global SDP attributes once */
1521   global_caps = gst_caps_new_empty_simple ("application/x-unknown");
1522   GST_DEBUG ("mapping sdp session level attributes to caps");
1523   gst_rtspsrc_sdp_attributes_to_caps (sdp->attributes, global_caps);
1524   GST_DEBUG ("mapping sdp media level attributes to caps");
1525   gst_rtspsrc_sdp_attributes_to_caps (media->attributes, global_caps);
1526
1527   len = gst_sdp_media_formats_len (media);
1528   for (i = 0; i < len; i++) {
1529     gint pt;
1530     GstCaps *caps, *outcaps;
1531     GstStructure *s;
1532     const gchar *enc;
1533     PtMapItem item;
1534
1535     pt = atoi (gst_sdp_media_get_format (media, i));
1536
1537     GST_DEBUG_OBJECT (src, " looking at %d pt: %d", i, pt);
1538
1539     /* convert caps */
1540     caps = gst_rtspsrc_media_to_caps (pt, media);
1541     if (caps == NULL) {
1542       GST_WARNING_OBJECT (src, " skipping pt %d without caps", pt);
1543       continue;
1544     }
1545
1546     /* do some tweaks */
1547     s = gst_caps_get_structure (caps, 0);
1548     if ((enc = gst_structure_get_string (s, "encoding-name"))) {
1549       stream->is_real = (strstr (enc, "-REAL") != NULL);
1550       if (strcmp (enc, "X-ASF-PF") == 0)
1551         stream->container = TRUE;
1552     }
1553
1554     /* Merge in global caps */
1555     /* Intersect will merge in missing fields to the current caps */
1556     outcaps = gst_caps_intersect (caps, global_caps);
1557     gst_caps_unref (caps);
1558
1559     /* the first pt will be the default */
1560     if (stream->ptmap->len == 0)
1561       stream->default_pt = pt;
1562
1563     item.pt = pt;
1564     item.caps = outcaps;
1565
1566     g_array_append_val (stream->ptmap, item);
1567   }
1568
1569   gst_caps_unref (global_caps);
1570   return;
1571
1572 no_proto:
1573   {
1574     GST_ERROR_OBJECT (src, "can't find proto in media");
1575     return;
1576   }
1577 unknown_proto:
1578   {
1579     GST_ERROR_OBJECT (src, "unknown proto in media %s", proto);
1580     return;
1581   }
1582 }
1583
1584 static const gchar *
1585 get_aggregate_control (GstRTSPSrc * src)
1586 {
1587   const gchar *base;
1588
1589   if (src->control)
1590     base = src->control;
1591   else if (src->content_base)
1592     base = src->content_base;
1593   else if (src->conninfo.url_str)
1594     base = src->conninfo.url_str;
1595   else
1596     base = "/";
1597
1598   return base;
1599 }
1600
1601 static void
1602 clear_ptmap_item (PtMapItem * item)
1603 {
1604   if (item->caps)
1605     gst_caps_unref (item->caps);
1606 }
1607
1608 static GstRTSPStream *
1609 gst_rtspsrc_create_stream (GstRTSPSrc * src, GstSDPMessage * sdp, gint idx)
1610 {
1611   GstRTSPStream *stream;
1612   const gchar *control_url;
1613   const GstSDPMedia *media;
1614
1615   /* get media, should not return NULL */
1616   media = gst_sdp_message_get_media (sdp, idx);
1617   if (media == NULL)
1618     return NULL;
1619
1620   stream = g_new0 (GstRTSPStream, 1);
1621   stream->parent = src;
1622   /* we mark the pad as not linked, we will mark it as OK when we add the pad to
1623    * the element. */
1624   stream->last_ret = GST_FLOW_NOT_LINKED;
1625   stream->added = FALSE;
1626   stream->setup = FALSE;
1627   stream->skipped = FALSE;
1628   stream->id = idx;
1629   stream->eos = FALSE;
1630   stream->discont = TRUE;
1631   stream->seqbase = -1;
1632   stream->timebase = -1;
1633   stream->send_ssrc = g_random_int ();
1634   stream->profile = GST_RTSP_PROFILE_AVP;
1635   stream->ptmap = g_array_new (FALSE, FALSE, sizeof (PtMapItem));
1636   g_array_set_clear_func (stream->ptmap, (GDestroyNotify) clear_ptmap_item);
1637
1638   /* collect bandwidth information for this steam. FIXME, configure in the RTP
1639    * session manager to scale RTCP. */
1640   gst_rtspsrc_collect_bandwidth (src, sdp, media, stream);
1641
1642   /* collect connection info */
1643   gst_rtspsrc_collect_connections (src, sdp, media, stream);
1644
1645   /* make the payload type map */
1646   gst_rtspsrc_collect_payloads (src, sdp, media, stream);
1647
1648   /* collect port number */
1649   stream->port = gst_sdp_media_get_port (media);
1650
1651   /* get control url to construct the setup url. The setup url is used to
1652    * configure the transport of the stream and is used to identity the stream in
1653    * the RTP-Info header field returned from PLAY. */
1654   control_url = gst_sdp_media_get_attribute_val (media, "control");
1655   if (control_url == NULL)
1656     control_url = gst_sdp_message_get_attribute_val_n (sdp, "control", 0);
1657
1658   GST_DEBUG_OBJECT (src, "stream %d, (%p)", stream->id, stream);
1659   GST_DEBUG_OBJECT (src, " port: %d", stream->port);
1660   GST_DEBUG_OBJECT (src, " container: %d", stream->container);
1661   GST_DEBUG_OBJECT (src, " control: %s", GST_STR_NULL (control_url));
1662
1663   if (control_url != NULL) {
1664     stream->control_url = g_strdup (control_url);
1665     /* Build a fully qualified url using the content_base if any or by prefixing
1666      * the original request.
1667      * If the control_url starts with a '/' or a non rtsp: protocol we will most
1668      * likely build a URL that the server will fail to understand, this is ok,
1669      * we will fail then. */
1670     if (g_str_has_prefix (control_url, "rtsp://"))
1671       stream->conninfo.location = g_strdup (control_url);
1672     else {
1673       const gchar *base;
1674       gboolean has_slash;
1675
1676       if (g_strcmp0 (control_url, "*") == 0)
1677         control_url = "";
1678
1679       base = get_aggregate_control (src);
1680
1681       /* check if the base ends or control starts with / */
1682       has_slash = g_str_has_prefix (control_url, "/");
1683       has_slash = has_slash || g_str_has_suffix (base, "/");
1684
1685       /* concatenate the two strings, insert / when not present */
1686       stream->conninfo.location =
1687           g_strdup_printf ("%s%s%s", base, has_slash ? "" : "/", control_url);
1688     }
1689   }
1690   GST_DEBUG_OBJECT (src, " setup: %s",
1691       GST_STR_NULL (stream->conninfo.location));
1692
1693   /* we keep track of all streams */
1694   src->streams = g_list_append (src->streams, stream);
1695
1696   return stream;
1697
1698   /* ERRORS */
1699 }
1700
1701 static void
1702 gst_rtspsrc_stream_free (GstRTSPSrc * src, GstRTSPStream * stream)
1703 {
1704   gint i;
1705
1706   GST_DEBUG_OBJECT (src, "free stream %p", stream);
1707
1708   g_array_free (stream->ptmap, TRUE);
1709
1710   g_free (stream->destination);
1711   g_free (stream->control_url);
1712   g_free (stream->conninfo.location);
1713
1714   for (i = 0; i < 2; i++) {
1715     if (stream->udpsrc[i]) {
1716       gst_element_set_state (stream->udpsrc[i], GST_STATE_NULL);
1717       gst_bin_remove (GST_BIN_CAST (src), stream->udpsrc[i]);
1718       gst_object_unref (stream->udpsrc[i]);
1719     }
1720     if (stream->channelpad[i])
1721       gst_object_unref (stream->channelpad[i]);
1722
1723     if (stream->udpsink[i]) {
1724       gst_element_set_state (stream->udpsink[i], GST_STATE_NULL);
1725       gst_bin_remove (GST_BIN_CAST (src), stream->udpsink[i]);
1726       gst_object_unref (stream->udpsink[i]);
1727     }
1728   }
1729   if (stream->fakesrc) {
1730     gst_element_set_state (stream->fakesrc, GST_STATE_NULL);
1731     gst_bin_remove (GST_BIN_CAST (src), stream->fakesrc);
1732     gst_object_unref (stream->fakesrc);
1733   }
1734   if (stream->srcpad) {
1735     gst_pad_set_active (stream->srcpad, FALSE);
1736     if (stream->added)
1737       gst_element_remove_pad (GST_ELEMENT_CAST (src), stream->srcpad);
1738   }
1739   if (stream->srtpenc)
1740     gst_object_unref (stream->srtpenc);
1741   if (stream->srtpdec)
1742     gst_object_unref (stream->srtpdec);
1743   if (stream->srtcpparams)
1744     gst_caps_unref (stream->srtcpparams);
1745   if (stream->rtcppad)
1746     gst_object_unref (stream->rtcppad);
1747   if (stream->session)
1748     g_object_unref (stream->session);
1749   if (stream->rtx_pt_map)
1750     gst_structure_free (stream->rtx_pt_map);
1751   g_free (stream);
1752 }
1753
1754 static void
1755 gst_rtspsrc_cleanup (GstRTSPSrc * src)
1756 {
1757   GList *walk;
1758
1759   GST_DEBUG_OBJECT (src, "cleanup");
1760
1761   for (walk = src->streams; walk; walk = g_list_next (walk)) {
1762     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
1763
1764     gst_rtspsrc_stream_free (src, stream);
1765   }
1766   g_list_free (src->streams);
1767   src->streams = NULL;
1768   if (src->manager) {
1769     if (src->manager_sig_id) {
1770       g_signal_handler_disconnect (src->manager, src->manager_sig_id);
1771       src->manager_sig_id = 0;
1772     }
1773     gst_element_set_state (src->manager, GST_STATE_NULL);
1774     gst_bin_remove (GST_BIN_CAST (src), src->manager);
1775     src->manager = NULL;
1776   }
1777   if (src->props)
1778     gst_structure_free (src->props);
1779   src->props = NULL;
1780
1781   g_free (src->content_base);
1782   src->content_base = NULL;
1783
1784   g_free (src->control);
1785   src->control = NULL;
1786
1787   if (src->range)
1788     gst_rtsp_range_free (src->range);
1789   src->range = NULL;
1790
1791   /* don't clear the SDP when it was used in the url */
1792   if (src->sdp && !src->from_sdp) {
1793     gst_sdp_message_free (src->sdp);
1794     src->sdp = NULL;
1795   }
1796
1797   src->need_segment = FALSE;
1798
1799   if (src->provided_clock) {
1800     gst_object_unref (src->provided_clock);
1801     src->provided_clock = NULL;
1802   }
1803 }
1804
1805 #define PARSE_INT(p, del, res)          \
1806 G_STMT_START {                          \
1807   gchar *t = p;                         \
1808   p = strstr (p, del);                  \
1809   if (p == NULL)                        \
1810     res = -1;                           \
1811   else {                                \
1812     *p = '\0';                          \
1813     p++;                                \
1814     res = atoi (t);                     \
1815   }                                     \
1816 } G_STMT_END
1817
1818 #define PARSE_STRING(p, del, res)       \
1819 G_STMT_START {                          \
1820   gchar *t = p;                         \
1821   p = strstr (p, del);                  \
1822   if (p == NULL) {                      \
1823     res = NULL;                         \
1824     p = t;                              \
1825   }                                     \
1826   else {                                \
1827     *p = '\0';                          \
1828     p++;                                \
1829     res = t;                            \
1830   }                                     \
1831 } G_STMT_END
1832
1833 #define SKIP_SPACES(p)                  \
1834   while (*p && g_ascii_isspace (*p))    \
1835     p++;
1836
1837 /* rtpmap contains:
1838  *
1839  *  <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
1840  */
1841 static gboolean
1842 gst_rtspsrc_parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name,
1843     gint * rate, gchar ** params)
1844 {
1845   gchar *p, *t;
1846
1847   p = (gchar *) rtpmap;
1848
1849   PARSE_INT (p, " ", *payload);
1850   if (*payload == -1)
1851     return FALSE;
1852
1853   SKIP_SPACES (p);
1854   if (*p == '\0')
1855     return FALSE;
1856
1857   PARSE_STRING (p, "/", *name);
1858   if (*name == NULL) {
1859     GST_DEBUG ("no rate, name %s", p);
1860     /* no rate, assume -1 then, this is not supposed to happen but RealMedia
1861      * streams seem to omit the rate. */
1862     *name = p;
1863     *rate = -1;
1864     return TRUE;
1865   }
1866
1867   t = p;
1868   p = strstr (p, "/");
1869   if (p == NULL) {
1870     *rate = atoi (t);
1871     return TRUE;
1872   }
1873   *p = '\0';
1874   p++;
1875   *rate = atoi (t);
1876
1877   t = p;
1878   if (*p == '\0')
1879     return TRUE;
1880   *params = t;
1881
1882   return TRUE;
1883 }
1884
1885 static gboolean
1886 parse_keymgmt (const gchar * keymgmt, GstCaps * caps)
1887 {
1888   gboolean res = FALSE;
1889   gsize size;
1890   guchar *data;
1891   GstMIKEYMessage *msg;
1892   const GstMIKEYPayload *payload;
1893   const gchar *srtp_cipher;
1894   const gchar *srtp_auth;
1895
1896   {
1897     gchar *orig_value;
1898     gchar *p, *kmpid;
1899
1900     p = orig_value = g_strdup (keymgmt);
1901
1902     SKIP_SPACES (p);
1903     if (*p == '\0') {
1904       g_free (orig_value);
1905       return FALSE;
1906     }
1907
1908     PARSE_STRING (p, " ", kmpid);
1909     if (kmpid == NULL || !g_str_equal (kmpid, "mikey")) {
1910       g_free (orig_value);
1911       return FALSE;
1912     }
1913     data = g_base64_decode (p, &size);
1914
1915     g_free (orig_value);        /* Don't need this any more */
1916   }
1917
1918   if (data == NULL)
1919     return FALSE;
1920
1921   msg = gst_mikey_message_new_from_data (data, size, NULL, NULL);
1922   g_free (data);
1923   if (msg == NULL)
1924     return FALSE;
1925
1926   srtp_cipher = "aes-128-icm";
1927   srtp_auth = "hmac-sha1-80";
1928
1929   /* check the Security policy if any */
1930   if ((payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_SP, 0))) {
1931     GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;
1932     guint len, i;
1933
1934     if (p->proto != GST_MIKEY_SEC_PROTO_SRTP)
1935       goto done;
1936
1937     len = gst_mikey_payload_sp_get_n_params (payload);
1938     for (i = 0; i < len; i++) {
1939       const GstMIKEYPayloadSPParam *param =
1940           gst_mikey_payload_sp_get_param (payload, i);
1941
1942       switch (param->type) {
1943         case GST_MIKEY_SP_SRTP_ENC_ALG:
1944           switch (param->val[0]) {
1945             case 0:
1946               srtp_cipher = "null";
1947               break;
1948             case 2:
1949             case 1:
1950               srtp_cipher = "aes-128-icm";
1951               break;
1952             default:
1953               break;
1954           }
1955           break;
1956         case GST_MIKEY_SP_SRTP_ENC_KEY_LEN:
1957           switch (param->val[0]) {
1958             case AES_128_KEY_LEN:
1959               srtp_cipher = "aes-128-icm";
1960               break;
1961             case AES_256_KEY_LEN:
1962               srtp_cipher = "aes-256-icm";
1963               break;
1964             default:
1965               break;
1966           }
1967           break;
1968         case GST_MIKEY_SP_SRTP_AUTH_ALG:
1969           switch (param->val[0]) {
1970             case 0:
1971               srtp_auth = "null";
1972               break;
1973             case 2:
1974             case 1:
1975               srtp_auth = "hmac-sha1-80";
1976               break;
1977             default:
1978               break;
1979           }
1980           break;
1981         case GST_MIKEY_SP_SRTP_AUTH_KEY_LEN:
1982           switch (param->val[0]) {
1983             case HMAC_32_KEY_LEN:
1984               srtp_auth = "hmac-sha1-32";
1985               break;
1986             case HMAC_80_KEY_LEN:
1987               srtp_auth = "hmac-sha1-80";
1988               break;
1989             default:
1990               break;
1991           }
1992           break;
1993         case GST_MIKEY_SP_SRTP_SRTP_ENC:
1994           break;
1995         case GST_MIKEY_SP_SRTP_SRTCP_ENC:
1996           break;
1997         default:
1998           break;
1999       }
2000     }
2001   }
2002
2003   if (!(payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_KEMAC, 0)))
2004     goto done;
2005   else {
2006     GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;
2007     const GstMIKEYPayload *sub;
2008     GstMIKEYPayloadKeyData *pkd;
2009     GstBuffer *buf;
2010
2011     if (p->enc_alg != GST_MIKEY_ENC_NULL || p->mac_alg != GST_MIKEY_MAC_NULL)
2012       goto done;
2013
2014     if (!(sub = gst_mikey_payload_kemac_get_sub (payload, 0)))
2015       goto done;
2016
2017     if (sub->type != GST_MIKEY_PT_KEY_DATA)
2018       goto done;
2019
2020     pkd = (GstMIKEYPayloadKeyData *) sub;
2021     buf =
2022         gst_buffer_new_wrapped (g_memdup (pkd->key_data, pkd->key_len),
2023         pkd->key_len);
2024     gst_caps_set_simple (caps, "srtp-key", GST_TYPE_BUFFER, buf, NULL);
2025     gst_buffer_unref (buf);
2026   }
2027
2028   gst_caps_set_simple (caps,
2029       "srtp-cipher", G_TYPE_STRING, srtp_cipher,
2030       "srtp-auth", G_TYPE_STRING, srtp_auth,
2031       "srtcp-cipher", G_TYPE_STRING, srtp_cipher,
2032       "srtcp-auth", G_TYPE_STRING, srtp_auth, NULL);
2033
2034   res = TRUE;
2035 done:
2036   gst_mikey_message_unref (msg);
2037
2038   return res;
2039 }
2040
2041 /*
2042  * Mapping SDP attributes to caps
2043  *
2044  * prepend 'a-' to IANA registered sdp attributes names
2045  * (ie: not prefixed with 'x-') in order to avoid
2046  * collision with gstreamer standard caps properties names
2047  */
2048 static void
2049 gst_rtspsrc_sdp_attributes_to_caps (GArray * attributes, GstCaps * caps)
2050 {
2051   if (attributes->len > 0) {
2052     GstStructure *s;
2053     guint i;
2054
2055     s = gst_caps_get_structure (caps, 0);
2056
2057     for (i = 0; i < attributes->len; i++) {
2058       GstSDPAttribute *attr = &g_array_index (attributes, GstSDPAttribute, i);
2059       gchar *tofree, *key;
2060
2061       key = attr->key;
2062
2063       /* skip some of the attribute we already handle */
2064       if (!strcmp (key, "fmtp"))
2065         continue;
2066       if (!strcmp (key, "rtpmap"))
2067         continue;
2068       if (!strcmp (key, "control"))
2069         continue;
2070       if (!strcmp (key, "range"))
2071         continue;
2072       if (!strcmp (key, "framesize"))
2073         continue;
2074       if (g_str_equal (key, "key-mgmt")) {
2075         parse_keymgmt (attr->value, caps);
2076         continue;
2077       }
2078
2079       /* string must be valid UTF8 */
2080       if (!g_utf8_validate (attr->value, -1, NULL))
2081         continue;
2082
2083       if (!g_str_has_prefix (key, "x-"))
2084         tofree = key = g_strdup_printf ("a-%s", key);
2085       else
2086         tofree = NULL;
2087
2088       GST_DEBUG ("adding caps: %s=%s", key, attr->value);
2089       gst_structure_set (s, key, G_TYPE_STRING, attr->value, NULL);
2090       g_free (tofree);
2091     }
2092   }
2093 }
2094
2095 static const gchar *
2096 rtsp_get_attribute_for_pt (const GstSDPMedia * media, const gchar * name,
2097     gint pt)
2098 {
2099   guint i;
2100
2101   for (i = 0;; i++) {
2102     const gchar *attr;
2103     gint val;
2104
2105     if ((attr = gst_sdp_media_get_attribute_val_n (media, name, i)) == NULL)
2106       break;
2107
2108     if (sscanf (attr, "%d ", &val) != 1)
2109       continue;
2110
2111     if (val == pt)
2112       return attr;
2113   }
2114   return NULL;
2115 }
2116
2117 /*
2118  *  Mapping of caps to and from SDP fields:
2119  *
2120  *   a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
2121  *   a=framesize:<payload> <width>-<height>
2122  *   a=fmtp:<payload> <param>[=<value>];...
2123  */
2124 static GstCaps *
2125 gst_rtspsrc_media_to_caps (gint pt, const GstSDPMedia * media)
2126 {
2127   GstCaps *caps;
2128   const gchar *rtpmap;
2129   const gchar *fmtp;
2130   const gchar *framesize;
2131   gchar *name = NULL;
2132   gint rate = -1;
2133   gchar *params = NULL;
2134   gchar *tmp;
2135   GstStructure *s;
2136   gint payload = 0;
2137   gboolean ret;
2138
2139   /* get and parse rtpmap */
2140   rtpmap = rtsp_get_attribute_for_pt (media, "rtpmap", pt);
2141
2142   if (rtpmap) {
2143     ret = gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate, &params);
2144     if (!ret) {
2145       g_warning ("error parsing rtpmap, ignoring");
2146       rtpmap = NULL;
2147     }
2148   }
2149   /* dynamic payloads need rtpmap or we fail */
2150   if (rtpmap == NULL && pt >= 96)
2151     goto no_rtpmap;
2152
2153   /* check if we have a rate, if not, we need to look up the rate from the
2154    * default rates based on the payload types. */
2155   if (rate == -1) {
2156     const GstRTPPayloadInfo *info;
2157
2158     if (GST_RTP_PAYLOAD_IS_DYNAMIC (pt)) {
2159       /* dynamic types, use media and encoding_name */
2160       tmp = g_ascii_strdown (media->media, -1);
2161       info = gst_rtp_payload_info_for_name (tmp, name);
2162       g_free (tmp);
2163     } else {
2164       /* static types, use payload type */
2165       info = gst_rtp_payload_info_for_pt (pt);
2166     }
2167
2168     if (info) {
2169       if ((rate = info->clock_rate) == 0)
2170         rate = -1;
2171     }
2172     /* we fail if we cannot find one */
2173     if (rate == -1)
2174       goto no_rate;
2175   }
2176
2177   tmp = g_ascii_strdown (media->media, -1);
2178   caps = gst_caps_new_simple ("application/x-unknown",
2179       "media", G_TYPE_STRING, tmp, "payload", G_TYPE_INT, pt, NULL);
2180   g_free (tmp);
2181   s = gst_caps_get_structure (caps, 0);
2182
2183   gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);
2184
2185   /* encoding name must be upper case */
2186   if (name != NULL) {
2187     tmp = g_ascii_strup (name, -1);
2188     gst_structure_set (s, "encoding-name", G_TYPE_STRING, tmp, NULL);
2189     g_free (tmp);
2190   }
2191
2192   /* params must be lower case */
2193   if (params != NULL) {
2194     tmp = g_ascii_strdown (params, -1);
2195     gst_structure_set (s, "encoding-params", G_TYPE_STRING, tmp, NULL);
2196     g_free (tmp);
2197   }
2198
2199   /* parse optional fmtp: field */
2200   if ((fmtp = rtsp_get_attribute_for_pt (media, "fmtp", pt))) {
2201     gchar *p;
2202     gint payload = 0;
2203
2204     p = (gchar *) fmtp;
2205
2206     /* p is now of the format <payload> <param>[=<value>];... */
2207     PARSE_INT (p, " ", payload);
2208     if (payload != -1 && payload == pt) {
2209       gchar **pairs;
2210       gint i;
2211
2212       /* <param>[=<value>] are separated with ';' */
2213       pairs = g_strsplit (p, ";", 0);
2214       for (i = 0; pairs[i]; i++) {
2215         gchar *valpos;
2216         const gchar *val, *key;
2217         gint j;
2218         const gchar *reserved_keys[] =
2219             { "media", "payload", "clock-rate", "encoding-name",
2220           "encoding-params"
2221         };
2222
2223         /* the key may not have a '=', the value can have other '='s */
2224         valpos = strstr (pairs[i], "=");
2225         if (valpos) {
2226           /* we have a '=' and thus a value, remove the '=' with \0 */
2227           *valpos = '\0';
2228           /* value is everything between '=' and ';'. We split the pairs at ;
2229            * boundaries so we can take the remainder of the value. Some servers
2230            * put spaces around the value which we strip off here. Alternatively
2231            * we could strip those spaces in the depayloaders should these spaces
2232            * actually carry any meaning in the future. */
2233           val = g_strstrip (valpos + 1);
2234         } else {
2235           /* simple <param>;.. is translated into <param>=1;... */
2236           val = "1";
2237         }
2238         /* strip the key of spaces, convert key to lowercase but not the value. */
2239         key = g_strstrip (pairs[i]);
2240
2241         /* skip keys from the fmtp, which we already use ourselves for the
2242          * caps. Some software is adding random things like clock-rate into
2243          * the fmtp, and we would otherwise here set a string-typed clock-rate
2244          * in the caps... and thus fail to create valid RTP caps
2245          */
2246         for (j = 0; j < G_N_ELEMENTS (reserved_keys); j++) {
2247           if (g_ascii_strcasecmp (reserved_keys[j], key) == 0) {
2248             key = "";
2249             break;
2250           }
2251         }
2252
2253         if (strlen (key) > 1) {
2254           tmp = g_ascii_strdown (key, -1);
2255           gst_structure_set (s, tmp, G_TYPE_STRING, val, NULL);
2256           g_free (tmp);
2257         }
2258       }
2259       g_strfreev (pairs);
2260     }
2261   }
2262
2263   /* parse framesize: field */
2264   if ((framesize = gst_sdp_media_get_attribute_val (media, "framesize"))) {
2265     gchar *p;
2266
2267     /* p is now of the format <payload> <width>-<height> */
2268     p = (gchar *) framesize;
2269
2270     PARSE_INT (p, " ", payload);
2271     if (payload != -1 && payload == pt) {
2272       gst_structure_set (s, "a-framesize", G_TYPE_STRING, p, NULL);
2273     }
2274   }
2275   return caps;
2276
2277   /* ERRORS */
2278 no_rtpmap:
2279   {
2280     g_warning ("rtpmap type not given for dynamic payload %d", pt);
2281     return NULL;
2282   }
2283 no_rate:
2284   {
2285     g_warning ("rate unknown for payload type %d", pt);
2286     return NULL;
2287   }
2288 }
2289
2290 static gboolean
2291 gst_rtspsrc_alloc_udp_ports (GstRTSPStream * stream,
2292     gint * rtpport, gint * rtcpport)
2293 {
2294   GstRTSPSrc *src;
2295   GstStateChangeReturn ret;
2296   GstElement *udpsrc0, *udpsrc1;
2297   gint tmp_rtp, tmp_rtcp;
2298   guint count;
2299   const gchar *host;
2300
2301   src = stream->parent;
2302
2303   udpsrc0 = NULL;
2304   udpsrc1 = NULL;
2305   count = 0;
2306
2307   /* Start at next port */
2308   tmp_rtp = src->next_port_num;
2309
2310   if (stream->is_ipv6)
2311     host = "udp://[::0]";
2312   else
2313     host = "udp://0.0.0.0";
2314
2315   /* try to allocate 2 UDP ports, the RTP port should be an even
2316    * number and the RTCP port should be the next (uneven) port */
2317 again:
2318
2319   if (tmp_rtp != 0 && src->client_port_range.max > 0 &&
2320       tmp_rtp >= src->client_port_range.max)
2321     goto no_ports;
2322
2323   udpsrc0 = gst_element_make_from_uri (GST_URI_SRC, host, NULL, NULL);
2324   if (udpsrc0 == NULL)
2325     goto no_udp_protocol;
2326   g_object_set (G_OBJECT (udpsrc0), "port", tmp_rtp, "reuse", FALSE, NULL);
2327
2328   if (src->udp_buffer_size != 0)
2329     g_object_set (G_OBJECT (udpsrc0), "buffer-size", src->udp_buffer_size,
2330         NULL);
2331
2332   ret = gst_element_set_state (udpsrc0, GST_STATE_READY);
2333   if (ret == GST_STATE_CHANGE_FAILURE) {
2334     if (tmp_rtp != 0) {
2335       GST_DEBUG_OBJECT (src, "Unable to make udpsrc from RTP port %d", tmp_rtp);
2336
2337       tmp_rtp += 2;
2338       if (++count > src->retry)
2339         goto no_ports;
2340
2341       GST_DEBUG_OBJECT (src, "free RTP udpsrc");
2342       gst_element_set_state (udpsrc0, GST_STATE_NULL);
2343       gst_object_unref (udpsrc0);
2344       udpsrc0 = NULL;
2345
2346       GST_DEBUG_OBJECT (src, "retry %d", count);
2347       goto again;
2348     }
2349     goto no_udp_protocol;
2350   }
2351
2352   g_object_get (G_OBJECT (udpsrc0), "port", &tmp_rtp, NULL);
2353   GST_DEBUG_OBJECT (src, "got RTP port %d", tmp_rtp);
2354
2355   /* check if port is even */
2356   if ((tmp_rtp & 0x01) != 0) {
2357     /* port not even, close and allocate another */
2358     if (++count > src->retry)
2359       goto no_ports;
2360
2361     GST_DEBUG_OBJECT (src, "RTP port not even");
2362
2363     GST_DEBUG_OBJECT (src, "free RTP udpsrc");
2364     gst_element_set_state (udpsrc0, GST_STATE_NULL);
2365     gst_object_unref (udpsrc0);
2366     udpsrc0 = NULL;
2367
2368     GST_DEBUG_OBJECT (src, "retry %d", count);
2369     tmp_rtp++;
2370     goto again;
2371   }
2372
2373   /* allocate port+1 for RTCP now */
2374   udpsrc1 = gst_element_make_from_uri (GST_URI_SRC, host, NULL, NULL);
2375   if (udpsrc1 == NULL)
2376     goto no_udp_rtcp_protocol;
2377
2378   /* set port */
2379   tmp_rtcp = tmp_rtp + 1;
2380   if (src->client_port_range.max > 0 && tmp_rtcp > src->client_port_range.max)
2381     goto no_ports;
2382
2383   g_object_set (G_OBJECT (udpsrc1), "port", tmp_rtcp, "reuse", FALSE, NULL);
2384
2385   GST_DEBUG_OBJECT (src, "starting RTCP on port %d", tmp_rtcp);
2386   ret = gst_element_set_state (udpsrc1, GST_STATE_READY);
2387   /* tmp_rtcp port is busy already : retry to make rtp/rtcp pair */
2388   if (ret == GST_STATE_CHANGE_FAILURE) {
2389     GST_DEBUG_OBJECT (src, "Unable to make udpsrc from RTCP port %d", tmp_rtcp);
2390
2391     if (++count > src->retry)
2392       goto no_ports;
2393
2394     GST_DEBUG_OBJECT (src, "free RTP udpsrc");
2395     gst_element_set_state (udpsrc0, GST_STATE_NULL);
2396     gst_object_unref (udpsrc0);
2397     udpsrc0 = NULL;
2398
2399     GST_DEBUG_OBJECT (src, "free RTCP udpsrc");
2400     gst_element_set_state (udpsrc1, GST_STATE_NULL);
2401     gst_object_unref (udpsrc1);
2402     udpsrc1 = NULL;
2403
2404     tmp_rtp += 2;
2405     GST_DEBUG_OBJECT (src, "retry %d", count);
2406     goto again;
2407   }
2408
2409   /* all fine, do port check */
2410   g_object_get (G_OBJECT (udpsrc0), "port", rtpport, NULL);
2411   g_object_get (G_OBJECT (udpsrc1), "port", rtcpport, NULL);
2412
2413   /* this should not happen... */
2414   if (*rtpport != tmp_rtp || *rtcpport != tmp_rtcp)
2415     goto port_error;
2416
2417   /* we keep these elements, we configure all in configure_transport when the
2418    * server told us to really use the UDP ports. */
2419   stream->udpsrc[0] = gst_object_ref_sink (udpsrc0);
2420   stream->udpsrc[1] = gst_object_ref_sink (udpsrc1);
2421   gst_element_set_locked_state (stream->udpsrc[0], TRUE);
2422   gst_element_set_locked_state (stream->udpsrc[1], TRUE);
2423
2424   /* keep track of next available port number when we have a range
2425    * configured */
2426   if (src->next_port_num != 0)
2427     src->next_port_num = tmp_rtcp + 1;
2428
2429   return TRUE;
2430
2431   /* ERRORS */
2432 no_udp_protocol:
2433   {
2434     GST_DEBUG_OBJECT (src, "could not get UDP source");
2435     goto cleanup;
2436   }
2437 no_ports:
2438   {
2439     GST_DEBUG_OBJECT (src, "could not allocate UDP port pair after %d retries",
2440         count);
2441     goto cleanup;
2442   }
2443 no_udp_rtcp_protocol:
2444   {
2445     GST_DEBUG_OBJECT (src, "could not get UDP source for RTCP");
2446     goto cleanup;
2447   }
2448 port_error:
2449   {
2450     GST_DEBUG_OBJECT (src, "ports don't match rtp: %d<->%d, rtcp: %d<->%d",
2451         tmp_rtp, *rtpport, tmp_rtcp, *rtcpport);
2452     goto cleanup;
2453   }
2454 cleanup:
2455   {
2456     if (udpsrc0) {
2457       gst_element_set_state (udpsrc0, GST_STATE_NULL);
2458       gst_object_unref (udpsrc0);
2459     }
2460     if (udpsrc1) {
2461       gst_element_set_state (udpsrc1, GST_STATE_NULL);
2462       gst_object_unref (udpsrc1);
2463     }
2464     return FALSE;
2465   }
2466 }
2467
2468 static void
2469 gst_rtspsrc_set_state (GstRTSPSrc * src, GstState state)
2470 {
2471   GList *walk;
2472
2473   if (src->manager)
2474     gst_element_set_state (GST_ELEMENT_CAST (src->manager), state);
2475
2476   for (walk = src->streams; walk; walk = g_list_next (walk)) {
2477     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
2478     gint i;
2479
2480     for (i = 0; i < 2; i++) {
2481       if (stream->udpsrc[i])
2482         gst_element_set_state (stream->udpsrc[i], state);
2483     }
2484   }
2485 }
2486
2487 static void
2488 gst_rtspsrc_flush (GstRTSPSrc * src, gboolean flush, gboolean playing)
2489 {
2490   GstEvent *event;
2491   gint cmd;
2492   GstState state;
2493
2494   if (flush) {
2495     event = gst_event_new_flush_start ();
2496     GST_DEBUG_OBJECT (src, "start flush");
2497     cmd = CMD_WAIT;
2498     state = GST_STATE_PAUSED;
2499   } else {
2500     event = gst_event_new_flush_stop (FALSE);
2501     GST_DEBUG_OBJECT (src, "stop flush; playing %d", playing);
2502     cmd = CMD_LOOP;
2503     if (playing)
2504       state = GST_STATE_PLAYING;
2505     else
2506       state = GST_STATE_PAUSED;
2507   }
2508   gst_rtspsrc_push_event (src, event);
2509   gst_rtspsrc_loop_send_cmd (src, cmd, CMD_LOOP);
2510   gst_rtspsrc_set_state (src, state);
2511 }
2512
2513 static GstRTSPResult
2514 gst_rtspsrc_connection_send (GstRTSPSrc * src, GstRTSPConnection * conn,
2515     GstRTSPMessage * message, GTimeVal * timeout)
2516 {
2517   GstRTSPResult ret;
2518
2519   if (conn)
2520     ret = gst_rtsp_connection_send (conn, message, timeout);
2521   else
2522     ret = GST_RTSP_ERROR;
2523
2524   return ret;
2525 }
2526
2527 static GstRTSPResult
2528 gst_rtspsrc_connection_receive (GstRTSPSrc * src, GstRTSPConnection * conn,
2529     GstRTSPMessage * message, GTimeVal * timeout)
2530 {
2531   GstRTSPResult ret;
2532
2533   if (conn)
2534     ret = gst_rtsp_connection_receive (conn, message, timeout);
2535   else
2536     ret = GST_RTSP_ERROR;
2537
2538   return ret;
2539 }
2540
2541 static void
2542 gst_rtspsrc_get_position (GstRTSPSrc * src)
2543 {
2544   GstQuery *query;
2545   GList *walk;
2546
2547   query = gst_query_new_position (GST_FORMAT_TIME);
2548   /*  should be known somewhere down the stream (e.g. jitterbuffer) */
2549   for (walk = src->streams; walk; walk = g_list_next (walk)) {
2550     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
2551     GstFormat fmt;
2552     gint64 pos;
2553
2554     if (stream->srcpad) {
2555       if (gst_pad_query (stream->srcpad, query)) {
2556         gst_query_parse_position (query, &fmt, &pos);
2557         GST_DEBUG_OBJECT (src, "retaining position %" GST_TIME_FORMAT,
2558             GST_TIME_ARGS (pos));
2559         src->last_pos = pos;
2560         goto out;
2561       }
2562     }
2563   }
2564
2565   src->last_pos = 0;
2566
2567 out:
2568
2569   gst_query_unref (query);
2570 }
2571
2572 static gboolean
2573 gst_rtspsrc_perform_seek (GstRTSPSrc * src, GstEvent * event)
2574 {
2575   gdouble rate;
2576   GstFormat format;
2577   GstSeekFlags flags;
2578   GstSeekType cur_type = GST_SEEK_TYPE_NONE, stop_type;
2579   gint64 cur, stop;
2580   gboolean flush, skip;
2581   gboolean update;
2582   gboolean playing;
2583   GstSegment seeksegment = { 0, };
2584   GList *walk;
2585
2586   if (event) {
2587     GST_DEBUG_OBJECT (src, "doing seek with event");
2588
2589     gst_event_parse_seek (event, &rate, &format, &flags,
2590         &cur_type, &cur, &stop_type, &stop);
2591
2592     /* no negative rates yet */
2593     if (rate < 0.0)
2594       goto negative_rate;
2595
2596     /* we need TIME format */
2597     if (format != src->segment.format)
2598       goto no_format;
2599   } else {
2600     GST_DEBUG_OBJECT (src, "doing seek without event");
2601     flags = 0;
2602     cur_type = GST_SEEK_TYPE_SET;
2603     stop_type = GST_SEEK_TYPE_SET;
2604   }
2605
2606   /* get flush flag */
2607   flush = flags & GST_SEEK_FLAG_FLUSH;
2608   skip = flags & GST_SEEK_FLAG_SKIP;
2609
2610   /* now we need to make sure the streaming thread is stopped. We do this by
2611    * either sending a FLUSH_START event downstream which will cause the
2612    * streaming thread to stop with a WRONG_STATE.
2613    * For a non-flushing seek we simply pause the task, which will happen as soon
2614    * as it completes one iteration (and thus might block when the sink is
2615    * blocking in preroll). */
2616   if (flush) {
2617     GST_DEBUG_OBJECT (src, "starting flush");
2618     gst_rtspsrc_flush (src, TRUE, FALSE);
2619   } else {
2620     if (src->task) {
2621       gst_task_pause (src->task);
2622     }
2623   }
2624
2625   /* we should now be able to grab the streaming thread because we stopped it
2626    * with the above flush/pause code */
2627   GST_RTSP_STREAM_LOCK (src);
2628
2629   GST_DEBUG_OBJECT (src, "stopped streaming");
2630
2631   /* stop flushing the rtsp connection so we can send PAUSE/PLAY below */
2632   gst_rtspsrc_connection_flush (src, FALSE);
2633
2634   /* copy segment, we need this because we still need the old
2635    * segment when we close the current segment. */
2636   memcpy (&seeksegment, &src->segment, sizeof (GstSegment));
2637
2638   /* configure the seek parameters in the seeksegment. We will then have the
2639    * right values in the segment to perform the seek */
2640   if (event) {
2641     GST_DEBUG_OBJECT (src, "configuring seek");
2642     gst_segment_do_seek (&seeksegment, rate, format, flags,
2643         cur_type, cur, stop_type, stop, &update);
2644   }
2645
2646   /* figure out the last position we need to play. If it's configured (stop !=
2647    * -1), use that, else we play until the total duration of the file */
2648   if ((stop = seeksegment.stop) == -1)
2649     stop = seeksegment.duration;
2650
2651   playing = (src->state == GST_RTSP_STATE_PLAYING);
2652
2653   /* if we were playing, pause first */
2654   if (playing) {
2655     /* obtain current position in case seek fails */
2656     gst_rtspsrc_get_position (src);
2657     gst_rtspsrc_pause (src, FALSE);
2658   }
2659   src->skip = skip;
2660
2661   src->state = GST_RTSP_STATE_SEEKING;
2662
2663   /* PLAY will add the range header now. */
2664   src->need_range = TRUE;
2665
2666   /* and continue playing */
2667   if (playing)
2668     gst_rtspsrc_play (src, &seeksegment, FALSE);
2669
2670   /* prepare for streaming again */
2671   if (flush) {
2672     /* if we started flush, we stop now */
2673     GST_DEBUG_OBJECT (src, "stopping flush");
2674     gst_rtspsrc_flush (src, FALSE, playing);
2675   }
2676
2677   /* now we did the seek and can activate the new segment values */
2678   memcpy (&src->segment, &seeksegment, sizeof (GstSegment));
2679
2680   /* if we're doing a segment seek, post a SEGMENT_START message */
2681   if (src->segment.flags & GST_SEEK_FLAG_SEGMENT) {
2682     gst_element_post_message (GST_ELEMENT_CAST (src),
2683         gst_message_new_segment_start (GST_OBJECT_CAST (src),
2684             src->segment.format, src->segment.position));
2685   }
2686
2687   /* now create the newsegment */
2688   GST_DEBUG_OBJECT (src, "Creating newsegment from %" G_GINT64_FORMAT
2689       " to %" G_GINT64_FORMAT, src->segment.position, stop);
2690
2691   /* mark discont */
2692   GST_DEBUG_OBJECT (src, "mark DISCONT, we did a seek to another position");
2693   for (walk = src->streams; walk; walk = g_list_next (walk)) {
2694     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
2695     stream->discont = TRUE;
2696   }
2697
2698   GST_RTSP_STREAM_UNLOCK (src);
2699
2700   return TRUE;
2701
2702   /* ERRORS */
2703 negative_rate:
2704   {
2705     GST_DEBUG_OBJECT (src, "negative playback rates are not supported yet.");
2706     return FALSE;
2707   }
2708 no_format:
2709   {
2710     GST_DEBUG_OBJECT (src, "unsupported format given, seek aborted.");
2711     return FALSE;
2712   }
2713 }
2714
2715 static gboolean
2716 gst_rtspsrc_handle_src_event (GstPad * pad, GstObject * parent,
2717     GstEvent * event)
2718 {
2719   GstRTSPSrc *src;
2720   gboolean res = TRUE;
2721   gboolean forward;
2722
2723   src = GST_RTSPSRC_CAST (parent);
2724
2725   GST_DEBUG_OBJECT (src, "pad %s:%s received event %s",
2726       GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE_NAME (event));
2727
2728   switch (GST_EVENT_TYPE (event)) {
2729     case GST_EVENT_SEEK:
2730       res = gst_rtspsrc_perform_seek (src, event);
2731       forward = FALSE;
2732       break;
2733     case GST_EVENT_QOS:
2734     case GST_EVENT_NAVIGATION:
2735     case GST_EVENT_LATENCY:
2736     default:
2737       forward = TRUE;
2738       break;
2739   }
2740   if (forward) {
2741     GstPad *target;
2742
2743     if ((target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad)))) {
2744       res = gst_pad_send_event (target, event);
2745       gst_object_unref (target);
2746     } else {
2747       gst_event_unref (event);
2748     }
2749   } else {
2750     gst_event_unref (event);
2751   }
2752
2753   return res;
2754 }
2755
2756 /* this is the final event function we receive on the internal source pad when
2757  * we deal with TCP connections */
2758 static gboolean
2759 gst_rtspsrc_handle_internal_src_event (GstPad * pad, GstObject * parent,
2760     GstEvent * event)
2761 {
2762   gboolean res;
2763
2764   GST_DEBUG_OBJECT (pad, "received event %s", GST_EVENT_TYPE_NAME (event));
2765
2766   switch (GST_EVENT_TYPE (event)) {
2767     case GST_EVENT_SEEK:
2768     case GST_EVENT_QOS:
2769     case GST_EVENT_NAVIGATION:
2770     case GST_EVENT_LATENCY:
2771     default:
2772       gst_event_unref (event);
2773       res = TRUE;
2774       break;
2775   }
2776   return res;
2777 }
2778
2779 /* this is the final query function we receive on the internal source pad when
2780  * we deal with TCP connections */
2781 static gboolean
2782 gst_rtspsrc_handle_internal_src_query (GstPad * pad, GstObject * parent,
2783     GstQuery * query)
2784 {
2785   GstRTSPSrc *src;
2786   gboolean res = TRUE;
2787
2788   src = GST_RTSPSRC_CAST (gst_pad_get_element_private (pad));
2789
2790   GST_DEBUG_OBJECT (src, "pad %s:%s received query %s",
2791       GST_DEBUG_PAD_NAME (pad), GST_QUERY_TYPE_NAME (query));
2792
2793   switch (GST_QUERY_TYPE (query)) {
2794     case GST_QUERY_POSITION:
2795     {
2796       /* no idea */
2797       break;
2798     }
2799     case GST_QUERY_DURATION:
2800     {
2801       GstFormat format;
2802
2803       gst_query_parse_duration (query, &format, NULL);
2804
2805       switch (format) {
2806         case GST_FORMAT_TIME:
2807           gst_query_set_duration (query, format, src->segment.duration);
2808           break;
2809         default:
2810           res = FALSE;
2811           break;
2812       }
2813       break;
2814     }
2815     case GST_QUERY_LATENCY:
2816     {
2817       /* we are live with a min latency of 0 and unlimited max latency, this
2818        * result will be updated by the session manager if there is any. */
2819       gst_query_set_latency (query, TRUE, 0, -1);
2820       break;
2821     }
2822     default:
2823       break;
2824   }
2825
2826   return res;
2827 }
2828
2829 /* this query is executed on the ghost source pad exposed on rtspsrc. */
2830 static gboolean
2831 gst_rtspsrc_handle_src_query (GstPad * pad, GstObject * parent,
2832     GstQuery * query)
2833 {
2834   GstRTSPSrc *src;
2835   gboolean res = FALSE;
2836
2837   src = GST_RTSPSRC_CAST (parent);
2838
2839   GST_DEBUG_OBJECT (src, "pad %s:%s received query %s",
2840       GST_DEBUG_PAD_NAME (pad), GST_QUERY_TYPE_NAME (query));
2841
2842   switch (GST_QUERY_TYPE (query)) {
2843     case GST_QUERY_DURATION:
2844     {
2845       GstFormat format;
2846
2847       gst_query_parse_duration (query, &format, NULL);
2848
2849       switch (format) {
2850         case GST_FORMAT_TIME:
2851           gst_query_set_duration (query, format, src->segment.duration);
2852           res = TRUE;
2853           break;
2854         default:
2855           break;
2856       }
2857       break;
2858     }
2859     case GST_QUERY_SEEKING:
2860     {
2861       GstFormat format;
2862
2863       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
2864       if (format == GST_FORMAT_TIME) {
2865         gboolean seekable =
2866             src->cur_protocols != GST_RTSP_LOWER_TRANS_UDP_MCAST;
2867
2868         /* seeking without duration is unlikely */
2869         seekable = seekable && src->seekable && src->segment.duration &&
2870             GST_CLOCK_TIME_IS_VALID (src->segment.duration);
2871
2872         gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0,
2873             src->segment.duration);
2874         res = TRUE;
2875       }
2876       break;
2877     }
2878     case GST_QUERY_URI:
2879     {
2880       gchar *uri;
2881
2882       uri = gst_rtspsrc_uri_get_uri (GST_URI_HANDLER (src));
2883       if (uri != NULL) {
2884         gst_query_set_uri (query, uri);
2885         g_free (uri);
2886         res = TRUE;
2887       }
2888       break;
2889     }
2890     default:
2891     {
2892       GstPad *target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (pad));
2893
2894       /* forward the query to the proxy target pad */
2895       if (target) {
2896         res = gst_pad_query (target, query);
2897         gst_object_unref (target);
2898       }
2899       break;
2900     }
2901   }
2902
2903   return res;
2904 }
2905
2906 /* callback for RTCP messages to be sent to the server when operating in TCP
2907  * mode. */
2908 static GstFlowReturn
2909 gst_rtspsrc_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2910 {
2911   GstRTSPSrc *src;
2912   GstRTSPStream *stream;
2913   GstFlowReturn res = GST_FLOW_OK;
2914   GstMapInfo map;
2915   guint8 *data;
2916   guint size;
2917   GstRTSPResult ret;
2918   GstRTSPMessage message = { 0 };
2919   GstRTSPConnection *conn;
2920
2921   stream = (GstRTSPStream *) gst_pad_get_element_private (pad);
2922   src = stream->parent;
2923
2924   gst_buffer_map (buffer, &map, GST_MAP_READ);
2925   size = map.size;
2926   data = map.data;
2927
2928   gst_rtsp_message_init_data (&message, stream->channel[1]);
2929
2930   /* lend the body data to the message */
2931   gst_rtsp_message_take_body (&message, data, size);
2932
2933   if (stream->conninfo.connection)
2934     conn = stream->conninfo.connection;
2935   else
2936     conn = src->conninfo.connection;
2937
2938   GST_DEBUG_OBJECT (src, "sending %u bytes RTCP", size);
2939   ret = gst_rtspsrc_connection_send (src, conn, &message, NULL);
2940   GST_DEBUG_OBJECT (src, "sent RTCP, %d", ret);
2941
2942   /* and steal it away again because we will free it when unreffing the
2943    * buffer */
2944   gst_rtsp_message_steal_body (&message, &data, &size);
2945   gst_rtsp_message_unset (&message);
2946
2947   gst_buffer_unmap (buffer, &map);
2948   gst_buffer_unref (buffer);
2949
2950   return res;
2951 }
2952
2953 static GstPadProbeReturn
2954 pad_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
2955 {
2956   GstRTSPSrc *src = user_data;
2957
2958   GST_DEBUG_OBJECT (src, "pad %s:%s blocked, activating streams",
2959       GST_DEBUG_PAD_NAME (pad));
2960
2961   /* activate the streams */
2962   GST_OBJECT_LOCK (src);
2963   if (!src->need_activate)
2964     goto was_ok;
2965
2966   src->need_activate = FALSE;
2967   GST_OBJECT_UNLOCK (src);
2968
2969   gst_rtspsrc_activate_streams (src);
2970
2971   return GST_PAD_PROBE_OK;
2972
2973 was_ok:
2974   {
2975     GST_OBJECT_UNLOCK (src);
2976     return GST_PAD_PROBE_OK;
2977   }
2978 }
2979
2980 static gboolean
2981 copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
2982 {
2983   GstPad *gpad = GST_PAD_CAST (user_data);
2984
2985   GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
2986   gst_pad_store_sticky_event (gpad, *event);
2987
2988   return TRUE;
2989 }
2990
2991 /* this callback is called when the session manager generated a new src pad with
2992  * payloaded RTP packets. We simply ghost the pad here. */
2993 static void
2994 new_manager_pad (GstElement * manager, GstPad * pad, GstRTSPSrc * src)
2995 {
2996   gchar *name;
2997   GstPadTemplate *template;
2998   gint id, ssrc, pt;
2999   GList *ostreams;
3000   GstRTSPStream *stream;
3001   gboolean all_added;
3002
3003   GST_DEBUG_OBJECT (src, "got new manager pad %" GST_PTR_FORMAT, pad);
3004
3005   GST_RTSP_STATE_LOCK (src);
3006   /* find stream */
3007   name = gst_object_get_name (GST_OBJECT_CAST (pad));
3008   if (sscanf (name, "recv_rtp_src_%u_%u_%u", &id, &ssrc, &pt) != 3)
3009     goto unknown_stream;
3010
3011   GST_DEBUG_OBJECT (src, "stream: %u, SSRC %08x, PT %d", id, ssrc, pt);
3012
3013   stream = find_stream (src, &id, (gpointer) find_stream_by_id);
3014   if (stream == NULL)
3015     goto unknown_stream;
3016
3017   /* save SSRC */
3018   stream->ssrc = ssrc;
3019
3020   /* we'll add it later see below */
3021   stream->added = TRUE;
3022
3023   /* check if we added all streams */
3024   all_added = TRUE;
3025   for (ostreams = src->streams; ostreams; ostreams = g_list_next (ostreams)) {
3026     GstRTSPStream *ostream = (GstRTSPStream *) ostreams->data;
3027
3028     GST_DEBUG_OBJECT (src, "stream %p, container %d, added %d, setup %d",
3029         ostream, ostream->container, ostream->added, ostream->setup);
3030
3031     /* if we find a stream for which we did a setup that is not added, we
3032      * need to wait some more */
3033     if (ostream->setup && !ostream->added) {
3034       all_added = FALSE;
3035       break;
3036     }
3037   }
3038   GST_RTSP_STATE_UNLOCK (src);
3039
3040   /* create a new pad we will use to stream to */
3041   template = gst_static_pad_template_get (&rtptemplate);
3042   stream->srcpad = gst_ghost_pad_new_from_template (name, pad, template);
3043   gst_object_unref (template);
3044   g_free (name);
3045
3046   gst_pad_set_event_function (stream->srcpad, gst_rtspsrc_handle_src_event);
3047   gst_pad_set_query_function (stream->srcpad, gst_rtspsrc_handle_src_query);
3048   gst_pad_set_active (stream->srcpad, TRUE);
3049   gst_pad_sticky_events_foreach (pad, copy_sticky_events, stream->srcpad);
3050   gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad);
3051
3052   if (all_added) {
3053     GST_DEBUG_OBJECT (src, "We added all streams");
3054     /* when we get here, all stream are added and we can fire the no-more-pads
3055      * signal. */
3056     gst_element_no_more_pads (GST_ELEMENT_CAST (src));
3057   }
3058
3059   return;
3060
3061   /* ERRORS */
3062 unknown_stream:
3063   {
3064     GST_DEBUG_OBJECT (src, "ignoring unknown stream");
3065     GST_RTSP_STATE_UNLOCK (src);
3066     g_free (name);
3067     return;
3068   }
3069 }
3070
3071 static GstCaps *
3072 stream_get_caps_for_pt (GstRTSPStream * stream, guint pt)
3073 {
3074   guint i, len;
3075
3076   len = stream->ptmap->len;
3077   for (i = 0; i < len; i++) {
3078     PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);
3079     if (item->pt == pt)
3080       return item->caps;
3081   }
3082   return NULL;
3083 }
3084
3085 static GstCaps *
3086 request_pt_map (GstElement * manager, guint session, guint pt, GstRTSPSrc * src)
3087 {
3088   GstRTSPStream *stream;
3089   GstCaps *caps;
3090
3091   GST_DEBUG_OBJECT (src, "getting pt map for pt %d in session %d", pt, session);
3092
3093   GST_RTSP_STATE_LOCK (src);
3094   stream = find_stream (src, &session, (gpointer) find_stream_by_id);
3095   if (!stream)
3096     goto unknown_stream;
3097
3098   if ((caps = stream_get_caps_for_pt (stream, pt)))
3099     gst_caps_ref (caps);
3100   GST_RTSP_STATE_UNLOCK (src);
3101
3102   return caps;
3103
3104 unknown_stream:
3105   {
3106     GST_DEBUG_OBJECT (src, "unknown stream %d", session);
3107     GST_RTSP_STATE_UNLOCK (src);
3108     return NULL;
3109   }
3110 }
3111
3112 static void
3113 gst_rtspsrc_do_stream_eos (GstRTSPSrc * src, GstRTSPStream * stream)
3114 {
3115   GST_DEBUG_OBJECT (src, "setting stream for session %u to EOS", stream->id);
3116
3117   if (stream->eos)
3118     goto was_eos;
3119
3120   stream->eos = TRUE;
3121   gst_rtspsrc_stream_push_event (src, stream, gst_event_new_eos ());
3122   return;
3123
3124   /* ERRORS */
3125 was_eos:
3126   {
3127     GST_DEBUG_OBJECT (src, "stream for session %u was already EOS", stream->id);
3128     return;
3129   }
3130 }
3131
3132 static void
3133 on_bye_ssrc (GObject * session, GObject * source, GstRTSPStream * stream)
3134 {
3135   GstRTSPSrc *src = stream->parent;
3136   guint ssrc;
3137
3138   g_object_get (source, "ssrc", &ssrc, NULL);
3139
3140   GST_DEBUG_OBJECT (src, "source %08x, stream %08x, session %u received BYE",
3141       ssrc, stream->ssrc, stream->id);
3142
3143   if (ssrc == stream->ssrc)
3144     gst_rtspsrc_do_stream_eos (src, stream);
3145 }
3146
3147 static void
3148 on_timeout (GObject * session, GObject * source, GstRTSPStream * stream)
3149 {
3150   GstRTSPSrc *src = stream->parent;
3151   guint ssrc;
3152
3153   g_object_get (source, "ssrc", &ssrc, NULL);
3154
3155   GST_WARNING_OBJECT (src, "source %08x, stream %08x in session %u timed out",
3156       ssrc, stream->ssrc, stream->id);
3157
3158   if (ssrc == stream->ssrc)
3159     gst_rtspsrc_do_stream_eos (src, stream);
3160 }
3161
3162 static void
3163 on_npt_stop (GstElement * rtpbin, guint session, guint ssrc, GstRTSPSrc * src)
3164 {
3165   GstRTSPStream *stream;
3166
3167   GST_DEBUG_OBJECT (src, "source in session %u reached NPT stop", session);
3168
3169   /* get stream for session */
3170   stream = find_stream (src, &session, (gpointer) find_stream_by_id);
3171   if (stream) {
3172     gst_rtspsrc_do_stream_eos (src, stream);
3173   }
3174 }
3175
3176 static void
3177 on_ssrc_active (GObject * session, GObject * source, GstRTSPStream * stream)
3178 {
3179   GST_DEBUG_OBJECT (stream->parent, "source in session %u is active",
3180       stream->id);
3181 }
3182
3183 static void
3184 set_manager_buffer_mode (GstRTSPSrc * src)
3185 {
3186   GObjectClass *klass;
3187
3188   if (src->manager == NULL)
3189     return;
3190
3191   klass = G_OBJECT_GET_CLASS (G_OBJECT (src->manager));
3192
3193   if (!g_object_class_find_property (klass, "buffer-mode"))
3194     return;
3195
3196   if (src->buffer_mode != BUFFER_MODE_AUTO) {
3197     g_object_set (src->manager, "buffer-mode", src->buffer_mode, NULL);
3198
3199     return;
3200   }
3201
3202   GST_DEBUG_OBJECT (src,
3203       "auto buffering mode, have clock %" GST_PTR_FORMAT, src->provided_clock);
3204
3205   if (src->provided_clock) {
3206     GstClock *clock = gst_element_get_clock (GST_ELEMENT_CAST (src));
3207
3208     if (clock == src->provided_clock) {
3209       GST_DEBUG_OBJECT (src, "selected synced");
3210       g_object_set (src->manager, "buffer-mode", BUFFER_MODE_SYNCED, NULL);
3211
3212       if (clock)
3213         gst_object_unref (clock);
3214
3215       return;
3216     }
3217
3218     /* Otherwise fall-through and use another buffer mode */
3219     if (clock)
3220       gst_object_unref (clock);
3221   }
3222
3223   GST_DEBUG_OBJECT (src, "auto buffering mode");
3224   if (src->use_buffering) {
3225     GST_DEBUG_OBJECT (src, "selected buffer");
3226     g_object_set (src->manager, "buffer-mode", BUFFER_MODE_BUFFER, NULL);
3227   } else {
3228     GST_DEBUG_OBJECT (src, "selected slave");
3229     g_object_set (src->manager, "buffer-mode", BUFFER_MODE_SLAVE, NULL);
3230   }
3231 }
3232
3233 static GstCaps *
3234 request_key (GstElement * srtpdec, guint ssrc, GstRTSPStream * stream)
3235 {
3236   GST_DEBUG ("request key %u", ssrc);
3237   return gst_caps_ref (stream_get_caps_for_pt (stream, stream->default_pt));
3238 }
3239
3240 static GstElement *
3241 request_rtp_decoder (GstElement * rtpbin, guint session, GstRTSPStream * stream)
3242 {
3243   GST_DEBUG ("decoder session %u, stream %p, %d", session, stream, stream->id);
3244   if (stream->id != session)
3245     return NULL;
3246
3247   if (stream->profile != GST_RTSP_PROFILE_SAVP &&
3248       stream->profile != GST_RTSP_PROFILE_SAVPF)
3249     return NULL;
3250
3251   if (stream->srtpdec == NULL) {
3252     gchar *name;
3253
3254     name = g_strdup_printf ("srtpdec_%u", session);
3255     stream->srtpdec = gst_element_factory_make ("srtpdec", name);
3256     g_free (name);
3257
3258     g_signal_connect (stream->srtpdec, "request-key",
3259         (GCallback) request_key, stream);
3260   }
3261   return gst_object_ref (stream->srtpdec);
3262 }
3263
3264 static GstElement *
3265 request_rtcp_encoder (GstElement * rtpbin, guint session,
3266     GstRTSPStream * stream)
3267 {
3268   gchar *name;
3269   GstPad *pad;
3270
3271   GST_DEBUG ("decoder session %u, stream %p, %d", session, stream, stream->id);
3272   if (stream->id != session)
3273     return NULL;
3274
3275   if (stream->profile != GST_RTSP_PROFILE_SAVP &&
3276       stream->profile != GST_RTSP_PROFILE_SAVPF)
3277     return NULL;
3278
3279   if (stream->srtpenc == NULL) {
3280     GstStructure *s;
3281
3282     name = g_strdup_printf ("srtpenc_%u", session);
3283     stream->srtpenc = gst_element_factory_make ("srtpenc", name);
3284     g_free (name);
3285
3286     /* get RTCP crypto parameters from caps */
3287     s = gst_caps_get_structure (stream->srtcpparams, 0);
3288     if (s) {
3289       GstBuffer *buf;
3290       const gchar *str;
3291       GType ciphertype, authtype;
3292       GValue rtcp_cipher = G_VALUE_INIT, rtcp_auth = G_VALUE_INIT;
3293
3294       ciphertype = g_type_from_name ("GstSrtpCipherType");
3295       authtype = g_type_from_name ("GstSrtpAuthType");
3296       g_value_init (&rtcp_cipher, ciphertype);
3297       g_value_init (&rtcp_auth, authtype);
3298
3299       str = gst_structure_get_string (s, "srtcp-cipher");
3300       gst_value_deserialize (&rtcp_cipher, str);
3301       str = gst_structure_get_string (s, "srtcp-auth");
3302       gst_value_deserialize (&rtcp_auth, str);
3303       gst_structure_get (s, "srtp-key", GST_TYPE_BUFFER, &buf, NULL);
3304
3305       g_object_set_property (G_OBJECT (stream->srtpenc), "rtcp-cipher",
3306           &rtcp_cipher);
3307       g_object_set_property (G_OBJECT (stream->srtpenc), "rtcp-auth",
3308           &rtcp_auth);
3309       g_object_set (stream->srtpenc, "key", buf, NULL);
3310
3311       g_value_unset (&rtcp_cipher);
3312       g_value_unset (&rtcp_auth);
3313       gst_buffer_unref (buf);
3314     }
3315   }
3316   name = g_strdup_printf ("rtcp_sink_%d", session);
3317   pad = gst_element_get_request_pad (stream->srtpenc, name);
3318   g_free (name);
3319   gst_object_unref (pad);
3320
3321   return gst_object_ref (stream->srtpenc);
3322 }
3323
3324 static GstElement *
3325 request_aux_receiver (GstElement * rtpbin, guint sessid, GstRTSPSrc * src)
3326 {
3327   GstElement *rtx, *bin;
3328   GstPad *pad;
3329   gchar *name;
3330   GstRTSPStream *stream;
3331
3332   stream = find_stream (src, &sessid, (gpointer) find_stream_by_id);
3333   if (!stream) {
3334     GST_WARNING_OBJECT (src, "Stream %u not found", sessid);
3335     return NULL;
3336   }
3337
3338   GST_INFO_OBJECT (src, "creating retransmision receiver for session %u "
3339       "with map %" GST_PTR_FORMAT, sessid, stream->rtx_pt_map);
3340   bin = gst_bin_new (NULL);
3341   rtx = gst_element_factory_make ("rtprtxreceive", NULL);
3342   g_object_set (rtx, "payload-type-map", stream->rtx_pt_map, NULL);
3343   gst_bin_add (GST_BIN (bin), rtx);
3344
3345   pad = gst_element_get_static_pad (rtx, "src");
3346   name = g_strdup_printf ("src_%u", sessid);
3347   gst_element_add_pad (bin, gst_ghost_pad_new (name, pad));
3348   g_free (name);
3349   gst_object_unref (pad);
3350
3351   pad = gst_element_get_static_pad (rtx, "sink");
3352   name = g_strdup_printf ("sink_%u", sessid);
3353   gst_element_add_pad (bin, gst_ghost_pad_new (name, pad));
3354   g_free (name);
3355   gst_object_unref (pad);
3356
3357   return bin;
3358 }
3359
3360 static void
3361 add_retransmission (GstRTSPSrc * src, GstRTSPTransport * transport)
3362 {
3363   GList *walk;
3364   guint signal_id;
3365   gboolean do_retransmission = FALSE;
3366
3367   if (transport->trans != GST_RTSP_TRANS_RTP)
3368     return;
3369   if (transport->profile != GST_RTSP_PROFILE_AVPF &&
3370       transport->profile != GST_RTSP_PROFILE_SAVPF)
3371     return;
3372
3373   signal_id = g_signal_lookup ("request-aux-receiver",
3374       G_OBJECT_TYPE (src->manager));
3375   /* there's already something connected */
3376   if (g_signal_handler_find (src->manager, G_SIGNAL_MATCH_ID, signal_id, 0,
3377           NULL, NULL, NULL) != 0) {
3378     GST_DEBUG_OBJECT (src, "Not adding RTX AUX element as "
3379         "\"request-aux-receiver\" signal is "
3380         "already used by the application");
3381     return;
3382   }
3383
3384   /* build the retransmission payload type map */
3385   for (walk = src->streams; walk; walk = g_list_next (walk)) {
3386     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
3387     gboolean do_retransmission_stream = FALSE;
3388     int i;
3389
3390     if (stream->rtx_pt_map)
3391       gst_structure_free (stream->rtx_pt_map);
3392     stream->rtx_pt_map = gst_structure_new_empty ("application/x-rtp-pt-map");
3393
3394     for (i = 0; i < stream->ptmap->len; i++) {
3395       PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);
3396       GstStructure *s = gst_caps_get_structure (item->caps, 0);
3397       const gchar *encoding;
3398
3399       /* we only care about RTX streams */
3400       if ((encoding = gst_structure_get_string (s, "encoding-name"))
3401           && g_strcmp0 (encoding, "RTX") == 0) {
3402         const gchar *stream_pt_s;
3403         gint rtx_pt;
3404
3405         if (gst_structure_get_int (s, "payload", &rtx_pt)
3406             && (stream_pt_s = gst_structure_get_string (s, "apt"))) {
3407
3408           if (rtx_pt != 0) {
3409             gst_structure_set (stream->rtx_pt_map, stream_pt_s, G_TYPE_UINT,
3410                 rtx_pt, NULL);
3411             do_retransmission_stream = TRUE;
3412           }
3413         }
3414       }
3415     }
3416
3417     if (do_retransmission_stream) {
3418       GST_DEBUG_OBJECT (src, "built retransmission payload map for stream "
3419           "id %i: %" GST_PTR_FORMAT, stream->id, stream->rtx_pt_map);
3420       do_retransmission = TRUE;
3421     } else {
3422       GST_DEBUG_OBJECT (src, "no retransmission payload map for stream "
3423           "id %i", stream->id);
3424       gst_structure_free (stream->rtx_pt_map);
3425       stream->rtx_pt_map = NULL;
3426     }
3427   }
3428
3429   if (do_retransmission) {
3430     GST_DEBUG_OBJECT (src, "Enabling retransmissions");
3431
3432     g_object_set (src->manager, "do-retransmission", TRUE, NULL);
3433
3434     /* enable RFC4588 retransmission handling by setting rtprtxreceive
3435      * as the "aux" element of rtpbin */
3436     g_signal_connect (src->manager, "request-aux-receiver",
3437         (GCallback) request_aux_receiver, src);
3438   } else {
3439     GST_DEBUG_OBJECT (src,
3440         "Not enabling retransmissions as no stream had a retransmission payload map");
3441   }
3442 }
3443
3444 /* try to get and configure a manager */
3445 static gboolean
3446 gst_rtspsrc_stream_configure_manager (GstRTSPSrc * src, GstRTSPStream * stream,
3447     GstRTSPTransport * transport)
3448 {
3449   const gchar *manager;
3450   gchar *name;
3451   GstStateChangeReturn ret;
3452
3453   /* find a manager */
3454   if (gst_rtsp_transport_get_manager (transport->trans, &manager, 0) < 0)
3455     goto no_manager;
3456
3457   if (manager) {
3458     GST_DEBUG_OBJECT (src, "using manager %s", manager);
3459
3460     /* configure the manager */
3461     if (src->manager == NULL) {
3462       GObjectClass *klass;
3463
3464       if (!(src->manager = gst_element_factory_make (manager, "manager"))) {
3465         /* fallback */
3466         if (gst_rtsp_transport_get_manager (transport->trans, &manager, 1) < 0)
3467           goto no_manager;
3468
3469         if (!manager)
3470           goto use_no_manager;
3471
3472         if (!(src->manager = gst_element_factory_make (manager, "manager")))
3473           goto manager_failed;
3474       }
3475
3476       /* we manage this element */
3477       gst_element_set_locked_state (src->manager, TRUE);
3478       gst_bin_add (GST_BIN_CAST (src), src->manager);
3479
3480       ret = gst_element_set_state (src->manager, GST_STATE_PAUSED);
3481       if (ret == GST_STATE_CHANGE_FAILURE)
3482         goto start_manager_failure;
3483
3484       g_object_set (src->manager, "latency", src->latency, NULL);
3485
3486       klass = G_OBJECT_GET_CLASS (G_OBJECT (src->manager));
3487
3488       if (g_object_class_find_property (klass, "ntp-sync")) {
3489         g_object_set (src->manager, "ntp-sync", src->ntp_sync, NULL);
3490       }
3491
3492       if (src->use_pipeline_clock) {
3493         if (g_object_class_find_property (klass, "use-pipeline-clock")) {
3494           g_object_set (src->manager, "use-pipeline-clock", TRUE, NULL);
3495         }
3496       } else {
3497         if (g_object_class_find_property (klass, "ntp-time-source")) {
3498           g_object_set (src->manager, "ntp-time-source", src->ntp_time_source,
3499               NULL);
3500         }
3501       }
3502
3503       if (src->sdes && g_object_class_find_property (klass, "sdes")) {
3504         g_object_set (src->manager, "sdes", src->sdes, NULL);
3505       }
3506
3507       if (g_object_class_find_property (klass, "drop-on-latency")) {
3508         g_object_set (src->manager, "drop-on-latency", src->drop_on_latency,
3509             NULL);
3510       }
3511
3512       if (g_object_class_find_property (klass, "max-rtcp-rtp-time-diff")) {
3513         g_object_set (src->manager, "max-rtcp-rtp-time-diff",
3514             src->max_rtcp_rtp_time_diff, NULL);
3515       }
3516
3517       /* buffer mode pauses are handled by adding offsets to buffer times,
3518        * but some depayloaders may have a hard time syncing output times
3519        * with such input times, e.g. container ones, most notably ASF */
3520       /* TODO alternatives are having an event that indicates these shifts,
3521        * or having rtsp extensions provide suggestion on buffer mode */
3522       /* valid duration implies not likely live pipeline,
3523        * so slaving in jitterbuffer does not make much sense
3524        * (and might mess things up due to bursts) */
3525       if (GST_CLOCK_TIME_IS_VALID (src->segment.duration) &&
3526           src->segment.duration && stream->container) {
3527         src->use_buffering = TRUE;
3528       } else {
3529         src->use_buffering = FALSE;
3530       }
3531
3532       set_manager_buffer_mode (src);
3533
3534       /* connect to signals */
3535       GST_DEBUG_OBJECT (src, "connect to signals on session manager, stream %p",
3536           stream);
3537       src->manager_sig_id =
3538           g_signal_connect (src->manager, "pad-added",
3539           (GCallback) new_manager_pad, src);
3540       src->manager_ptmap_id =
3541           g_signal_connect (src->manager, "request-pt-map",
3542           (GCallback) request_pt_map, src);
3543
3544       g_signal_connect (src->manager, "on-npt-stop", (GCallback) on_npt_stop,
3545           src);
3546
3547       g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_NEW_MANAGER], 0,
3548           src->manager);
3549
3550       if (src->do_retransmission)
3551         add_retransmission (src, transport);
3552     }
3553     g_signal_connect (src->manager, "request-rtp-decoder",
3554         (GCallback) request_rtp_decoder, stream);
3555     g_signal_connect (src->manager, "request-rtcp-decoder",
3556         (GCallback) request_rtp_decoder, stream);
3557     g_signal_connect (src->manager, "request-rtcp-encoder",
3558         (GCallback) request_rtcp_encoder, stream);
3559
3560     /* we stream directly to the manager, get some pads. Each RTSP stream goes
3561      * into a separate RTP session. */
3562     name = g_strdup_printf ("recv_rtp_sink_%u", stream->id);
3563     stream->channelpad[0] = gst_element_get_request_pad (src->manager, name);
3564     g_free (name);
3565     name = g_strdup_printf ("recv_rtcp_sink_%u", stream->id);
3566     stream->channelpad[1] = gst_element_get_request_pad (src->manager, name);
3567     g_free (name);
3568
3569     /* now configure the bandwidth in the manager */
3570     if (g_signal_lookup ("get-internal-session",
3571             G_OBJECT_TYPE (src->manager)) != 0) {
3572       GObject *rtpsession;
3573
3574       g_signal_emit_by_name (src->manager, "get-internal-session", stream->id,
3575           &rtpsession);
3576       if (rtpsession) {
3577         GstRTPProfile rtp_profile;
3578
3579         GST_INFO_OBJECT (src, "configure bandwidth in session %p", rtpsession);
3580
3581         stream->session = rtpsession;
3582
3583         if (stream->as_bandwidth != -1) {
3584           GST_INFO_OBJECT (src, "setting AS: %f",
3585               (gdouble) (stream->as_bandwidth * 1000));
3586           g_object_set (rtpsession, "bandwidth",
3587               (gdouble) (stream->as_bandwidth * 1000), NULL);
3588         }
3589         if (stream->rr_bandwidth != -1) {
3590           GST_INFO_OBJECT (src, "setting RR: %u", stream->rr_bandwidth);
3591           g_object_set (rtpsession, "rtcp-rr-bandwidth", stream->rr_bandwidth,
3592               NULL);
3593         }
3594         if (stream->rs_bandwidth != -1) {
3595           GST_INFO_OBJECT (src, "setting RS: %u", stream->rs_bandwidth);
3596           g_object_set (rtpsession, "rtcp-rs-bandwidth", stream->rs_bandwidth,
3597               NULL);
3598         }
3599
3600         switch (stream->profile) {
3601           case GST_RTSP_PROFILE_AVPF:
3602             rtp_profile = GST_RTP_PROFILE_AVPF;
3603             break;
3604           case GST_RTSP_PROFILE_SAVP:
3605             rtp_profile = GST_RTP_PROFILE_SAVP;
3606             break;
3607           case GST_RTSP_PROFILE_SAVPF:
3608             rtp_profile = GST_RTP_PROFILE_SAVPF;
3609             break;
3610           case GST_RTSP_PROFILE_AVP:
3611           default:
3612             rtp_profile = GST_RTP_PROFILE_AVP;
3613             break;
3614         }
3615
3616         g_object_set (rtpsession, "rtp-profile", rtp_profile, NULL);
3617
3618         g_object_set (rtpsession, "probation", src->probation, NULL);
3619
3620         g_object_set (rtpsession, "internal-ssrc", stream->send_ssrc, NULL);
3621
3622         g_signal_connect (rtpsession, "on-bye-ssrc", (GCallback) on_bye_ssrc,
3623             stream);
3624         g_signal_connect (rtpsession, "on-bye-timeout", (GCallback) on_timeout,
3625             stream);
3626         g_signal_connect (rtpsession, "on-timeout", (GCallback) on_timeout,
3627             stream);
3628         g_signal_connect (rtpsession, "on-ssrc-active",
3629             (GCallback) on_ssrc_active, stream);
3630       }
3631     }
3632   }
3633
3634 use_no_manager:
3635   return TRUE;
3636
3637   /* ERRORS */
3638 no_manager:
3639   {
3640     GST_DEBUG_OBJECT (src, "cannot get a session manager");
3641     return FALSE;
3642   }
3643 manager_failed:
3644   {
3645     GST_DEBUG_OBJECT (src, "no session manager element %s found", manager);
3646     return FALSE;
3647   }
3648 start_manager_failure:
3649   {
3650     GST_DEBUG_OBJECT (src, "could not start session manager");
3651     return FALSE;
3652   }
3653 }
3654
3655 /* free the UDP sources allocated when negotiating a transport.
3656  * This function is called when the server negotiated to a transport where the
3657  * UDP sources are not needed anymore, such as TCP or multicast. */
3658 static void
3659 gst_rtspsrc_stream_free_udp (GstRTSPStream * stream)
3660 {
3661   gint i;
3662
3663   for (i = 0; i < 2; i++) {
3664     if (stream->udpsrc[i]) {
3665       GST_DEBUG ("free UDP source %d for stream %p", i, stream);
3666       gst_element_set_state (stream->udpsrc[i], GST_STATE_NULL);
3667       gst_object_unref (stream->udpsrc[i]);
3668       stream->udpsrc[i] = NULL;
3669     }
3670   }
3671 }
3672
3673 /* for TCP, create pads to send and receive data to and from the manager and to
3674  * intercept various events and queries
3675  */
3676 static gboolean
3677 gst_rtspsrc_stream_configure_tcp (GstRTSPSrc * src, GstRTSPStream * stream,
3678     GstRTSPTransport * transport, GstPad ** outpad)
3679 {
3680   gchar *name;
3681   GstPadTemplate *template;
3682   GstPad *pad0, *pad1;
3683
3684   /* configure for interleaved delivery, nothing needs to be done
3685    * here, the loop function will call the chain functions of the
3686    * session manager. */
3687   stream->channel[0] = transport->interleaved.min;
3688   stream->channel[1] = transport->interleaved.max;
3689   GST_DEBUG_OBJECT (src, "stream %p on channels %d-%d", stream,
3690       stream->channel[0], stream->channel[1]);
3691
3692   /* we can remove the allocated UDP ports now */
3693   gst_rtspsrc_stream_free_udp (stream);
3694
3695   /* no session manager, send data to srcpad directly */
3696   if (!stream->channelpad[0]) {
3697     GST_DEBUG_OBJECT (src, "no manager, creating pad");
3698
3699     /* create a new pad we will use to stream to */
3700     name = g_strdup_printf ("stream_%u", stream->id);
3701     template = gst_static_pad_template_get (&rtptemplate);
3702     stream->channelpad[0] = gst_pad_new_from_template (template, name);
3703     gst_object_unref (template);
3704     g_free (name);
3705
3706     /* set caps and activate */
3707     gst_pad_use_fixed_caps (stream->channelpad[0]);
3708     gst_pad_set_active (stream->channelpad[0], TRUE);
3709
3710     *outpad = gst_object_ref (stream->channelpad[0]);
3711   } else {
3712     GST_DEBUG_OBJECT (src, "using manager source pad");
3713
3714     template = gst_static_pad_template_get (&anysrctemplate);
3715
3716     /* allocate pads for sending the channel data into the manager */
3717     pad0 = gst_pad_new_from_template (template, "internalsrc_0");
3718     gst_pad_link_full (pad0, stream->channelpad[0], GST_PAD_LINK_CHECK_NOTHING);
3719     gst_object_unref (stream->channelpad[0]);
3720     stream->channelpad[0] = pad0;
3721     gst_pad_set_event_function (pad0, gst_rtspsrc_handle_internal_src_event);
3722     gst_pad_set_query_function (pad0, gst_rtspsrc_handle_internal_src_query);
3723     gst_pad_set_element_private (pad0, src);
3724     gst_pad_set_active (pad0, TRUE);
3725
3726     if (stream->channelpad[1]) {
3727       /* if we have a sinkpad for the other channel, create a pad and link to the
3728        * manager. */
3729       pad1 = gst_pad_new_from_template (template, "internalsrc_1");
3730       gst_pad_set_event_function (pad1, gst_rtspsrc_handle_internal_src_event);
3731       gst_pad_link_full (pad1, stream->channelpad[1],
3732           GST_PAD_LINK_CHECK_NOTHING);
3733       gst_object_unref (stream->channelpad[1]);
3734       stream->channelpad[1] = pad1;
3735       gst_pad_set_active (pad1, TRUE);
3736     }
3737     gst_object_unref (template);
3738   }
3739   /* setup RTCP transport back to the server if we have to. */
3740   if (src->manager && src->do_rtcp) {
3741     GstPad *pad;
3742
3743     template = gst_static_pad_template_get (&anysinktemplate);
3744
3745     stream->rtcppad = gst_pad_new_from_template (template, "internalsink_0");
3746     gst_pad_set_chain_function (stream->rtcppad, gst_rtspsrc_sink_chain);
3747     gst_pad_set_element_private (stream->rtcppad, stream);
3748     gst_pad_set_active (stream->rtcppad, TRUE);
3749
3750     /* get session RTCP pad */
3751     name = g_strdup_printf ("send_rtcp_src_%u", stream->id);
3752     pad = gst_element_get_request_pad (src->manager, name);
3753     g_free (name);
3754
3755     /* and link */
3756     if (pad) {
3757       gst_pad_link_full (pad, stream->rtcppad, GST_PAD_LINK_CHECK_NOTHING);
3758       gst_object_unref (pad);
3759     }
3760
3761     gst_object_unref (template);
3762   }
3763   return TRUE;
3764 }
3765
3766 static void
3767 gst_rtspsrc_get_transport_info (GstRTSPSrc * src, GstRTSPStream * stream,
3768     GstRTSPTransport * transport, const gchar ** destination, gint * min,
3769     gint * max, guint * ttl)
3770 {
3771   if (transport->lower_transport == GST_RTSP_LOWER_TRANS_UDP_MCAST) {
3772     if (destination) {
3773       if (!(*destination = transport->destination))
3774         *destination = stream->destination;
3775     }
3776     if (min && max) {
3777       /* transport first */
3778       *min = transport->port.min;
3779       *max = transport->port.max;
3780       if (*min == -1 && *max == -1) {
3781         /* then try from SDP */
3782         if (stream->port != 0) {
3783           *min = stream->port;
3784           *max = stream->port + 1;
3785         }
3786       }
3787     }
3788
3789     if (ttl) {
3790       if (!(*ttl = transport->ttl))
3791         *ttl = stream->ttl;
3792     }
3793   } else {
3794     if (destination) {
3795       /* first take the source, then the endpoint to figure out where to send
3796        * the RTCP. */
3797       if (!(*destination = transport->source)) {
3798         if (src->conninfo.connection)
3799           *destination = gst_rtsp_connection_get_ip (src->conninfo.connection);
3800         else if (stream->conninfo.connection)
3801           *destination =
3802               gst_rtsp_connection_get_ip (stream->conninfo.connection);
3803       }
3804     }
3805     if (min && max) {
3806       /* for unicast we only expect the ports here */
3807       *min = transport->server_port.min;
3808       *max = transport->server_port.max;
3809     }
3810   }
3811 }
3812
3813 /* For multicast create UDP sources and join the multicast group. */
3814 static gboolean
3815 gst_rtspsrc_stream_configure_mcast (GstRTSPSrc * src, GstRTSPStream * stream,
3816     GstRTSPTransport * transport, GstPad ** outpad)
3817 {
3818   gchar *uri;
3819   const gchar *destination;
3820   gint min, max;
3821
3822   GST_DEBUG_OBJECT (src, "creating UDP sources for multicast");
3823
3824   /* we can remove the allocated UDP ports now */
3825   gst_rtspsrc_stream_free_udp (stream);
3826
3827   gst_rtspsrc_get_transport_info (src, stream, transport, &destination, &min,
3828       &max, NULL);
3829
3830   /* we need a destination now */
3831   if (destination == NULL)
3832     goto no_destination;
3833
3834   /* we really need ports now or we won't be able to receive anything at all */
3835   if (min == -1 && max == -1)
3836     goto no_ports;
3837
3838   GST_DEBUG_OBJECT (src, "have destination '%s' and ports (%d)-(%d)",
3839       destination, min, max);
3840
3841   /* creating UDP source for RTP */
3842   if (min != -1) {
3843     uri = g_strdup_printf ("udp://%s:%d", destination, min);
3844     stream->udpsrc[0] =
3845         gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
3846     g_free (uri);
3847     if (stream->udpsrc[0] == NULL)
3848       goto no_element;
3849
3850     /* take ownership */
3851     gst_object_ref_sink (stream->udpsrc[0]);
3852
3853     if (src->udp_buffer_size != 0)
3854       g_object_set (G_OBJECT (stream->udpsrc[0]), "buffer-size",
3855           src->udp_buffer_size, NULL);
3856
3857     if (src->multi_iface != NULL)
3858       g_object_set (G_OBJECT (stream->udpsrc[0]), "multicast-iface",
3859           src->multi_iface, NULL);
3860
3861     /* change state */
3862     gst_element_set_locked_state (stream->udpsrc[0], TRUE);
3863     gst_element_set_state (stream->udpsrc[0], GST_STATE_READY);
3864   }
3865
3866   /* creating another UDP source for RTCP */
3867   if (max != -1) {
3868     GstCaps *caps;
3869
3870     uri = g_strdup_printf ("udp://%s:%d", destination, max);
3871     stream->udpsrc[1] =
3872         gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
3873     g_free (uri);
3874     if (stream->udpsrc[1] == NULL)
3875       goto no_element;
3876
3877     if (stream->profile == GST_RTSP_PROFILE_SAVP ||
3878         stream->profile == GST_RTSP_PROFILE_SAVPF)
3879       caps = gst_caps_new_empty_simple ("application/x-srtcp");
3880     else
3881       caps = gst_caps_new_empty_simple ("application/x-rtcp");
3882     g_object_set (stream->udpsrc[1], "caps", caps, NULL);
3883     gst_caps_unref (caps);
3884
3885     /* take ownership */
3886     gst_object_ref_sink (stream->udpsrc[1]);
3887
3888     if (src->multi_iface != NULL)
3889       g_object_set (G_OBJECT (stream->udpsrc[0]), "multicast-iface",
3890           src->multi_iface, NULL);
3891
3892     gst_element_set_state (stream->udpsrc[1], GST_STATE_READY);
3893   }
3894   return TRUE;
3895
3896   /* ERRORS */
3897 no_element:
3898   {
3899     GST_DEBUG_OBJECT (src, "no UDP source element found");
3900     return FALSE;
3901   }
3902 no_destination:
3903   {
3904     GST_DEBUG_OBJECT (src, "no destination found");
3905     return FALSE;
3906   }
3907 no_ports:
3908   {
3909     GST_DEBUG_OBJECT (src, "no ports found");
3910     return FALSE;
3911   }
3912 }
3913
3914 /* configure the remainder of the UDP ports */
3915 static gboolean
3916 gst_rtspsrc_stream_configure_udp (GstRTSPSrc * src, GstRTSPStream * stream,
3917     GstRTSPTransport * transport, GstPad ** outpad)
3918 {
3919   /* we manage the UDP elements now. For unicast, the UDP sources where
3920    * allocated in the stream when we suggested a transport. */
3921   if (stream->udpsrc[0]) {
3922     GstCaps *caps;
3923
3924     gst_element_set_locked_state (stream->udpsrc[0], TRUE);
3925     gst_bin_add (GST_BIN_CAST (src), stream->udpsrc[0]);
3926
3927     GST_DEBUG_OBJECT (src, "setting up UDP source");
3928
3929     /* configure a timeout on the UDP port. When the timeout message is
3930      * posted, we assume UDP transport is not possible. We reconnect using TCP
3931      * if we can. */
3932     g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout",
3933         src->udp_timeout * 1000, NULL);
3934
3935     if ((caps = stream_get_caps_for_pt (stream, stream->default_pt)))
3936       g_object_set (stream->udpsrc[0], "caps", caps, NULL);
3937
3938     /* get output pad of the UDP source. */
3939     *outpad = gst_element_get_static_pad (stream->udpsrc[0], "src");
3940
3941     /* save it so we can unblock */
3942     stream->blockedpad = *outpad;
3943
3944     /* configure pad block on the pad. As soon as there is dataflow on the
3945      * UDP source, we know that UDP is not blocked by a firewall and we can
3946      * configure all the streams to let the application autoplug decoders. */
3947     stream->blockid =
3948         gst_pad_add_probe (stream->blockedpad,
3949         GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER |
3950         GST_PAD_PROBE_TYPE_BUFFER_LIST, pad_blocked, src, NULL);
3951
3952     if (stream->channelpad[0]) {
3953       GST_DEBUG_OBJECT (src, "connecting UDP source 0 to manager");
3954       /* configure for UDP delivery, we need to connect the UDP pads to
3955        * the session plugin. */
3956       gst_pad_link_full (*outpad, stream->channelpad[0],
3957           GST_PAD_LINK_CHECK_NOTHING);
3958       gst_object_unref (*outpad);
3959       *outpad = NULL;
3960       /* we connected to pad-added signal to get pads from the manager */
3961     } else {
3962       GST_DEBUG_OBJECT (src, "using UDP src pad as output");
3963     }
3964   }
3965
3966   /* RTCP port */
3967   if (stream->udpsrc[1]) {
3968     GstCaps *caps;
3969
3970     gst_element_set_locked_state (stream->udpsrc[1], TRUE);
3971     gst_bin_add (GST_BIN_CAST (src), stream->udpsrc[1]);
3972
3973     if (stream->profile == GST_RTSP_PROFILE_SAVP ||
3974         stream->profile == GST_RTSP_PROFILE_SAVPF)
3975       caps = gst_caps_new_empty_simple ("application/x-srtcp");
3976     else
3977       caps = gst_caps_new_empty_simple ("application/x-rtcp");
3978     g_object_set (stream->udpsrc[1], "caps", caps, NULL);
3979     gst_caps_unref (caps);
3980
3981     if (stream->channelpad[1]) {
3982       GstPad *pad;
3983
3984       GST_DEBUG_OBJECT (src, "connecting UDP source 1 to manager");
3985
3986       pad = gst_element_get_static_pad (stream->udpsrc[1], "src");
3987       gst_pad_link_full (pad, stream->channelpad[1],
3988           GST_PAD_LINK_CHECK_NOTHING);
3989       gst_object_unref (pad);
3990     } else {
3991       /* leave unlinked */
3992     }
3993   }
3994   return TRUE;
3995 }
3996
3997 /* configure the UDP sink back to the server for status reports */
3998 static gboolean
3999 gst_rtspsrc_stream_configure_udp_sinks (GstRTSPSrc * src,
4000     GstRTSPStream * stream, GstRTSPTransport * transport)
4001 {
4002   GstPad *pad;
4003   gint rtp_port, rtcp_port;
4004   gboolean do_rtp, do_rtcp;
4005   const gchar *destination;
4006   gchar *uri, *name;
4007   guint ttl = 0;
4008   GSocket *socket;
4009
4010   /* get transport info */
4011   gst_rtspsrc_get_transport_info (src, stream, transport, &destination,
4012       &rtp_port, &rtcp_port, &ttl);
4013
4014   /* see what we need to do */
4015   do_rtp = (rtp_port != -1);
4016   /* it's possible that the server does not want us to send RTCP in which case
4017    * the port is -1 */
4018   do_rtcp = (rtcp_port != -1 && src->manager != NULL && src->do_rtcp);
4019
4020   /* we need a destination when we have RTP or RTCP ports */
4021   if (destination == NULL && (do_rtp || do_rtcp))
4022     goto no_destination;
4023
4024   /* try to construct the fakesrc to the RTP port of the server to open up any
4025    * NAT firewalls */
4026   if (do_rtp) {
4027     GST_DEBUG_OBJECT (src, "configure RTP UDP sink for %s:%d", destination,
4028         rtp_port);
4029
4030     uri = g_strdup_printf ("udp://%s:%d", destination, rtp_port);
4031     stream->udpsink[0] =
4032         gst_element_make_from_uri (GST_URI_SINK, uri, NULL, NULL);
4033     g_free (uri);
4034     if (stream->udpsink[0] == NULL)
4035       goto no_sink_element;
4036
4037     /* don't join multicast group, we will have the source socket do that */
4038     /* no sync or async state changes needed */
4039     g_object_set (G_OBJECT (stream->udpsink[0]), "auto-multicast", FALSE,
4040         "loop", FALSE, "sync", FALSE, "async", FALSE, NULL);
4041     if (ttl > 0)
4042       g_object_set (G_OBJECT (stream->udpsink[0]), "ttl", ttl, NULL);
4043
4044     if (stream->udpsrc[0]) {
4045       /* configure socket, we give it the same UDP socket as the udpsrc for RTP
4046        * so that NAT firewalls will open a hole for us */
4047       g_object_get (G_OBJECT (stream->udpsrc[0]), "used-socket", &socket, NULL);
4048       GST_DEBUG_OBJECT (src, "RTP UDP src has sock %p", socket);
4049       /* configure socket and make sure udpsink does not close it when shutting
4050        * down, it belongs to udpsrc after all. */
4051       g_object_set (G_OBJECT (stream->udpsink[0]), "socket", socket,
4052           "close-socket", FALSE, NULL);
4053       g_object_unref (socket);
4054     }
4055
4056     /* the source for the dummy packets to open up NAT */
4057     stream->fakesrc = gst_element_factory_make ("fakesrc", NULL);
4058     if (stream->fakesrc == NULL)
4059       goto no_fakesrc_element;
4060
4061     /* random data in 5 buffers, a size of 200 bytes should be fine */
4062     g_object_set (G_OBJECT (stream->fakesrc), "filltype", 3, "num-buffers", 5,
4063         "sizetype", 2, "sizemax", 200, "silent", TRUE, NULL);
4064
4065     /* we don't want to consider this a sink */
4066     GST_OBJECT_FLAG_UNSET (stream->udpsink[0], GST_ELEMENT_FLAG_SINK);
4067
4068     /* keep everything locked */
4069     gst_element_set_locked_state (stream->udpsink[0], TRUE);
4070     gst_element_set_locked_state (stream->fakesrc, TRUE);
4071
4072     gst_object_ref (stream->udpsink[0]);
4073     gst_bin_add (GST_BIN_CAST (src), stream->udpsink[0]);
4074     gst_object_ref (stream->fakesrc);
4075     gst_bin_add (GST_BIN_CAST (src), stream->fakesrc);
4076
4077     gst_element_link_pads_full (stream->fakesrc, "src", stream->udpsink[0],
4078         "sink", GST_PAD_LINK_CHECK_NOTHING);
4079   }
4080   if (do_rtcp) {
4081     GST_DEBUG_OBJECT (src, "configure RTCP UDP sink for %s:%d", destination,
4082         rtcp_port);
4083
4084     uri = g_strdup_printf ("udp://%s:%d", destination, rtcp_port);
4085     stream->udpsink[1] =
4086         gst_element_make_from_uri (GST_URI_SINK, uri, NULL, NULL);
4087     g_free (uri);
4088     if (stream->udpsink[1] == NULL)
4089       goto no_sink_element;
4090
4091     /* don't join multicast group, we will have the source socket do that */
4092     /* no sync or async state changes needed */
4093     g_object_set (G_OBJECT (stream->udpsink[1]), "auto-multicast", FALSE,
4094         "loop", FALSE, "sync", FALSE, "async", FALSE, NULL);
4095     if (ttl > 0)
4096       g_object_set (G_OBJECT (stream->udpsink[0]), "ttl", ttl, NULL);
4097
4098     if (stream->udpsrc[1]) {
4099       /* configure socket, we give it the same UDP socket as the udpsrc for RTCP
4100        * because some servers check the port number of where it sends RTCP to identify
4101        * the RTCP packets it receives */
4102       g_object_get (G_OBJECT (stream->udpsrc[1]), "used-socket", &socket, NULL);
4103       GST_DEBUG_OBJECT (src, "RTCP UDP src has sock %p", socket);
4104       /* configure socket and make sure udpsink does not close it when shutting
4105        * down, it belongs to udpsrc after all. */
4106       g_object_set (G_OBJECT (stream->udpsink[1]), "socket", socket,
4107           "close-socket", FALSE, NULL);
4108       g_object_unref (socket);
4109     }
4110
4111     /* we don't want to consider this a sink */
4112     GST_OBJECT_FLAG_UNSET (stream->udpsink[1], GST_ELEMENT_FLAG_SINK);
4113
4114     /* we keep this playing always */
4115     gst_element_set_locked_state (stream->udpsink[1], TRUE);
4116     gst_element_set_state (stream->udpsink[1], GST_STATE_PLAYING);
4117
4118     gst_object_ref (stream->udpsink[1]);
4119     gst_bin_add (GST_BIN_CAST (src), stream->udpsink[1]);
4120
4121     stream->rtcppad = gst_element_get_static_pad (stream->udpsink[1], "sink");
4122
4123     /* get session RTCP pad */
4124     name = g_strdup_printf ("send_rtcp_src_%u", stream->id);
4125     pad = gst_element_get_request_pad (src->manager, name);
4126     g_free (name);
4127
4128     /* and link */
4129     if (pad) {
4130       gst_pad_link_full (pad, stream->rtcppad, GST_PAD_LINK_CHECK_NOTHING);
4131       gst_object_unref (pad);
4132     }
4133   }
4134
4135   return TRUE;
4136
4137   /* ERRORS */
4138 no_destination:
4139   {
4140     GST_DEBUG_OBJECT (src, "no destination address specified");
4141     return FALSE;
4142   }
4143 no_sink_element:
4144   {
4145     GST_DEBUG_OBJECT (src, "no UDP sink element found");
4146     return FALSE;
4147   }
4148 no_fakesrc_element:
4149   {
4150     GST_DEBUG_OBJECT (src, "no fakesrc element found");
4151     return FALSE;
4152   }
4153 }
4154
4155 /* sets up all elements needed for streaming over the specified transport.
4156  * Does not yet expose the element pads, this will be done when there is actuall
4157  * dataflow detected, which might never happen when UDP is blocked in a
4158  * firewall, for example.
4159  */
4160 static gboolean
4161 gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream,
4162     GstRTSPTransport * transport)
4163 {
4164   GstRTSPSrc *src;
4165   GstPad *outpad = NULL;
4166   GstPadTemplate *template;
4167   gchar *name;
4168   const gchar *media_type;
4169   guint i, len;
4170
4171   src = stream->parent;
4172
4173   GST_DEBUG_OBJECT (src, "configuring transport for stream %p", stream);
4174
4175   /* get the proper media type for this stream now */
4176   if (gst_rtsp_transport_get_media_type (transport, &media_type) < 0)
4177     goto unknown_transport;
4178   if (!media_type)
4179     goto unknown_transport;
4180
4181   /* configure the final media type */
4182   GST_DEBUG_OBJECT (src, "setting media type to %s", media_type);
4183
4184   len = stream->ptmap->len;
4185   for (i = 0; i < len; i++) {
4186     GstStructure *s;
4187     PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);
4188
4189     if (item->caps == NULL)
4190       continue;
4191
4192     s = gst_caps_get_structure (item->caps, 0);
4193     gst_structure_set_name (s, media_type);
4194     /* set ssrc if known */
4195     if (transport->ssrc)
4196       gst_structure_set (s, "ssrc", G_TYPE_UINT, transport->ssrc, NULL);
4197   }
4198
4199   /* try to get and configure a manager, channelpad[0-1] will be configured with
4200    * the pads for the manager, or NULL when no manager is needed. */
4201   if (!gst_rtspsrc_stream_configure_manager (src, stream, transport))
4202     goto no_manager;
4203
4204   switch (transport->lower_transport) {
4205     case GST_RTSP_LOWER_TRANS_TCP:
4206       if (!gst_rtspsrc_stream_configure_tcp (src, stream, transport, &outpad))
4207         goto transport_failed;
4208       break;
4209     case GST_RTSP_LOWER_TRANS_UDP_MCAST:
4210       if (!gst_rtspsrc_stream_configure_mcast (src, stream, transport, &outpad))
4211         goto transport_failed;
4212       /* fallthrough, the rest is the same for UDP and MCAST */
4213     case GST_RTSP_LOWER_TRANS_UDP:
4214       if (!gst_rtspsrc_stream_configure_udp (src, stream, transport, &outpad))
4215         goto transport_failed;
4216       /* configure udpsinks back to the server for RTCP messages and for the
4217        * dummy RTP messages to open NAT. */
4218       if (!gst_rtspsrc_stream_configure_udp_sinks (src, stream, transport))
4219         goto transport_failed;
4220       break;
4221     default:
4222       goto unknown_transport;
4223   }
4224
4225   if (outpad) {
4226     GST_DEBUG_OBJECT (src, "creating ghostpad");
4227
4228     gst_pad_use_fixed_caps (outpad);
4229
4230     /* create ghostpad, don't add just yet, this will be done when we activate
4231      * the stream. */
4232     name = g_strdup_printf ("stream_%u", stream->id);
4233     template = gst_static_pad_template_get (&rtptemplate);
4234     stream->srcpad = gst_ghost_pad_new_from_template (name, outpad, template);
4235     gst_pad_set_event_function (stream->srcpad, gst_rtspsrc_handle_src_event);
4236     gst_pad_set_query_function (stream->srcpad, gst_rtspsrc_handle_src_query);
4237     gst_object_unref (template);
4238     g_free (name);
4239
4240     gst_object_unref (outpad);
4241   }
4242   /* mark pad as ok */
4243   stream->last_ret = GST_FLOW_OK;
4244
4245   return TRUE;
4246
4247   /* ERRORS */
4248 transport_failed:
4249   {
4250     GST_DEBUG_OBJECT (src, "failed to configure transport");
4251     return FALSE;
4252   }
4253 unknown_transport:
4254   {
4255     GST_DEBUG_OBJECT (src, "unknown transport");
4256     return FALSE;
4257   }
4258 no_manager:
4259   {
4260     GST_DEBUG_OBJECT (src, "cannot get a session manager");
4261     return FALSE;
4262   }
4263 }
4264
4265 /* send a couple of dummy random packets on the receiver RTP port to the server,
4266  * this should make a firewall think we initiated the data transfer and
4267  * hopefully allow packets to go from the sender port to our RTP receiver port */
4268 static gboolean
4269 gst_rtspsrc_send_dummy_packets (GstRTSPSrc * src)
4270 {
4271   GList *walk;
4272
4273   if (src->nat_method != GST_RTSP_NAT_DUMMY)
4274     return TRUE;
4275
4276   for (walk = src->streams; walk; walk = g_list_next (walk)) {
4277     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
4278
4279     if (stream->fakesrc && stream->udpsink[0]) {
4280       GST_DEBUG_OBJECT (src, "sending dummy packet to stream %p", stream);
4281       gst_element_set_state (stream->udpsink[0], GST_STATE_NULL);
4282       gst_element_set_state (stream->fakesrc, GST_STATE_NULL);
4283       gst_element_set_state (stream->udpsink[0], GST_STATE_PLAYING);
4284       gst_element_set_state (stream->fakesrc, GST_STATE_PLAYING);
4285     }
4286   }
4287   return TRUE;
4288 }
4289
4290 /* Adds the source pads of all configured streams to the element.
4291  * This code is performed when we detected dataflow.
4292  *
4293  * We detect dataflow from either the _loop function or with pad probes on the
4294  * udp sources.
4295  */
4296 static gboolean
4297 gst_rtspsrc_activate_streams (GstRTSPSrc * src)
4298 {
4299   GList *walk;
4300
4301   GST_DEBUG_OBJECT (src, "activating streams");
4302
4303   for (walk = src->streams; walk; walk = g_list_next (walk)) {
4304     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
4305
4306     if (stream->udpsrc[0]) {
4307       /* remove timeout, we are streaming now and timeouts will be handled by
4308        * the session manager and jitter buffer */
4309       g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout", (guint64) 0, NULL);
4310     }
4311     if (stream->srcpad) {
4312       GST_DEBUG_OBJECT (src, "activating stream pad %p", stream);
4313       gst_pad_set_active (stream->srcpad, TRUE);
4314
4315       /* if we don't have a session manager, set the caps now. If we have a
4316        * session, we will get a notification of the pad and the caps. */
4317       if (!src->manager) {
4318         GstCaps *caps;
4319
4320         caps = stream_get_caps_for_pt (stream, stream->default_pt);
4321         GST_DEBUG_OBJECT (src, "setting pad caps for stream %p", stream);
4322         gst_pad_set_caps (stream->srcpad, caps);
4323       }
4324       /* add the pad */
4325       if (!stream->added) {
4326         GST_DEBUG_OBJECT (src, "adding stream pad %p", stream);
4327         gst_element_add_pad (GST_ELEMENT_CAST (src), stream->srcpad);
4328         stream->added = TRUE;
4329       }
4330     }
4331   }
4332
4333   /* unblock all pads */
4334   for (walk = src->streams; walk; walk = g_list_next (walk)) {
4335     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
4336
4337     if (stream->blockid) {
4338       GST_DEBUG_OBJECT (src, "unblocking stream pad %p", stream);
4339       gst_pad_remove_probe (stream->blockedpad, stream->blockid);
4340       stream->blockid = 0;
4341     }
4342   }
4343
4344   return TRUE;
4345 }
4346
4347 static void
4348 gst_rtspsrc_configure_caps (GstRTSPSrc * src, GstSegment * segment,
4349     gboolean reset_manager)
4350 {
4351   GList *walk;
4352   guint64 start, stop;
4353   gdouble play_speed, play_scale;
4354
4355   GST_DEBUG_OBJECT (src, "configuring stream caps");
4356
4357   start = segment->position;
4358   stop = segment->duration;
4359   play_speed = segment->rate;
4360   play_scale = segment->applied_rate;
4361
4362   for (walk = src->streams; walk; walk = g_list_next (walk)) {
4363     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
4364     guint j, len;
4365
4366     if (!stream->setup)
4367       continue;
4368
4369     len = stream->ptmap->len;
4370     for (j = 0; j < len; j++) {
4371       GstCaps *caps;
4372       PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, j);
4373
4374       if (item->caps == NULL)
4375         continue;
4376
4377       caps = gst_caps_make_writable (item->caps);
4378       /* update caps */
4379       if (stream->timebase != -1)
4380         gst_caps_set_simple (caps, "clock-base", G_TYPE_UINT,
4381             (guint) stream->timebase, NULL);
4382       if (stream->seqbase != -1)
4383         gst_caps_set_simple (caps, "seqnum-base", G_TYPE_UINT,
4384             (guint) stream->seqbase, NULL);
4385       gst_caps_set_simple (caps, "npt-start", G_TYPE_UINT64, start, NULL);
4386       if (stop != -1)
4387         gst_caps_set_simple (caps, "npt-stop", G_TYPE_UINT64, stop, NULL);
4388       gst_caps_set_simple (caps, "play-speed", G_TYPE_DOUBLE, play_speed, NULL);
4389       gst_caps_set_simple (caps, "play-scale", G_TYPE_DOUBLE, play_scale, NULL);
4390
4391       item->caps = caps;
4392       GST_DEBUG_OBJECT (src, "stream %p, pt %d, caps %" GST_PTR_FORMAT, stream,
4393           item->pt, caps);
4394
4395       if (item->pt == stream->default_pt && stream->udpsrc[0]) {
4396         g_object_set (stream->udpsrc[0], "caps", caps, NULL);
4397       }
4398     }
4399   }
4400   if (reset_manager && src->manager) {
4401     GST_DEBUG_OBJECT (src, "clear session");
4402     g_signal_emit_by_name (src->manager, "clear-pt-map", NULL);
4403   }
4404 }
4405
4406 static GstFlowReturn
4407 gst_rtspsrc_combine_flows (GstRTSPSrc * src, GstRTSPStream * stream,
4408     GstFlowReturn ret)
4409 {
4410   GList *streams;
4411
4412   /* store the value */
4413   stream->last_ret = ret;
4414
4415   /* if it's success we can return the value right away */
4416   if (ret == GST_FLOW_OK)
4417     goto done;
4418
4419   /* any other error that is not-linked can be returned right
4420    * away */
4421   if (ret != GST_FLOW_NOT_LINKED)
4422     goto done;
4423
4424   /* only return NOT_LINKED if all other pads returned NOT_LINKED */
4425   for (streams = src->streams; streams; streams = g_list_next (streams)) {
4426     GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
4427
4428     ret = ostream->last_ret;
4429     /* some other return value (must be SUCCESS but we can return
4430      * other values as well) */
4431     if (ret != GST_FLOW_NOT_LINKED)
4432       goto done;
4433   }
4434   /* if we get here, all other pads were unlinked and we return
4435    * NOT_LINKED then */
4436 done:
4437   return ret;
4438 }
4439
4440 static gboolean
4441 gst_rtspsrc_stream_push_event (GstRTSPSrc * src, GstRTSPStream * stream,
4442     GstEvent * event)
4443 {
4444   gboolean res = TRUE;
4445
4446   /* only streams that have a connection to the outside world */
4447   if (!stream->setup)
4448     goto done;
4449
4450   if (stream->udpsrc[0]) {
4451     gst_event_ref (event);
4452     res = gst_element_send_event (stream->udpsrc[0], event);
4453   } else if (stream->channelpad[0]) {
4454     gst_event_ref (event);
4455     if (GST_PAD_IS_SRC (stream->channelpad[0]))
4456       res = gst_pad_push_event (stream->channelpad[0], event);
4457     else
4458       res = gst_pad_send_event (stream->channelpad[0], event);
4459   }
4460
4461   if (stream->udpsrc[1]) {
4462     gst_event_ref (event);
4463     res &= gst_element_send_event (stream->udpsrc[1], event);
4464   } else if (stream->channelpad[1]) {
4465     gst_event_ref (event);
4466     if (GST_PAD_IS_SRC (stream->channelpad[1]))
4467       res &= gst_pad_push_event (stream->channelpad[1], event);
4468     else
4469       res &= gst_pad_send_event (stream->channelpad[1], event);
4470   }
4471
4472 done:
4473   gst_event_unref (event);
4474
4475   return res;
4476 }
4477
4478 static gboolean
4479 gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event)
4480 {
4481   GList *streams;
4482   gboolean res = TRUE;
4483
4484   for (streams = src->streams; streams; streams = g_list_next (streams)) {
4485     GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
4486
4487     gst_event_ref (event);
4488     res &= gst_rtspsrc_stream_push_event (src, ostream, event);
4489   }
4490   gst_event_unref (event);
4491
4492   return res;
4493 }
4494
4495 static GstRTSPResult
4496 gst_rtsp_conninfo_connect (GstRTSPSrc * src, GstRTSPConnInfo * info,
4497     gboolean async)
4498 {
4499   GstRTSPResult res;
4500
4501   if (info->connection == NULL) {
4502     if (info->url == NULL) {
4503       GST_DEBUG_OBJECT (src, "parsing uri (%s)...", info->location);
4504       if ((res = gst_rtsp_url_parse (info->location, &info->url)) < 0)
4505         goto parse_error;
4506     }
4507
4508     /* create connection */
4509     GST_DEBUG_OBJECT (src, "creating connection (%s)...", info->location);
4510     if ((res = gst_rtsp_connection_create (info->url, &info->connection)) < 0)
4511       goto could_not_create;
4512
4513     if (info->url_str)
4514       g_free (info->url_str);
4515     info->url_str = gst_rtsp_url_get_request_uri (info->url);
4516
4517     GST_DEBUG_OBJECT (src, "sanitized uri %s", info->url_str);
4518
4519     if (info->url->transports & GST_RTSP_LOWER_TRANS_TLS) {
4520       if (!gst_rtsp_connection_set_tls_validation_flags (info->connection,
4521               src->tls_validation_flags))
4522         GST_WARNING_OBJECT (src, "Unable to set TLS validation flags");
4523
4524       if (src->tls_database)
4525         gst_rtsp_connection_set_tls_database (info->connection,
4526             src->tls_database);
4527
4528       if (src->tls_interaction)
4529         gst_rtsp_connection_set_tls_interaction (info->connection,
4530             src->tls_interaction);
4531     }
4532
4533     if (info->url->transports & GST_RTSP_LOWER_TRANS_HTTP)
4534       gst_rtsp_connection_set_tunneled (info->connection, TRUE);
4535
4536     if (src->proxy_host) {
4537       GST_DEBUG_OBJECT (src, "setting proxy %s:%d", src->proxy_host,
4538           src->proxy_port);
4539       gst_rtsp_connection_set_proxy (info->connection, src->proxy_host,
4540           src->proxy_port);
4541     }
4542   }
4543
4544   if (!info->connected) {
4545     /* connect */
4546     if (async)
4547       GST_ELEMENT_PROGRESS (src, CONTINUE, "connect",
4548           ("Connecting to %s", info->location));
4549     GST_DEBUG_OBJECT (src, "connecting (%s)...", info->location);
4550     if ((res =
4551             gst_rtsp_connection_connect (info->connection,
4552                 src->ptcp_timeout)) < 0)
4553       goto could_not_connect;
4554
4555     info->connected = TRUE;
4556   }
4557   return GST_RTSP_OK;
4558
4559   /* ERRORS */
4560 parse_error:
4561   {
4562     GST_ERROR_OBJECT (src, "No valid RTSP URL was provided");
4563     return res;
4564   }
4565 could_not_create:
4566   {
4567     gchar *str = gst_rtsp_strresult (res);
4568     GST_ERROR_OBJECT (src, "Could not create connection. (%s)", str);
4569     g_free (str);
4570     return res;
4571   }
4572 could_not_connect:
4573   {
4574     gchar *str = gst_rtsp_strresult (res);
4575     GST_ERROR_OBJECT (src, "Could not connect to server. (%s)", str);
4576     g_free (str);
4577     return res;
4578   }
4579 }
4580
4581 static GstRTSPResult
4582 gst_rtsp_conninfo_close (GstRTSPSrc * src, GstRTSPConnInfo * info,
4583     gboolean free)
4584 {
4585   GST_RTSP_STATE_LOCK (src);
4586   if (info->connected) {
4587     GST_DEBUG_OBJECT (src, "closing connection...");
4588     gst_rtsp_connection_close (info->connection);
4589     info->connected = FALSE;
4590   }
4591   if (free && info->connection) {
4592     /* free connection */
4593     GST_DEBUG_OBJECT (src, "freeing connection...");
4594     gst_rtsp_connection_free (info->connection);
4595     info->connection = NULL;
4596   }
4597   GST_RTSP_STATE_UNLOCK (src);
4598   return GST_RTSP_OK;
4599 }
4600
4601 static GstRTSPResult
4602 gst_rtsp_conninfo_reconnect (GstRTSPSrc * src, GstRTSPConnInfo * info,
4603     gboolean async)
4604 {
4605   GstRTSPResult res;
4606
4607   GST_DEBUG_OBJECT (src, "reconnecting connection...");
4608   gst_rtsp_conninfo_close (src, info, FALSE);
4609   res = gst_rtsp_conninfo_connect (src, info, async);
4610
4611   return res;
4612 }
4613
4614 static void
4615 gst_rtspsrc_connection_flush (GstRTSPSrc * src, gboolean flush)
4616 {
4617   GList *walk;
4618
4619   GST_DEBUG_OBJECT (src, "set flushing %d", flush);
4620   GST_RTSP_STATE_LOCK (src);
4621   if (src->conninfo.connection && src->conninfo.flushing != flush) {
4622     GST_DEBUG_OBJECT (src, "connection flush");
4623     gst_rtsp_connection_flush (src->conninfo.connection, flush);
4624     src->conninfo.flushing = flush;
4625   }
4626   for (walk = src->streams; walk; walk = g_list_next (walk)) {
4627     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
4628     if (stream->conninfo.connection && stream->conninfo.flushing != flush) {
4629       GST_DEBUG_OBJECT (src, "stream %p flush", stream);
4630       gst_rtsp_connection_flush (stream->conninfo.connection, flush);
4631       stream->conninfo.flushing = flush;
4632     }
4633   }
4634   GST_RTSP_STATE_UNLOCK (src);
4635 }
4636
4637 static GstRTSPResult
4638 gst_rtspsrc_init_request (GstRTSPSrc * src, GstRTSPMessage * msg,
4639     GstRTSPMethod method, const gchar * uri)
4640 {
4641   GstRTSPResult res;
4642
4643   res = gst_rtsp_message_init_request (msg, method, uri);
4644   if (res < 0)
4645     return res;
4646
4647   /* set user-agent */
4648   if (src->user_agent)
4649     gst_rtsp_message_add_header (msg, GST_RTSP_HDR_USER_AGENT, src->user_agent);
4650
4651   return res;
4652 }
4653
4654 /* FIXME, handle server request, reply with OK, for now */
4655 static GstRTSPResult
4656 gst_rtspsrc_handle_request (GstRTSPSrc * src, GstRTSPConnection * conn,
4657     GstRTSPMessage * request)
4658 {
4659   GstRTSPMessage response = { 0 };
4660   GstRTSPResult res;
4661
4662   GST_DEBUG_OBJECT (src, "got server request message");
4663
4664   if (src->debug)
4665     gst_rtsp_message_dump (request);
4666
4667   res = gst_rtsp_ext_list_receive_request (src->extensions, request);
4668
4669   if (res == GST_RTSP_ENOTIMPL) {
4670     /* default implementation, send OK */
4671     GST_DEBUG_OBJECT (src, "prepare OK reply");
4672     res =
4673         gst_rtsp_message_init_response (&response, GST_RTSP_STS_OK, "OK",
4674         request);
4675     if (res < 0)
4676       goto send_error;
4677
4678     /* let app parse and reply */
4679     g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_HANDLE_REQUEST],
4680         0, request, &response);
4681
4682     if (src->debug)
4683       gst_rtsp_message_dump (&response);
4684
4685     res = gst_rtspsrc_connection_send (src, conn, &response, NULL);
4686     if (res < 0)
4687       goto send_error;
4688
4689     gst_rtsp_message_unset (&response);
4690   } else if (res == GST_RTSP_EEOF)
4691     return res;
4692
4693   return GST_RTSP_OK;
4694
4695   /* ERRORS */
4696 send_error:
4697   {
4698     gst_rtsp_message_unset (&response);
4699     return res;
4700   }
4701 }
4702
4703 /* send server keep-alive */
4704 static GstRTSPResult
4705 gst_rtspsrc_send_keep_alive (GstRTSPSrc * src)
4706 {
4707   GstRTSPMessage request = { 0 };
4708   GstRTSPResult res;
4709   GstRTSPMethod method;
4710   const gchar *control;
4711
4712   if (src->do_rtsp_keep_alive == FALSE) {
4713     GST_DEBUG_OBJECT (src, "do-rtsp-keep-alive is FALSE, not sending.");
4714     gst_rtsp_connection_reset_timeout (src->conninfo.connection);
4715     return GST_RTSP_OK;
4716   }
4717
4718   GST_DEBUG_OBJECT (src, "creating server keep-alive");
4719
4720   /* find a method to use for keep-alive */
4721   if (src->methods & GST_RTSP_GET_PARAMETER)
4722     method = GST_RTSP_GET_PARAMETER;
4723   else
4724     method = GST_RTSP_OPTIONS;
4725
4726   control = get_aggregate_control (src);
4727   if (control == NULL)
4728     goto no_control;
4729
4730   res = gst_rtspsrc_init_request (src, &request, method, control);
4731   if (res < 0)
4732     goto send_error;
4733
4734   if (src->debug)
4735     gst_rtsp_message_dump (&request);
4736
4737   res =
4738       gst_rtspsrc_connection_send (src, src->conninfo.connection, &request,
4739       NULL);
4740   if (res < 0)
4741     goto send_error;
4742
4743   gst_rtsp_connection_reset_timeout (src->conninfo.connection);
4744   gst_rtsp_message_unset (&request);
4745
4746   return GST_RTSP_OK;
4747
4748   /* ERRORS */
4749 no_control:
4750   {
4751     GST_WARNING_OBJECT (src, "no control url to send keepalive");
4752     return GST_RTSP_OK;
4753   }
4754 send_error:
4755   {
4756     gchar *str = gst_rtsp_strresult (res);
4757
4758     gst_rtsp_message_unset (&request);
4759     GST_ELEMENT_WARNING (src, RESOURCE, WRITE, (NULL),
4760         ("Could not send keep-alive. (%s)", str));
4761     g_free (str);
4762     return res;
4763   }
4764 }
4765
4766 static GstFlowReturn
4767 gst_rtspsrc_handle_data (GstRTSPSrc * src, GstRTSPMessage * message)
4768 {
4769   GstFlowReturn ret = GST_FLOW_OK;
4770   gint channel;
4771   GstRTSPStream *stream;
4772   GstPad *outpad = NULL;
4773   guint8 *data;
4774   guint size;
4775   GstBuffer *buf;
4776   gboolean is_rtcp;
4777
4778   channel = message->type_data.data.channel;
4779
4780   stream = find_stream (src, &channel, (gpointer) find_stream_by_channel);
4781   if (!stream)
4782     goto unknown_stream;
4783
4784   if (channel == stream->channel[0]) {
4785     outpad = stream->channelpad[0];
4786     is_rtcp = FALSE;
4787   } else if (channel == stream->channel[1]) {
4788     outpad = stream->channelpad[1];
4789     is_rtcp = TRUE;
4790   } else {
4791     is_rtcp = FALSE;
4792   }
4793
4794   /* take a look at the body to figure out what we have */
4795   gst_rtsp_message_get_body (message, &data, &size);
4796   if (size < 2)
4797     goto invalid_length;
4798
4799   /* channels are not correct on some servers, do extra check */
4800   if (data[1] >= 200 && data[1] <= 204) {
4801     /* hmm RTCP message switch to the RTCP pad of the same stream. */
4802     outpad = stream->channelpad[1];
4803     is_rtcp = TRUE;
4804   }
4805
4806   /* we have no clue what this is, just ignore then. */
4807   if (outpad == NULL)
4808     goto unknown_stream;
4809
4810   /* take the message body for further processing */
4811   gst_rtsp_message_steal_body (message, &data, &size);
4812
4813   /* strip the trailing \0 */
4814   size -= 1;
4815
4816   buf = gst_buffer_new ();
4817   gst_buffer_append_memory (buf,
4818       gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
4819
4820   /* don't need message anymore */
4821   gst_rtsp_message_unset (message);
4822
4823   GST_DEBUG_OBJECT (src, "pushing data of size %d on channel %d", size,
4824       channel);
4825
4826   if (src->need_activate) {
4827     gchar *stream_id;
4828     GstEvent *event;
4829     GChecksum *cs;
4830     gchar *uri;
4831     GList *streams;
4832     guint group_id = gst_util_group_id_next ();
4833
4834     /* generate an SHA256 sum of the URI */
4835     cs = g_checksum_new (G_CHECKSUM_SHA256);
4836     uri = src->conninfo.location;
4837     g_checksum_update (cs, (const guchar *) uri, strlen (uri));
4838
4839     for (streams = src->streams; streams; streams = g_list_next (streams)) {
4840       GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
4841       GstCaps *caps;
4842
4843       stream_id =
4844           g_strdup_printf ("%s/%d", g_checksum_get_string (cs), ostream->id);
4845       event = gst_event_new_stream_start (stream_id);
4846       gst_event_set_group_id (event, group_id);
4847
4848       g_free (stream_id);
4849       gst_rtspsrc_stream_push_event (src, ostream, event);
4850
4851       if ((caps = stream_get_caps_for_pt (ostream, ostream->default_pt))) {
4852         /* only streams that have a connection to the outside world */
4853         if (ostream->setup) {
4854           if (ostream->udpsrc[0]) {
4855             gst_element_send_event (ostream->udpsrc[0],
4856                 gst_event_new_caps (caps));
4857           } else if (ostream->channelpad[0]) {
4858             if (GST_PAD_IS_SRC (ostream->channelpad[0]))
4859               gst_pad_push_event (ostream->channelpad[0],
4860                   gst_event_new_caps (caps));
4861             else
4862               gst_pad_send_event (ostream->channelpad[0],
4863                   gst_event_new_caps (caps));
4864           }
4865
4866           caps = gst_caps_new_empty_simple ("application/x-rtcp");
4867
4868           if (ostream->udpsrc[1]) {
4869             gst_element_send_event (ostream->udpsrc[1],
4870                 gst_event_new_caps (caps));
4871           } else if (ostream->channelpad[1]) {
4872             if (GST_PAD_IS_SRC (ostream->channelpad[1]))
4873               gst_pad_push_event (ostream->channelpad[1],
4874                   gst_event_new_caps (caps));
4875             else
4876               gst_pad_send_event (ostream->channelpad[1],
4877                   gst_event_new_caps (caps));
4878           }
4879
4880           gst_caps_unref (caps);
4881         }
4882       }
4883     }
4884     g_checksum_free (cs);
4885
4886     gst_rtspsrc_activate_streams (src);
4887     src->need_activate = FALSE;
4888     src->need_segment = TRUE;
4889   }
4890
4891   if (src->base_time == -1) {
4892     /* Take current running_time. This timestamp will be put on
4893      * the first buffer of each stream because we are a live source and so we
4894      * timestamp with the running_time. When we are dealing with TCP, we also
4895      * only timestamp the first buffer (using the DISCONT flag) because a server
4896      * typically bursts data, for which we don't want to compensate by speeding
4897      * up the media. The other timestamps will be interpollated from this one
4898      * using the RTP timestamps. */
4899     GST_OBJECT_LOCK (src);
4900     if (GST_ELEMENT_CLOCK (src)) {
4901       GstClockTime now;
4902       GstClockTime base_time;
4903
4904       now = gst_clock_get_time (GST_ELEMENT_CLOCK (src));
4905       base_time = GST_ELEMENT_CAST (src)->base_time;
4906
4907       src->base_time = now - base_time;
4908
4909       GST_DEBUG_OBJECT (src, "first buffer at time %" GST_TIME_FORMAT ", base %"
4910           GST_TIME_FORMAT, GST_TIME_ARGS (now), GST_TIME_ARGS (base_time));
4911     }
4912     GST_OBJECT_UNLOCK (src);
4913   }
4914
4915   /* If needed send a new segment, don't forget we are live and buffer are
4916    * timestamped with running time */
4917   if (src->need_segment) {
4918     GstSegment segment;
4919     src->need_segment = FALSE;
4920     gst_segment_init (&segment, GST_FORMAT_TIME);
4921     gst_rtspsrc_push_event (src, gst_event_new_segment (&segment));
4922   }
4923
4924   if (stream->discont && !is_rtcp) {
4925     /* mark first RTP buffer as discont */
4926     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
4927     stream->discont = FALSE;
4928     /* first buffer gets the timestamp, other buffers are not timestamped and
4929      * their presentation time will be interpollated from the rtp timestamps. */
4930     GST_DEBUG_OBJECT (src, "setting timestamp %" GST_TIME_FORMAT,
4931         GST_TIME_ARGS (src->base_time));
4932
4933     GST_BUFFER_TIMESTAMP (buf) = src->base_time;
4934   }
4935
4936   /* chain to the peer pad */
4937   if (GST_PAD_IS_SINK (outpad))
4938     ret = gst_pad_chain (outpad, buf);
4939   else
4940     ret = gst_pad_push (outpad, buf);
4941
4942   if (!is_rtcp) {
4943     /* combine all stream flows for the data transport */
4944     ret = gst_rtspsrc_combine_flows (src, stream, ret);
4945   }
4946   return ret;
4947
4948   /* ERRORS */
4949 unknown_stream:
4950   {
4951     GST_DEBUG_OBJECT (src, "unknown stream on channel %d, ignored", channel);
4952     gst_rtsp_message_unset (message);
4953     return GST_FLOW_OK;
4954   }
4955 invalid_length:
4956   {
4957     GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
4958         ("Short message received, ignoring."));
4959     gst_rtsp_message_unset (message);
4960     return GST_FLOW_OK;
4961   }
4962 }
4963
4964 static GstFlowReturn
4965 gst_rtspsrc_loop_interleaved (GstRTSPSrc * src)
4966 {
4967   GstRTSPMessage message = { 0 };
4968   GstRTSPResult res;
4969   GstFlowReturn ret = GST_FLOW_OK;
4970   GTimeVal tv_timeout;
4971
4972   while (TRUE) {
4973     /* get the next timeout interval */
4974     gst_rtsp_connection_next_timeout (src->conninfo.connection, &tv_timeout);
4975
4976     /* see if the timeout period expired */
4977     if ((tv_timeout.tv_sec | tv_timeout.tv_usec) == 0) {
4978       GST_DEBUG_OBJECT (src, "timout, sending keep-alive");
4979       /* send keep-alive, only act on interrupt, a warning will be posted for
4980        * other errors. */
4981       if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
4982         goto interrupt;
4983       /* get new timeout */
4984       gst_rtsp_connection_next_timeout (src->conninfo.connection, &tv_timeout);
4985     }
4986
4987     GST_DEBUG_OBJECT (src, "doing receive with timeout %ld seconds, %ld usec",
4988         tv_timeout.tv_sec, tv_timeout.tv_usec);
4989
4990     /* protect the connection with the connection lock so that we can see when
4991      * we are finished doing server communication */
4992     res =
4993         gst_rtspsrc_connection_receive (src, src->conninfo.connection,
4994         &message, src->ptcp_timeout);
4995
4996     switch (res) {
4997       case GST_RTSP_OK:
4998         GST_DEBUG_OBJECT (src, "we received a server message");
4999         break;
5000       case GST_RTSP_EINTR:
5001         /* we got interrupted this means we need to stop */
5002         goto interrupt;
5003       case GST_RTSP_ETIMEOUT:
5004         /* no reply, send keep alive */
5005         GST_DEBUG_OBJECT (src, "timeout, sending keep-alive");
5006         if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
5007           goto interrupt;
5008         continue;
5009       case GST_RTSP_EEOF:
5010         /* go EOS when the server closed the connection */
5011         goto server_eof;
5012       default:
5013         goto receive_error;
5014     }
5015
5016     switch (message.type) {
5017       case GST_RTSP_MESSAGE_REQUEST:
5018         /* server sends us a request message, handle it */
5019         res =
5020             gst_rtspsrc_handle_request (src, src->conninfo.connection,
5021             &message);
5022         if (res == GST_RTSP_EEOF)
5023           goto server_eof;
5024         else if (res < 0)
5025           goto handle_request_failed;
5026         break;
5027       case GST_RTSP_MESSAGE_RESPONSE:
5028         /* we ignore response messages */
5029         GST_DEBUG_OBJECT (src, "ignoring response message");
5030         if (src->debug)
5031           gst_rtsp_message_dump (&message);
5032         break;
5033       case GST_RTSP_MESSAGE_DATA:
5034         GST_DEBUG_OBJECT (src, "got data message");
5035         ret = gst_rtspsrc_handle_data (src, &message);
5036         if (ret != GST_FLOW_OK)
5037           goto handle_data_failed;
5038         break;
5039       default:
5040         GST_WARNING_OBJECT (src, "ignoring unknown message type %d",
5041             message.type);
5042         break;
5043     }
5044   }
5045   g_assert_not_reached ();
5046
5047   /* ERRORS */
5048 server_eof:
5049   {
5050     GST_DEBUG_OBJECT (src, "we got an eof from the server");
5051     GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
5052         ("The server closed the connection."));
5053     src->conninfo.connected = FALSE;
5054     gst_rtsp_message_unset (&message);
5055     return GST_FLOW_EOS;
5056   }
5057 interrupt:
5058   {
5059     gst_rtsp_message_unset (&message);
5060     GST_DEBUG_OBJECT (src, "got interrupted");
5061     return GST_FLOW_FLUSHING;
5062   }
5063 receive_error:
5064   {
5065     gchar *str = gst_rtsp_strresult (res);
5066
5067     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
5068         ("Could not receive message. (%s)", str));
5069     g_free (str);
5070
5071     gst_rtsp_message_unset (&message);
5072     return GST_FLOW_ERROR;
5073   }
5074 handle_request_failed:
5075   {
5076     gchar *str = gst_rtsp_strresult (res);
5077
5078     GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
5079         ("Could not handle server message. (%s)", str));
5080     g_free (str);
5081     gst_rtsp_message_unset (&message);
5082     return GST_FLOW_ERROR;
5083   }
5084 handle_data_failed:
5085   {
5086     GST_DEBUG_OBJECT (src, "could no handle data message");
5087     return ret;
5088   }
5089 }
5090
5091 static GstFlowReturn
5092 gst_rtspsrc_loop_udp (GstRTSPSrc * src)
5093 {
5094   GstRTSPResult res;
5095   GstRTSPMessage message = { 0 };
5096   gint retry = 0;
5097
5098   while (TRUE) {
5099     GTimeVal tv_timeout;
5100
5101     /* get the next timeout interval */
5102     gst_rtsp_connection_next_timeout (src->conninfo.connection, &tv_timeout);
5103
5104     GST_DEBUG_OBJECT (src, "doing receive with timeout %d seconds",
5105         (gint) tv_timeout.tv_sec);
5106
5107     gst_rtsp_message_unset (&message);
5108
5109     /* we should continue reading the TCP socket because the server might
5110      * send us requests. When the session timeout expires, we need to send a
5111      * keep-alive request to keep the session open. */
5112     res = gst_rtspsrc_connection_receive (src, src->conninfo.connection,
5113         &message, &tv_timeout);
5114
5115     switch (res) {
5116       case GST_RTSP_OK:
5117         GST_DEBUG_OBJECT (src, "we received a server message");
5118         break;
5119       case GST_RTSP_EINTR:
5120         /* we got interrupted, see what we have to do */
5121         goto interrupt;
5122       case GST_RTSP_ETIMEOUT:
5123         /* send keep-alive, ignore the result, a warning will be posted. */
5124         GST_DEBUG_OBJECT (src, "timeout, sending keep-alive");
5125         if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
5126           goto interrupt;
5127         continue;
5128       case GST_RTSP_EEOF:
5129         /* server closed the connection. not very fatal for UDP, reconnect and
5130          * see what happens. */
5131         GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
5132             ("The server closed the connection."));
5133         if (src->udp_reconnect) {
5134           if ((res =
5135                   gst_rtsp_conninfo_reconnect (src, &src->conninfo, FALSE)) < 0)
5136             goto connect_error;
5137         } else {
5138           goto server_eof;
5139         }
5140         continue;
5141       case GST_RTSP_ENET:
5142         GST_DEBUG_OBJECT (src, "An ethernet problem occured.");
5143       default:
5144         GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
5145             ("Unhandled return value %d.", res));
5146         goto receive_error;
5147     }
5148
5149     switch (message.type) {
5150       case GST_RTSP_MESSAGE_REQUEST:
5151         /* server sends us a request message, handle it */
5152         res =
5153             gst_rtspsrc_handle_request (src, src->conninfo.connection,
5154             &message);
5155         if (res == GST_RTSP_EEOF)
5156           goto server_eof;
5157         else if (res < 0)
5158           goto handle_request_failed;
5159         break;
5160       case GST_RTSP_MESSAGE_RESPONSE:
5161         /* we ignore response and data messages */
5162         GST_DEBUG_OBJECT (src, "ignoring response message");
5163         if (src->debug)
5164           gst_rtsp_message_dump (&message);
5165         if (message.type_data.response.code == GST_RTSP_STS_UNAUTHORIZED) {
5166           GST_DEBUG_OBJECT (src, "but is Unauthorized response ...");
5167           if (gst_rtspsrc_setup_auth (src, &message) && !(retry++)) {
5168             GST_DEBUG_OBJECT (src, "so retrying keep-alive");
5169             if ((res = gst_rtspsrc_send_keep_alive (src)) == GST_RTSP_EINTR)
5170               goto interrupt;
5171           }
5172         } else {
5173           retry = 0;
5174         }
5175         break;
5176       case GST_RTSP_MESSAGE_DATA:
5177         /* we ignore response and data messages */
5178         GST_DEBUG_OBJECT (src, "ignoring data message");
5179         break;
5180       default:
5181         GST_WARNING_OBJECT (src, "ignoring unknown message type %d",
5182             message.type);
5183         break;
5184     }
5185   }
5186   g_assert_not_reached ();
5187
5188   /* we get here when the connection got interrupted */
5189 interrupt:
5190   {
5191     gst_rtsp_message_unset (&message);
5192     GST_DEBUG_OBJECT (src, "got interrupted");
5193     return GST_FLOW_FLUSHING;
5194   }
5195 connect_error:
5196   {
5197     gchar *str = gst_rtsp_strresult (res);
5198     GstFlowReturn ret;
5199
5200     src->conninfo.connected = FALSE;
5201     if (res != GST_RTSP_EINTR) {
5202       GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
5203           ("Could not connect to server. (%s)", str));
5204       g_free (str);
5205       ret = GST_FLOW_ERROR;
5206     } else {
5207       ret = GST_FLOW_FLUSHING;
5208     }
5209     return ret;
5210   }
5211 receive_error:
5212   {
5213     gchar *str = gst_rtsp_strresult (res);
5214
5215     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
5216         ("Could not receive message. (%s)", str));
5217     g_free (str);
5218     return GST_FLOW_ERROR;
5219   }
5220 handle_request_failed:
5221   {
5222     gchar *str = gst_rtsp_strresult (res);
5223     GstFlowReturn ret;
5224
5225     gst_rtsp_message_unset (&message);
5226     if (res != GST_RTSP_EINTR) {
5227       GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
5228           ("Could not handle server message. (%s)", str));
5229       g_free (str);
5230       ret = GST_FLOW_ERROR;
5231     } else {
5232       ret = GST_FLOW_FLUSHING;
5233     }
5234     return ret;
5235   }
5236 server_eof:
5237   {
5238     GST_DEBUG_OBJECT (src, "we got an eof from the server");
5239     GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
5240         ("The server closed the connection."));
5241     src->conninfo.connected = FALSE;
5242     gst_rtsp_message_unset (&message);
5243     return GST_FLOW_EOS;
5244   }
5245 }
5246
5247 static GstRTSPResult
5248 gst_rtspsrc_reconnect (GstRTSPSrc * src, gboolean async)
5249 {
5250   GstRTSPResult res = GST_RTSP_OK;
5251   gboolean restart;
5252
5253   GST_DEBUG_OBJECT (src, "doing reconnect");
5254
5255   GST_OBJECT_LOCK (src);
5256   /* only restart when the pads were not yet activated, else we were
5257    * streaming over UDP */
5258   restart = src->need_activate;
5259   GST_OBJECT_UNLOCK (src);
5260
5261   /* no need to restart, we're done */
5262   if (!restart)
5263     goto done;
5264
5265   /* we can try only TCP now */
5266   src->cur_protocols = GST_RTSP_LOWER_TRANS_TCP;
5267
5268   /* close and cleanup our state */
5269   if ((res = gst_rtspsrc_close (src, async, FALSE)) < 0)
5270     goto done;
5271
5272   /* see if we have TCP left to try. Also don't try TCP when we were configured
5273    * with an SDP. */
5274   if (!(src->protocols & GST_RTSP_LOWER_TRANS_TCP) || src->from_sdp)
5275     goto no_protocols;
5276
5277   /* We post a warning message now to inform the user
5278    * that nothing happened. It's most likely a firewall thing. */
5279   GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
5280       ("Could not receive any UDP packets for %.4f seconds, maybe your "
5281           "firewall is blocking it. Retrying using a TCP connection.",
5282           gst_guint64_to_gdouble (src->udp_timeout / 1000000.0)));
5283
5284   /* open new connection using tcp */
5285   if (gst_rtspsrc_open (src, async) < 0)
5286     goto open_failed;
5287
5288   /* start playback */
5289   if (gst_rtspsrc_play (src, &src->segment, async) < 0)
5290     goto play_failed;
5291
5292 done:
5293   return res;
5294
5295   /* ERRORS */
5296 no_protocols:
5297   {
5298     src->cur_protocols = 0;
5299     /* no transport possible, post an error and stop */
5300     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
5301         ("Could not receive any UDP packets for %.4f seconds, maybe your "
5302             "firewall is blocking it. No other protocols to try.",
5303             gst_guint64_to_gdouble (src->udp_timeout / 1000000.0)));
5304     return GST_RTSP_ERROR;
5305   }
5306 open_failed:
5307   {
5308     GST_DEBUG_OBJECT (src, "open failed");
5309     return GST_RTSP_OK;
5310   }
5311 play_failed:
5312   {
5313     GST_DEBUG_OBJECT (src, "play failed");
5314     return GST_RTSP_OK;
5315   }
5316 }
5317
5318 static void
5319 gst_rtspsrc_loop_start_cmd (GstRTSPSrc * src, gint cmd)
5320 {
5321   switch (cmd) {
5322     case CMD_OPEN:
5323       GST_ELEMENT_PROGRESS (src, START, "open", ("Opening Stream"));
5324       break;
5325     case CMD_PLAY:
5326       GST_ELEMENT_PROGRESS (src, START, "request", ("Sending PLAY request"));
5327       break;
5328     case CMD_PAUSE:
5329       GST_ELEMENT_PROGRESS (src, START, "request", ("Sending PAUSE request"));
5330       break;
5331     case CMD_CLOSE:
5332       GST_ELEMENT_PROGRESS (src, START, "close", ("Closing Stream"));
5333       break;
5334     default:
5335       break;
5336   }
5337 }
5338
5339 static void
5340 gst_rtspsrc_loop_complete_cmd (GstRTSPSrc * src, gint cmd)
5341 {
5342   switch (cmd) {
5343     case CMD_OPEN:
5344       GST_ELEMENT_PROGRESS (src, COMPLETE, "open", ("Opened Stream"));
5345       break;
5346     case CMD_PLAY:
5347       GST_ELEMENT_PROGRESS (src, COMPLETE, "request", ("Sent PLAY request"));
5348       break;
5349     case CMD_PAUSE:
5350       GST_ELEMENT_PROGRESS (src, COMPLETE, "request", ("Sent PAUSE request"));
5351       break;
5352     case CMD_CLOSE:
5353       GST_ELEMENT_PROGRESS (src, COMPLETE, "close", ("Closed Stream"));
5354       break;
5355     default:
5356       break;
5357   }
5358 }
5359
5360 static void
5361 gst_rtspsrc_loop_cancel_cmd (GstRTSPSrc * src, gint cmd)
5362 {
5363   switch (cmd) {
5364     case CMD_OPEN:
5365       GST_ELEMENT_PROGRESS (src, CANCELED, "open", ("Open canceled"));
5366       break;
5367     case CMD_PLAY:
5368       GST_ELEMENT_PROGRESS (src, CANCELED, "request", ("PLAY canceled"));
5369       break;
5370     case CMD_PAUSE:
5371       GST_ELEMENT_PROGRESS (src, CANCELED, "request", ("PAUSE canceled"));
5372       break;
5373     case CMD_CLOSE:
5374       GST_ELEMENT_PROGRESS (src, CANCELED, "close", ("Close canceled"));
5375       break;
5376     default:
5377       break;
5378   }
5379 }
5380
5381 static void
5382 gst_rtspsrc_loop_error_cmd (GstRTSPSrc * src, gint cmd)
5383 {
5384   switch (cmd) {
5385     case CMD_OPEN:
5386       GST_ELEMENT_PROGRESS (src, ERROR, "open", ("Open failed"));
5387       break;
5388     case CMD_PLAY:
5389       GST_ELEMENT_PROGRESS (src, ERROR, "request", ("PLAY failed"));
5390       break;
5391     case CMD_PAUSE:
5392       GST_ELEMENT_PROGRESS (src, ERROR, "request", ("PAUSE failed"));
5393       break;
5394     case CMD_CLOSE:
5395       GST_ELEMENT_PROGRESS (src, ERROR, "close", ("Close failed"));
5396       break;
5397     default:
5398       break;
5399   }
5400 }
5401
5402 static void
5403 gst_rtspsrc_loop_end_cmd (GstRTSPSrc * src, gint cmd, GstRTSPResult ret)
5404 {
5405   if (ret == GST_RTSP_OK)
5406     gst_rtspsrc_loop_complete_cmd (src, cmd);
5407   else if (ret == GST_RTSP_EINTR)
5408     gst_rtspsrc_loop_cancel_cmd (src, cmd);
5409   else
5410     gst_rtspsrc_loop_error_cmd (src, cmd);
5411 }
5412
5413 static gboolean
5414 gst_rtspsrc_loop_send_cmd (GstRTSPSrc * src, gint cmd, gint mask)
5415 {
5416   gint old;
5417   gboolean flushed = FALSE;
5418
5419   /* start new request */
5420   gst_rtspsrc_loop_start_cmd (src, cmd);
5421
5422   GST_DEBUG_OBJECT (src, "sending cmd %s", cmd_to_string (cmd));
5423
5424   GST_OBJECT_LOCK (src);
5425   old = src->pending_cmd;
5426   if (old == CMD_RECONNECT) {
5427     GST_DEBUG_OBJECT (src, "ignore, we were reconnecting");
5428     cmd = CMD_RECONNECT;
5429   }
5430   if (old != CMD_WAIT) {
5431     src->pending_cmd = CMD_WAIT;
5432     GST_OBJECT_UNLOCK (src);
5433     /* cancel previous request */
5434     GST_DEBUG_OBJECT (src, "cancel previous request %s", cmd_to_string (old));
5435     gst_rtspsrc_loop_cancel_cmd (src, old);
5436     GST_OBJECT_LOCK (src);
5437   }
5438   src->pending_cmd = cmd;
5439   /* interrupt if allowed */
5440   if (src->busy_cmd & mask) {
5441     GST_DEBUG_OBJECT (src, "connection flush busy %s",
5442         cmd_to_string (src->busy_cmd));
5443     gst_rtspsrc_connection_flush (src, TRUE);
5444     flushed = TRUE;
5445   } else {
5446     GST_DEBUG_OBJECT (src, "not interrupting busy cmd %s",
5447         cmd_to_string (src->busy_cmd));
5448   }
5449   if (src->task)
5450     gst_task_start (src->task);
5451   GST_OBJECT_UNLOCK (src);
5452
5453   return flushed;
5454 }
5455
5456 static gboolean
5457 gst_rtspsrc_loop (GstRTSPSrc * src)
5458 {
5459   GstFlowReturn ret;
5460
5461   if (!src->conninfo.connection || !src->conninfo.connected)
5462     goto no_connection;
5463
5464   if (src->interleaved)
5465     ret = gst_rtspsrc_loop_interleaved (src);
5466   else
5467     ret = gst_rtspsrc_loop_udp (src);
5468
5469   if (ret != GST_FLOW_OK)
5470     goto pause;
5471
5472   return TRUE;
5473
5474   /* ERRORS */
5475 no_connection:
5476   {
5477     GST_WARNING_OBJECT (src, "we are not connected");
5478     ret = GST_FLOW_FLUSHING;
5479     goto pause;
5480   }
5481 pause:
5482   {
5483     const gchar *reason = gst_flow_get_name (ret);
5484
5485     GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
5486     src->running = FALSE;
5487     if (ret == GST_FLOW_EOS) {
5488       /* perform EOS logic */
5489       if (src->segment.flags & GST_SEEK_FLAG_SEGMENT) {
5490         gst_element_post_message (GST_ELEMENT_CAST (src),
5491             gst_message_new_segment_done (GST_OBJECT_CAST (src),
5492                 src->segment.format, src->segment.position));
5493         gst_rtspsrc_push_event (src,
5494             gst_event_new_segment_done (src->segment.format,
5495                 src->segment.position));
5496       } else {
5497         gst_rtspsrc_push_event (src, gst_event_new_eos ());
5498       }
5499     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
5500       /* for fatal errors we post an error message, post the error before the
5501        * EOS so the app knows about the error first. */
5502       GST_ELEMENT_ERROR (src, STREAM, FAILED,
5503           ("Internal data flow error."),
5504           ("streaming task paused, reason %s (%d)", reason, ret));
5505       gst_rtspsrc_push_event (src, gst_event_new_eos ());
5506     }
5507     gst_rtspsrc_loop_send_cmd (src, CMD_WAIT, CMD_LOOP);
5508     return FALSE;
5509   }
5510 }
5511
5512 #ifndef GST_DISABLE_GST_DEBUG
5513 static const gchar *
5514 gst_rtsp_auth_method_to_string (GstRTSPAuthMethod method)
5515 {
5516   gint index = 0;
5517
5518   while (method != 0) {
5519     index++;
5520     method >>= 1;
5521   }
5522   switch (index) {
5523     case 0:
5524       return "None";
5525     case 1:
5526       return "Basic";
5527     case 2:
5528       return "Digest";
5529   }
5530
5531   return "Unknown";
5532 }
5533 #endif
5534
5535 static const gchar *
5536 gst_rtspsrc_skip_lws (const gchar * s)
5537 {
5538   while (g_ascii_isspace (*s))
5539     s++;
5540   return s;
5541 }
5542
5543 static const gchar *
5544 gst_rtspsrc_unskip_lws (const gchar * s, const gchar * start)
5545 {
5546   while (s > start && g_ascii_isspace (*(s - 1)))
5547     s--;
5548   return s;
5549 }
5550
5551 static const gchar *
5552 gst_rtspsrc_skip_commas (const gchar * s)
5553 {
5554   /* The grammar allows for multiple commas */
5555   while (g_ascii_isspace (*s) || *s == ',')
5556     s++;
5557   return s;
5558 }
5559
5560 static const gchar *
5561 gst_rtspsrc_skip_item (const gchar * s)
5562 {
5563   gboolean quoted = FALSE;
5564   const gchar *start = s;
5565
5566   /* A list item ends at the last non-whitespace character
5567    * before a comma which is not inside a quoted-string. Or at
5568    * the end of the string.
5569    */
5570   while (*s) {
5571     if (*s == '"')
5572       quoted = !quoted;
5573     else if (quoted) {
5574       if (*s == '\\' && *(s + 1))
5575         s++;
5576     } else {
5577       if (*s == ',')
5578         break;
5579     }
5580     s++;
5581   }
5582
5583   return gst_rtspsrc_unskip_lws (s, start);
5584 }
5585
5586 static void
5587 gst_rtsp_decode_quoted_string (gchar * quoted_string)
5588 {
5589   gchar *src, *dst;
5590
5591   src = quoted_string + 1;
5592   dst = quoted_string;
5593   while (*src && *src != '"') {
5594     if (*src == '\\' && *(src + 1))
5595       src++;
5596     *dst++ = *src++;
5597   }
5598   *dst = '\0';
5599 }
5600
5601 /* Extract the authentication tokens that the server provided for each method
5602  * into an array of structures and give those to the connection object.
5603  */
5604 static void
5605 gst_rtspsrc_parse_digest_challenge (GstRTSPConnection * conn,
5606     const gchar * header, gboolean * stale)
5607 {
5608   GSList *list = NULL, *iter;
5609   const gchar *end;
5610   gchar *item, *eq, *name_end, *value;
5611
5612   g_return_if_fail (stale != NULL);
5613
5614   gst_rtsp_connection_clear_auth_params (conn);
5615   *stale = FALSE;
5616
5617   /* Parse a header whose content is described by RFC2616 as
5618    * "#something", where "something" does not itself contain commas,
5619    * except as part of quoted-strings, into a list of allocated strings.
5620    */
5621   header = gst_rtspsrc_skip_commas (header);
5622   while (*header) {
5623     end = gst_rtspsrc_skip_item (header);
5624     list = g_slist_prepend (list, g_strndup (header, end - header));
5625     header = gst_rtspsrc_skip_commas (end);
5626   }
5627   if (!list)
5628     return;
5629
5630   list = g_slist_reverse (list);
5631   for (iter = list; iter; iter = iter->next) {
5632     item = iter->data;
5633
5634     eq = strchr (item, '=');
5635     if (eq) {
5636       name_end = (gchar *) gst_rtspsrc_unskip_lws (eq, item);
5637       if (name_end == item) {
5638         /* That's no good... */
5639         g_free (item);
5640         continue;
5641       }
5642
5643       *name_end = '\0';
5644
5645       value = (gchar *) gst_rtspsrc_skip_lws (eq + 1);
5646       if (*value == '"')
5647         gst_rtsp_decode_quoted_string (value);
5648     } else
5649       value = NULL;
5650
5651     if (value && strcmp (item, "stale") == 0 && strcmp (value, "TRUE") == 0)
5652       *stale = TRUE;
5653     gst_rtsp_connection_set_auth_param (conn, item, value);
5654     g_free (item);
5655   }
5656
5657   g_slist_free (list);
5658 }
5659
5660 /* Parse a WWW-Authenticate Response header and determine the
5661  * available authentication methods
5662  *
5663  * This code should also cope with the fact that each WWW-Authenticate
5664  * header can contain multiple challenge methods + tokens
5665  *
5666  * At the moment, for Basic auth, we just do a minimal check and don't
5667  * even parse out the realm */
5668 static void
5669 gst_rtspsrc_parse_auth_hdr (gchar * hdr, GstRTSPAuthMethod * methods,
5670     GstRTSPConnection * conn, gboolean * stale)
5671 {
5672   gchar *start;
5673
5674   g_return_if_fail (hdr != NULL);
5675   g_return_if_fail (methods != NULL);
5676   g_return_if_fail (stale != NULL);
5677
5678   /* Skip whitespace at the start of the string */
5679   for (start = hdr; start[0] != '\0' && g_ascii_isspace (start[0]); start++);
5680
5681   if (g_ascii_strncasecmp (start, "basic", 5) == 0)
5682     *methods |= GST_RTSP_AUTH_BASIC;
5683   else if (g_ascii_strncasecmp (start, "digest ", 7) == 0) {
5684     *methods |= GST_RTSP_AUTH_DIGEST;
5685     gst_rtspsrc_parse_digest_challenge (conn, &start[7], stale);
5686   }
5687 }
5688
5689 /**
5690  * gst_rtspsrc_setup_auth:
5691  * @src: the rtsp source
5692  *
5693  * Configure a username and password and auth method on the
5694  * connection object based on a response we received from the
5695  * peer.
5696  *
5697  * Currently, this requires that a username and password were supplied
5698  * in the uri. In the future, they may be requested on demand by sending
5699  * a message up the bus.
5700  *
5701  * Returns: TRUE if authentication information could be set up correctly.
5702  */
5703 static gboolean
5704 gst_rtspsrc_setup_auth (GstRTSPSrc * src, GstRTSPMessage * response)
5705 {
5706   gchar *user = NULL;
5707   gchar *pass = NULL;
5708   GstRTSPAuthMethod avail_methods = GST_RTSP_AUTH_NONE;
5709   GstRTSPAuthMethod method;
5710   GstRTSPResult auth_result;
5711   GstRTSPUrl *url;
5712   GstRTSPConnection *conn;
5713   gchar *hdr;
5714   gboolean stale = FALSE;
5715
5716   conn = src->conninfo.connection;
5717
5718   /* Identify the available auth methods and see if any are supported */
5719   if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_WWW_AUTHENTICATE,
5720           &hdr, 0) == GST_RTSP_OK) {
5721     gst_rtspsrc_parse_auth_hdr (hdr, &avail_methods, conn, &stale);
5722   }
5723
5724   if (avail_methods == GST_RTSP_AUTH_NONE)
5725     goto no_auth_available;
5726
5727   /* For digest auth, if the response indicates that the session
5728    * data are stale, we just update them in the connection object and
5729    * return TRUE to retry the request */
5730   if (stale)
5731     src->tried_url_auth = FALSE;
5732
5733   url = gst_rtsp_connection_get_url (conn);
5734
5735   /* Do we have username and password available? */
5736   if (url != NULL && !src->tried_url_auth && url->user != NULL
5737       && url->passwd != NULL) {
5738     user = url->user;
5739     pass = url->passwd;
5740     src->tried_url_auth = TRUE;
5741     GST_DEBUG_OBJECT (src,
5742         "Attempting authentication using credentials from the URL");
5743   } else {
5744     user = src->user_id;
5745     pass = src->user_pw;
5746     GST_DEBUG_OBJECT (src,
5747         "Attempting authentication using credentials from the properties");
5748   }
5749
5750   /* FIXME: If the url didn't contain username and password or we tried them
5751    * already, request a username and passwd from the application via some kind
5752    * of credentials request message */
5753
5754   /* If we don't have a username and passwd at this point, bail out. */
5755   if (user == NULL || pass == NULL)
5756     goto no_user_pass;
5757
5758   /* Try to configure for each available authentication method, strongest to
5759    * weakest */
5760   for (method = GST_RTSP_AUTH_MAX; method != GST_RTSP_AUTH_NONE; method >>= 1) {
5761     /* Check if this method is available on the server */
5762     if ((method & avail_methods) == 0)
5763       continue;
5764
5765     /* Pass the credentials to the connection to try on the next request */
5766     auth_result = gst_rtsp_connection_set_auth (conn, method, user, pass);
5767     /* INVAL indicates an invalid username/passwd were supplied, so we'll just
5768      * ignore it and end up retrying later */
5769     if (auth_result == GST_RTSP_OK || auth_result == GST_RTSP_EINVAL) {
5770       GST_DEBUG_OBJECT (src, "Attempting %s authentication",
5771           gst_rtsp_auth_method_to_string (method));
5772       break;
5773     }
5774   }
5775
5776   if (method == GST_RTSP_AUTH_NONE)
5777     goto no_auth_available;
5778
5779   return TRUE;
5780
5781 no_auth_available:
5782   {
5783     /* Output an error indicating that we couldn't connect because there were
5784      * no supported authentication protocols */
5785     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
5786         ("No supported authentication protocol was found"));
5787     return FALSE;
5788   }
5789 no_user_pass:
5790   {
5791     /* We don't fire an error message, we just return FALSE and let the
5792      * normal NOT_AUTHORIZED error be propagated */
5793     return FALSE;
5794   }
5795 }
5796
5797 static GstRTSPResult
5798 gst_rtspsrc_try_send (GstRTSPSrc * src, GstRTSPConnection * conn,
5799     GstRTSPMessage * request, GstRTSPMessage * response,
5800     GstRTSPStatusCode * code)
5801 {
5802   GstRTSPResult res;
5803   GstRTSPStatusCode thecode;
5804   gchar *content_base = NULL;
5805   gint try = 0;
5806
5807 again:
5808   if (!src->short_header)
5809     gst_rtsp_ext_list_before_send (src->extensions, request);
5810
5811   GST_DEBUG_OBJECT (src, "sending message");
5812
5813   if (src->debug)
5814     gst_rtsp_message_dump (request);
5815
5816   res = gst_rtspsrc_connection_send (src, conn, request, src->ptcp_timeout);
5817   if (res < 0)
5818     goto send_error;
5819
5820   gst_rtsp_connection_reset_timeout (conn);
5821
5822 next:
5823   res = gst_rtspsrc_connection_receive (src, conn, response, src->ptcp_timeout);
5824   if (res < 0)
5825     goto receive_error;
5826
5827   if (src->debug)
5828     gst_rtsp_message_dump (response);
5829
5830   switch (response->type) {
5831     case GST_RTSP_MESSAGE_REQUEST:
5832       res = gst_rtspsrc_handle_request (src, conn, response);
5833       if (res == GST_RTSP_EEOF)
5834         goto server_eof;
5835       else if (res < 0)
5836         goto handle_request_failed;
5837       goto next;
5838     case GST_RTSP_MESSAGE_RESPONSE:
5839       /* ok, a response is good */
5840       GST_DEBUG_OBJECT (src, "received response message");
5841       break;
5842     case GST_RTSP_MESSAGE_DATA:
5843       /* get next response */
5844       GST_DEBUG_OBJECT (src, "handle data response message");
5845       gst_rtspsrc_handle_data (src, response);
5846       goto next;
5847     default:
5848       GST_WARNING_OBJECT (src, "ignoring unknown message type %d",
5849           response->type);
5850       goto next;
5851   }
5852
5853   thecode = response->type_data.response.code;
5854
5855   GST_DEBUG_OBJECT (src, "got response message %d", thecode);
5856
5857   /* if the caller wanted the result code, we store it. */
5858   if (code)
5859     *code = thecode;
5860
5861   /* If the request didn't succeed, bail out before doing any more */
5862   if (thecode != GST_RTSP_STS_OK)
5863     return GST_RTSP_OK;
5864
5865   /* store new content base if any */
5866   gst_rtsp_message_get_header (response, GST_RTSP_HDR_CONTENT_BASE,
5867       &content_base, 0);
5868   if (content_base) {
5869     g_free (src->content_base);
5870     src->content_base = g_strdup (content_base);
5871   }
5872   gst_rtsp_ext_list_after_send (src->extensions, request, response);
5873
5874   return GST_RTSP_OK;
5875
5876   /* ERRORS */
5877 send_error:
5878   {
5879     gchar *str = gst_rtsp_strresult (res);
5880
5881     if (res != GST_RTSP_EINTR) {
5882       GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
5883           ("Could not send message. (%s)", str));
5884     } else {
5885       GST_WARNING_OBJECT (src, "send interrupted");
5886     }
5887     g_free (str);
5888     return res;
5889   }
5890 receive_error:
5891   {
5892     switch (res) {
5893       case GST_RTSP_EEOF:
5894         GST_WARNING_OBJECT (src, "server closed connection");
5895         if ((try == 0) && !src->interleaved && src->udp_reconnect) {
5896           try++;
5897           /* if reconnect succeeds, try again */
5898           if ((res =
5899                   gst_rtsp_conninfo_reconnect (src, &src->conninfo,
5900                       FALSE)) == 0)
5901             goto again;
5902         }
5903         /* only try once after reconnect, then fallthrough and error out */
5904       default:
5905       {
5906         gchar *str = gst_rtsp_strresult (res);
5907
5908         if (res != GST_RTSP_EINTR) {
5909           GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
5910               ("Could not receive message. (%s)", str));
5911         } else {
5912           GST_WARNING_OBJECT (src, "receive interrupted");
5913         }
5914         g_free (str);
5915         break;
5916       }
5917     }
5918     return res;
5919   }
5920 handle_request_failed:
5921   {
5922     /* ERROR was posted */
5923     gst_rtsp_message_unset (response);
5924     return res;
5925   }
5926 server_eof:
5927   {
5928     GST_DEBUG_OBJECT (src, "we got an eof from the server");
5929     GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
5930         ("The server closed the connection."));
5931     gst_rtsp_message_unset (response);
5932     return res;
5933   }
5934 }
5935
5936 /**
5937  * gst_rtspsrc_send:
5938  * @src: the rtsp source
5939  * @conn: the connection to send on
5940  * @request: must point to a valid request
5941  * @response: must point to an empty #GstRTSPMessage
5942  * @code: an optional code result
5943  *
5944  * send @request and retrieve the response in @response. optionally @code can be
5945  * non-NULL in which case it will contain the status code of the response.
5946  *
5947  * If This function returns #GST_RTSP_OK, @response will contain a valid response
5948  * message that should be cleaned with gst_rtsp_message_unset() after usage.
5949  *
5950  * If @code is NULL, this function will return #GST_RTSP_ERROR (with an invalid
5951  * @response message) if the response code was not 200 (OK).
5952  *
5953  * If the attempt results in an authentication failure, then this will attempt
5954  * to retrieve authentication credentials via gst_rtspsrc_setup_auth and retry
5955  * the request.
5956  *
5957  * Returns: #GST_RTSP_OK if the processing was successful.
5958  */
5959 static GstRTSPResult
5960 gst_rtspsrc_send (GstRTSPSrc * src, GstRTSPConnection * conn,
5961     GstRTSPMessage * request, GstRTSPMessage * response,
5962     GstRTSPStatusCode * code)
5963 {
5964   GstRTSPStatusCode int_code = GST_RTSP_STS_OK;
5965   GstRTSPResult res = GST_RTSP_ERROR;
5966   gint count;
5967   gboolean retry;
5968   GstRTSPMethod method = GST_RTSP_INVALID;
5969
5970   count = 0;
5971   do {
5972     retry = FALSE;
5973
5974     /* make sure we don't loop forever */
5975     if (count++ > 8)
5976       break;
5977
5978     /* save method so we can disable it when the server complains */
5979     method = request->type_data.request.method;
5980
5981     if ((res =
5982             gst_rtspsrc_try_send (src, conn, request, response, &int_code)) < 0)
5983       goto error;
5984
5985     switch (int_code) {
5986       case GST_RTSP_STS_UNAUTHORIZED:
5987       case GST_RTSP_STS_NOT_FOUND:
5988         if (gst_rtspsrc_setup_auth (src, response)) {
5989           /* Try the request/response again after configuring the auth info
5990            * and loop again */
5991           retry = TRUE;
5992         }
5993         break;
5994       default:
5995         break;
5996     }
5997   } while (retry == TRUE);
5998
5999   /* If the user requested the code, let them handle errors, otherwise
6000    * post an error below */
6001   if (code != NULL)
6002     *code = int_code;
6003   else if (int_code != GST_RTSP_STS_OK)
6004     goto error_response;
6005
6006   return res;
6007
6008   /* ERRORS */
6009 error:
6010   {
6011     GST_DEBUG_OBJECT (src, "got error %d", res);
6012     return res;
6013   }
6014 error_response:
6015   {
6016     res = GST_RTSP_ERROR;
6017
6018     switch (response->type_data.response.code) {
6019       case GST_RTSP_STS_NOT_FOUND:
6020         GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("%s",
6021                 response->type_data.response.reason));
6022         break;
6023       case GST_RTSP_STS_UNAUTHORIZED:
6024         GST_ELEMENT_ERROR (src, RESOURCE, NOT_AUTHORIZED, (NULL), ("%s",
6025                 response->type_data.response.reason));
6026         break;
6027       case GST_RTSP_STS_MOVED_PERMANENTLY:
6028       case GST_RTSP_STS_MOVE_TEMPORARILY:
6029       {
6030         gchar *new_location;
6031         GstRTSPLowerTrans transports;
6032
6033         GST_DEBUG_OBJECT (src, "got redirection");
6034         /* if we don't have a Location Header, we must error */
6035         if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_LOCATION,
6036                 &new_location, 0) < 0)
6037           break;
6038
6039         /* When we receive a redirect result, we go back to the INIT state after
6040          * parsing the new URI. The caller should do the needed steps to issue
6041          * a new setup when it detects this state change. */
6042         GST_DEBUG_OBJECT (src, "redirection to %s", new_location);
6043
6044         /* save current transports */
6045         if (src->conninfo.url)
6046           transports = src->conninfo.url->transports;
6047         else
6048           transports = GST_RTSP_LOWER_TRANS_UNKNOWN;
6049
6050         gst_rtspsrc_uri_set_uri (GST_URI_HANDLER (src), new_location, NULL);
6051
6052         /* set old transports */
6053         if (src->conninfo.url && transports != GST_RTSP_LOWER_TRANS_UNKNOWN)
6054           src->conninfo.url->transports = transports;
6055
6056         src->need_redirect = TRUE;
6057         src->state = GST_RTSP_STATE_INIT;
6058         res = GST_RTSP_OK;
6059         break;
6060       }
6061       case GST_RTSP_STS_NOT_ACCEPTABLE:
6062       case GST_RTSP_STS_NOT_IMPLEMENTED:
6063       case GST_RTSP_STS_METHOD_NOT_ALLOWED:
6064         GST_WARNING_OBJECT (src, "got NOT IMPLEMENTED, disable method %s",
6065             gst_rtsp_method_as_text (method));
6066         src->methods &= ~method;
6067         res = GST_RTSP_OK;
6068         break;
6069       default:
6070         GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
6071             ("Got error response: %d (%s).", response->type_data.response.code,
6072                 response->type_data.response.reason));
6073         break;
6074     }
6075     /* if we return ERROR we should unset the response ourselves */
6076     if (res == GST_RTSP_ERROR)
6077       gst_rtsp_message_unset (response);
6078
6079     return res;
6080   }
6081 }
6082
6083 static GstRTSPResult
6084 gst_rtspsrc_send_cb (GstRTSPExtension * ext, GstRTSPMessage * request,
6085     GstRTSPMessage * response, GstRTSPSrc * src)
6086 {
6087   return gst_rtspsrc_send (src, src->conninfo.connection, request, response,
6088       NULL);
6089 }
6090
6091
6092 /* parse the response and collect all the supported methods. We need this
6093  * information so that we don't try to send an unsupported request to the
6094  * server.
6095  */
6096 static gboolean
6097 gst_rtspsrc_parse_methods (GstRTSPSrc * src, GstRTSPMessage * response)
6098 {
6099   GstRTSPHeaderField field;
6100   gchar *respoptions;
6101   gint indx = 0;
6102
6103   /* reset supported methods */
6104   src->methods = 0;
6105
6106   /* Try Allow Header first */
6107   field = GST_RTSP_HDR_ALLOW;
6108   while (TRUE) {
6109     respoptions = NULL;
6110     gst_rtsp_message_get_header (response, field, &respoptions, indx);
6111     if (indx == 0 && !respoptions) {
6112       /* if no Allow header was found then try the Public header... */
6113       field = GST_RTSP_HDR_PUBLIC;
6114       gst_rtsp_message_get_header (response, field, &respoptions, indx);
6115     }
6116     if (!respoptions)
6117       break;
6118
6119     src->methods |= gst_rtsp_options_from_text (respoptions);
6120
6121     indx++;
6122   }
6123
6124   if (src->methods == 0) {
6125     /* neither Allow nor Public are required, assume the server supports
6126      * at least DESCRIBE, SETUP, we always assume it supports PLAY as
6127      * well. */
6128     GST_DEBUG_OBJECT (src, "could not get OPTIONS");
6129     src->methods = GST_RTSP_DESCRIBE | GST_RTSP_SETUP;
6130   }
6131   /* always assume PLAY, FIXME, extensions should be able to override
6132    * this */
6133   src->methods |= GST_RTSP_PLAY;
6134   /* also assume it will support Range */
6135   src->seekable = TRUE;
6136
6137   /* we need describe and setup */
6138   if (!(src->methods & GST_RTSP_DESCRIBE))
6139     goto no_describe;
6140   if (!(src->methods & GST_RTSP_SETUP))
6141     goto no_setup;
6142
6143   return TRUE;
6144
6145   /* ERRORS */
6146 no_describe:
6147   {
6148     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
6149         ("Server does not support DESCRIBE."));
6150     return FALSE;
6151   }
6152 no_setup:
6153   {
6154     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
6155         ("Server does not support SETUP."));
6156     return FALSE;
6157   }
6158 }
6159
6160 /* masks to be kept in sync with the hardcoded protocol order of preference
6161  * in code below */
6162 static const guint protocol_masks[] = {
6163   GST_RTSP_LOWER_TRANS_UDP,
6164   GST_RTSP_LOWER_TRANS_UDP_MCAST,
6165   GST_RTSP_LOWER_TRANS_TCP,
6166   0
6167 };
6168
6169 static GstRTSPResult
6170 gst_rtspsrc_create_transports_string (GstRTSPSrc * src,
6171     GstRTSPLowerTrans protocols, GstRTSPProfile profile, gchar ** transports)
6172 {
6173   GstRTSPResult res;
6174   GString *result;
6175   gboolean add_udp_str;
6176
6177   *transports = NULL;
6178
6179   res =
6180       gst_rtsp_ext_list_get_transports (src->extensions, protocols, transports);
6181
6182   if (res < 0)
6183     goto failed;
6184
6185   GST_DEBUG_OBJECT (src, "got transports %s", GST_STR_NULL (*transports));
6186
6187   /* extension listed transports, use those */
6188   if (*transports != NULL)
6189     return GST_RTSP_OK;
6190
6191   /* it's the default */
6192   add_udp_str = FALSE;
6193
6194   /* the default RTSP transports */
6195   result = g_string_new ("RTP");
6196
6197   switch (profile) {
6198     case GST_RTSP_PROFILE_AVP:
6199       g_string_append (result, "/AVP");
6200       break;
6201     case GST_RTSP_PROFILE_SAVP:
6202       g_string_append (result, "/SAVP");
6203       break;
6204     case GST_RTSP_PROFILE_AVPF:
6205       g_string_append (result, "/AVPF");
6206       break;
6207     case GST_RTSP_PROFILE_SAVPF:
6208       g_string_append (result, "/SAVPF");
6209       break;
6210     default:
6211       break;
6212   }
6213
6214   if (protocols & GST_RTSP_LOWER_TRANS_UDP) {
6215     GST_DEBUG_OBJECT (src, "adding UDP unicast");
6216     if (add_udp_str)
6217       g_string_append (result, "/UDP");
6218     g_string_append (result, ";unicast;client_port=%%u1-%%u2");
6219   } else if (protocols & GST_RTSP_LOWER_TRANS_UDP_MCAST) {
6220     GST_DEBUG_OBJECT (src, "adding UDP multicast");
6221     /* we don't have to allocate any UDP ports yet, if the selected transport
6222      * turns out to be multicast we can create them and join the multicast
6223      * group indicated in the transport reply */
6224     if (add_udp_str)
6225       g_string_append (result, "/UDP");
6226     g_string_append (result, ";multicast");
6227     if (src->next_port_num != 0) {
6228       if (src->client_port_range.max > 0 &&
6229           src->next_port_num >= src->client_port_range.max)
6230         goto no_ports;
6231
6232       g_string_append_printf (result, ";client_port=%d-%d",
6233           src->next_port_num, src->next_port_num + 1);
6234     }
6235   } else if (protocols & GST_RTSP_LOWER_TRANS_TCP) {
6236     GST_DEBUG_OBJECT (src, "adding TCP");
6237
6238     g_string_append (result, "/TCP;unicast;interleaved=%%i1-%%i2");
6239   }
6240   *transports = g_string_free (result, FALSE);
6241
6242   GST_DEBUG_OBJECT (src, "prepared transports %s", GST_STR_NULL (*transports));
6243
6244   return GST_RTSP_OK;
6245
6246   /* ERRORS */
6247 failed:
6248   {
6249     GST_ERROR ("extension gave error %d", res);
6250     return res;
6251   }
6252 no_ports:
6253   {
6254     GST_ERROR ("no more ports available");
6255     return GST_RTSP_ERROR;
6256   }
6257 }
6258
6259 static GstRTSPResult
6260 gst_rtspsrc_prepare_transports (GstRTSPStream * stream, gchar ** transports,
6261     gint orig_rtpport, gint orig_rtcpport)
6262 {
6263   GstRTSPSrc *src;
6264   gint nr_udp, nr_int;
6265   gchar *next, *p;
6266   gint rtpport = 0, rtcpport = 0;
6267   GString *str;
6268
6269   src = stream->parent;
6270
6271   /* find number of placeholders first */
6272   if (strstr (*transports, "%%i2"))
6273     nr_int = 2;
6274   else if (strstr (*transports, "%%i1"))
6275     nr_int = 1;
6276   else
6277     nr_int = 0;
6278
6279   if (strstr (*transports, "%%u2"))
6280     nr_udp = 2;
6281   else if (strstr (*transports, "%%u1"))
6282     nr_udp = 1;
6283   else
6284     nr_udp = 0;
6285
6286   if (nr_udp == 0 && nr_int == 0)
6287     goto done;
6288
6289   if (nr_udp > 0) {
6290     if (!orig_rtpport || !orig_rtcpport) {
6291       if (!gst_rtspsrc_alloc_udp_ports (stream, &rtpport, &rtcpport))
6292         goto failed;
6293     } else {
6294       rtpport = orig_rtpport;
6295       rtcpport = orig_rtcpport;
6296     }
6297   }
6298
6299   str = g_string_new ("");
6300   p = *transports;
6301   while ((next = strstr (p, "%%"))) {
6302     g_string_append_len (str, p, next - p);
6303     if (next[2] == 'u') {
6304       if (next[3] == '1')
6305         g_string_append_printf (str, "%d", rtpport);
6306       else if (next[3] == '2')
6307         g_string_append_printf (str, "%d", rtcpport);
6308     }
6309     if (next[2] == 'i') {
6310       if (next[3] == '1')
6311         g_string_append_printf (str, "%d", src->free_channel);
6312       else if (next[3] == '2')
6313         g_string_append_printf (str, "%d", src->free_channel + 1);
6314     }
6315
6316     p = next + 4;
6317   }
6318   /* append final part */
6319   g_string_append (str, p);
6320
6321   g_free (*transports);
6322   *transports = g_string_free (str, FALSE);
6323
6324 done:
6325   return GST_RTSP_OK;
6326
6327   /* ERRORS */
6328 failed:
6329   {
6330     GST_ERROR ("failed to allocate udp ports");
6331     return GST_RTSP_ERROR;
6332   }
6333 }
6334
6335 static guint8
6336 enc_key_length_from_cipher_name (const gchar * cipher)
6337 {
6338   if (g_strcmp0 (cipher, "aes-128-icm") == 0)
6339     return AES_128_KEY_LEN;
6340   else if (g_strcmp0 (cipher, "aes-256-icm") == 0)
6341     return AES_256_KEY_LEN;
6342   else {
6343     GST_ERROR ("encryption algorithm '%s' not supported", cipher);
6344     return 0;
6345   }
6346 }
6347
6348 static guint8
6349 auth_key_length_from_auth_name (const gchar * auth)
6350 {
6351   if (g_strcmp0 (auth, "hmac-sha1-32") == 0)
6352     return HMAC_32_KEY_LEN;
6353   else if (g_strcmp0 (auth, "hmac-sha1-80") == 0)
6354     return HMAC_80_KEY_LEN;
6355   else {
6356     GST_ERROR ("authentication algorithm '%s' not supported", auth);
6357     return 0;
6358   }
6359 }
6360
6361 static GstCaps *
6362 signal_get_srtcp_params (GstRTSPSrc * src, GstRTSPStream * stream)
6363 {
6364   GstCaps *caps = NULL;
6365
6366   g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_REQUEST_RTCP_KEY], 0,
6367       stream->id, &caps);
6368
6369   if (caps != NULL)
6370     GST_DEBUG_OBJECT (src, "SRTP parameters received");
6371
6372   return caps;
6373 }
6374
6375 static GstCaps *
6376 default_srtcp_params (void)
6377 {
6378   guint i;
6379   GstCaps *caps;
6380   GstBuffer *buf;
6381   guint8 *key_data;
6382 #define KEY_SIZE 30
6383   guint data_size = GST_ROUND_UP_4 (KEY_SIZE);
6384
6385   /* create a random key */
6386   key_data = g_malloc (data_size);
6387   for (i = 0; i < data_size; i += 4)
6388     GST_WRITE_UINT32_BE (key_data + i, g_random_int ());
6389
6390   buf = gst_buffer_new_wrapped (key_data, KEY_SIZE);
6391
6392   caps = gst_caps_new_simple ("application/x-srtp",
6393       "srtp-key", GST_TYPE_BUFFER, buf,
6394       "srtcp-cipher", G_TYPE_STRING, "aes-128-icm",
6395       "srtcp-auth", G_TYPE_STRING, "hmac-sha1-80", NULL);
6396
6397   gst_buffer_unref (buf);
6398
6399   return caps;
6400 }
6401
6402 static gchar *
6403 gst_rtspsrc_stream_make_keymgmt (GstRTSPSrc * src, GstRTSPStream * stream)
6404 {
6405   GBytes *bytes;
6406   gchar *result, *base64;
6407   const guint8 *data;
6408   gsize size;
6409   GstMIKEYMessage *msg;
6410   GstMIKEYPayload *payload, *pkd;
6411   guint8 byte;
6412   GstStructure *s;
6413   GstMapInfo info;
6414   GstBuffer *srtpkey;
6415   const GValue *val;
6416   const gchar *srtcpcipher, *srtcpauth;
6417
6418   stream->srtcpparams = signal_get_srtcp_params (src, stream);
6419   if (stream->srtcpparams == NULL)
6420     stream->srtcpparams = default_srtcp_params ();
6421
6422   s = gst_caps_get_structure (stream->srtcpparams, 0);
6423
6424   srtcpcipher = gst_structure_get_string (s, "srtcp-cipher");
6425   srtcpauth = gst_structure_get_string (s, "srtcp-auth");
6426   val = gst_structure_get_value (s, "srtp-key");
6427
6428   if (srtcpcipher == NULL || srtcpauth == NULL || val == NULL) {
6429     GST_ERROR_OBJECT (src, "could not find the right SRTP parameters in caps");
6430     return NULL;
6431   }
6432
6433   srtpkey = gst_value_get_buffer (val);
6434
6435   msg = gst_mikey_message_new ();
6436   /* unencrypted MIKEY message, we send this over TLS so this is allowed */
6437   gst_mikey_message_set_info (msg, GST_MIKEY_VERSION, GST_MIKEY_TYPE_PSK_INIT,
6438       FALSE, GST_MIKEY_PRF_MIKEY_1, g_random_int (), GST_MIKEY_MAP_TYPE_SRTP);
6439   /* add policy '0' for our SSRC */
6440   gst_mikey_message_add_cs_srtp (msg, 0, stream->send_ssrc, 0);
6441   /* timestamp is now */
6442   gst_mikey_message_add_t_now_ntp_utc (msg);
6443   /* add some random data */
6444   gst_mikey_message_add_rand_len (msg, 16);
6445
6446   /* the policy '0' is SRTP */
6447   payload = gst_mikey_payload_new (GST_MIKEY_PT_SP);
6448   gst_mikey_payload_sp_set (payload, 0, GST_MIKEY_SEC_PROTO_SRTP);
6449
6450   /* only AES-CM is supported */
6451   byte = 1;
6452   gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_ALG, 1, &byte);
6453   /* encryption key length */
6454   byte = enc_key_length_from_cipher_name (srtcpcipher);
6455   gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_KEY_LEN, 1,
6456       &byte);
6457   /* only HMAC-SHA1 */
6458   gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_ALG, 1,
6459       &byte);
6460   /* authentication key length */
6461   byte = auth_key_length_from_auth_name (srtcpauth);
6462   gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_KEY_LEN, 1,
6463       &byte);
6464   /* we enable encryption on RTP and RTCP */
6465   gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_ENC, 1,
6466       &byte);
6467   gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTCP_ENC, 1,
6468       &byte);
6469   /* we enable authentication on RTP and RTCP */
6470   gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_AUTH, 1,
6471       &byte);
6472   gst_mikey_message_add_payload (msg, payload);
6473
6474   /* make unencrypted KEMAC */
6475   payload = gst_mikey_payload_new (GST_MIKEY_PT_KEMAC);
6476   gst_mikey_payload_kemac_set (payload, GST_MIKEY_ENC_NULL, GST_MIKEY_MAC_NULL);
6477   /* add the key in KEMAC */
6478   pkd = gst_mikey_payload_new (GST_MIKEY_PT_KEY_DATA);
6479   gst_buffer_map (srtpkey, &info, GST_MAP_READ);
6480   gst_mikey_payload_key_data_set_key (pkd, GST_MIKEY_KD_TEK, info.size,
6481       info.data);
6482   gst_buffer_unmap (srtpkey, &info);
6483   gst_mikey_payload_kemac_add_sub (payload, pkd);
6484   gst_mikey_message_add_payload (msg, payload);
6485
6486   /* now serialize this to bytes */
6487   bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);
6488   gst_mikey_message_unref (msg);
6489   /* and make it into base64 */
6490   data = g_bytes_get_data (bytes, &size);
6491   base64 = g_base64_encode (data, size);
6492   g_bytes_unref (bytes);
6493
6494   result = g_strdup_printf ("prot=mikey;uri=\"%s\";data=\"%s\"",
6495       stream->conninfo.location, base64);
6496   g_free (base64);
6497
6498   return result;
6499 }
6500
6501
6502 /* Perform the SETUP request for all the streams.
6503  *
6504  * We ask the server for a specific transport, which initially includes all the
6505  * ones we can support (UDP/TCP/MULTICAST). For the UDP transport we allocate
6506  * two local UDP ports that we send to the server.
6507  *
6508  * Once the server replied with a transport, we configure the other streams
6509  * with the same transport.
6510  *
6511  * This function will also configure the stream for the selected transport,
6512  * which basically means creating the pipeline.
6513  */
6514 static GstRTSPResult
6515 gst_rtspsrc_setup_streams (GstRTSPSrc * src, gboolean async)
6516 {
6517   GList *walk;
6518   GstRTSPResult res = GST_RTSP_ERROR;
6519   GstRTSPMessage request = { 0 };
6520   GstRTSPMessage response = { 0 };
6521   GstRTSPStream *stream = NULL;
6522   GstRTSPLowerTrans protocols;
6523   GstRTSPStatusCode code;
6524   gboolean unsupported_real = FALSE;
6525   gint rtpport, rtcpport;
6526   GstRTSPUrl *url;
6527   gchar *hval;
6528
6529   if (src->conninfo.connection) {
6530     url = gst_rtsp_connection_get_url (src->conninfo.connection);
6531     /* we initially allow all configured lower transports. based on the URL
6532      * transports and the replies from the server we narrow them down. */
6533     protocols = url->transports & src->cur_protocols;
6534   } else {
6535     url = NULL;
6536     protocols = src->cur_protocols;
6537   }
6538
6539   if (protocols == 0)
6540     goto no_protocols;
6541
6542   /* reset some state */
6543   src->free_channel = 0;
6544   src->interleaved = FALSE;
6545   src->need_activate = FALSE;
6546   /* keep track of next port number, 0 is random */
6547   src->next_port_num = src->client_port_range.min;
6548   rtpport = rtcpport = 0;
6549
6550   if (G_UNLIKELY (src->streams == NULL))
6551     goto no_streams;
6552
6553   for (walk = src->streams; walk; walk = g_list_next (walk)) {
6554     GstRTSPConnection *conn;
6555     gchar *transports;
6556     gint retry = 0;
6557     guint mask = 0;
6558     gboolean selected;
6559     GstCaps *caps;
6560
6561     stream = (GstRTSPStream *) walk->data;
6562
6563     caps = stream_get_caps_for_pt (stream, stream->default_pt);
6564     if (caps == NULL) {
6565       GST_DEBUG_OBJECT (src, "skipping stream %p, no caps", stream);
6566       continue;
6567     }
6568
6569     if (stream->skipped) {
6570       GST_DEBUG_OBJECT (src, "skipping stream %p", stream);
6571       continue;
6572     }
6573
6574     /* see if we need to configure this stream */
6575     if (!gst_rtsp_ext_list_configure_stream (src->extensions, caps)) {
6576       GST_DEBUG_OBJECT (src, "skipping stream %p, disabled by extension",
6577           stream);
6578       continue;
6579     }
6580
6581     g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_SELECT_STREAM], 0,
6582         stream->id, caps, &selected);
6583     if (!selected) {
6584       GST_DEBUG_OBJECT (src, "skipping stream %p, disabled by signal", stream);
6585       continue;
6586     }
6587
6588     /* merge/overwrite global caps */
6589     if (caps) {
6590       guint j, num;
6591       GstStructure *s;
6592
6593       s = gst_caps_get_structure (caps, 0);
6594
6595       num = gst_structure_n_fields (src->props);
6596       for (j = 0; j < num; j++) {
6597         const gchar *name;
6598         const GValue *val;
6599
6600         name = gst_structure_nth_field_name (src->props, j);
6601         val = gst_structure_get_value (src->props, name);
6602         gst_structure_set_value (s, name, val);
6603
6604         GST_DEBUG_OBJECT (src, "copied %s", name);
6605       }
6606     }
6607
6608     /* skip setup if we have no URL for it */
6609     if (stream->conninfo.location == NULL) {
6610       GST_DEBUG_OBJECT (src, "skipping stream %p, no setup", stream);
6611       continue;
6612     }
6613
6614     if (src->conninfo.connection == NULL) {
6615       if (!gst_rtsp_conninfo_connect (src, &stream->conninfo, async)) {
6616         GST_DEBUG_OBJECT (src, "skipping stream %p, failed to connect", stream);
6617         continue;
6618       }
6619       conn = stream->conninfo.connection;
6620     } else {
6621       conn = src->conninfo.connection;
6622     }
6623     GST_DEBUG_OBJECT (src, "doing setup of stream %p with %s", stream,
6624         stream->conninfo.location);
6625
6626     /* if we have a multicast connection, only suggest multicast from now on */
6627     if (stream->is_multicast)
6628       protocols &= GST_RTSP_LOWER_TRANS_UDP_MCAST;
6629
6630   next_protocol:
6631     /* first selectable protocol */
6632     while (protocol_masks[mask] && !(protocols & protocol_masks[mask]))
6633       mask++;
6634     if (!protocol_masks[mask])
6635       goto no_protocols;
6636
6637   retry:
6638     GST_DEBUG_OBJECT (src, "protocols = 0x%x, protocol mask = 0x%x", protocols,
6639         protocol_masks[mask]);
6640     /* create a string with first transport in line */
6641     transports = NULL;
6642     res = gst_rtspsrc_create_transports_string (src,
6643         protocols & protocol_masks[mask], stream->profile, &transports);
6644     if (res < 0 || transports == NULL)
6645       goto setup_transport_failed;
6646
6647     if (strlen (transports) == 0) {
6648       g_free (transports);
6649       GST_DEBUG_OBJECT (src, "no transports found");
6650       mask++;
6651       goto next_protocol;
6652     }
6653
6654     GST_DEBUG_OBJECT (src, "replace ports in %s", GST_STR_NULL (transports));
6655
6656     /* replace placeholders with real values, this function will optionally
6657      * allocate UDP ports and other info needed to execute the setup request */
6658     res = gst_rtspsrc_prepare_transports (stream, &transports,
6659         retry > 0 ? rtpport : 0, retry > 0 ? rtcpport : 0);
6660     if (res < 0) {
6661       g_free (transports);
6662       goto setup_transport_failed;
6663     }
6664
6665     GST_DEBUG_OBJECT (src, "transport is now %s", GST_STR_NULL (transports));
6666
6667     /* create SETUP request */
6668     res =
6669         gst_rtspsrc_init_request (src, &request, GST_RTSP_SETUP,
6670         stream->conninfo.location);
6671     if (res < 0) {
6672       g_free (transports);
6673       goto create_request_failed;
6674     }
6675
6676     /* select transport */
6677     gst_rtsp_message_take_header (&request, GST_RTSP_HDR_TRANSPORT, transports);
6678
6679     /* set up keys */
6680     if (stream->profile == GST_RTSP_PROFILE_SAVP ||
6681         stream->profile == GST_RTSP_PROFILE_SAVPF) {
6682       hval = gst_rtspsrc_stream_make_keymgmt (src, stream);
6683       gst_rtsp_message_take_header (&request, GST_RTSP_HDR_KEYMGMT, hval);
6684     }
6685
6686     /* if the user wants a non default RTP packet size we add the blocksize
6687      * parameter */
6688     if (src->rtp_blocksize > 0) {
6689       hval = g_strdup_printf ("%d", src->rtp_blocksize);
6690       gst_rtsp_message_take_header (&request, GST_RTSP_HDR_BLOCKSIZE, hval);
6691     }
6692
6693     if (async)
6694       GST_ELEMENT_PROGRESS (src, CONTINUE, "request", ("SETUP stream %d",
6695               stream->id));
6696
6697     /* handle the code ourselves */
6698     res = gst_rtspsrc_send (src, conn, &request, &response, &code);
6699     if (res < 0)
6700       goto send_error;
6701
6702     switch (code) {
6703       case GST_RTSP_STS_OK:
6704         break;
6705       case GST_RTSP_STS_UNSUPPORTED_TRANSPORT:
6706         gst_rtsp_message_unset (&request);
6707         gst_rtsp_message_unset (&response);
6708         /* cleanup of leftover transport */
6709         gst_rtspsrc_stream_free_udp (stream);
6710         /* MS WMServer RTSP MUST use same UDP pair in all SETUP requests;
6711          * we might be in this case */
6712         if (stream->container && rtpport && rtcpport && !retry) {
6713           GST_DEBUG_OBJECT (src, "retrying with original port pair %u-%u",
6714               rtpport, rtcpport);
6715           retry++;
6716           goto retry;
6717         }
6718         /* this transport did not go down well, but we may have others to try
6719          * that we did not send yet, try those and only give up then
6720          * but not without checking for lost cause/extension so we can
6721          * post a nicer/more useful error message later */
6722         if (!unsupported_real)
6723           unsupported_real = stream->is_real;
6724         /* select next available protocol, give up on this stream if none */
6725         mask++;
6726         while (protocol_masks[mask] && !(protocols & protocol_masks[mask]))
6727           mask++;
6728         if (!protocol_masks[mask] || unsupported_real)
6729           continue;
6730         else
6731           goto retry;
6732       default:
6733         /* cleanup of leftover transport and move to the next stream */
6734         gst_rtspsrc_stream_free_udp (stream);
6735         goto response_error;
6736     }
6737
6738     /* parse response transport */
6739     {
6740       gchar *resptrans = NULL;
6741       GstRTSPTransport transport = { 0 };
6742
6743       gst_rtsp_message_get_header (&response, GST_RTSP_HDR_TRANSPORT,
6744           &resptrans, 0);
6745       if (!resptrans) {
6746         gst_rtspsrc_stream_free_udp (stream);
6747         goto no_transport;
6748       }
6749
6750       /* parse transport, go to next stream on parse error */
6751       if (gst_rtsp_transport_parse (resptrans, &transport) != GST_RTSP_OK) {
6752         GST_WARNING_OBJECT (src, "failed to parse transport %s", resptrans);
6753         goto next;
6754       }
6755
6756       /* update allowed transports for other streams. once the transport of
6757        * one stream has been determined, we make sure that all other streams
6758        * are configured in the same way */
6759       switch (transport.lower_transport) {
6760         case GST_RTSP_LOWER_TRANS_TCP:
6761           GST_DEBUG_OBJECT (src, "stream %p as TCP interleaved", stream);
6762           protocols = GST_RTSP_LOWER_TRANS_TCP;
6763           src->interleaved = TRUE;
6764           /* update free channels */
6765           src->free_channel =
6766               MAX (transport.interleaved.min, src->free_channel);
6767           src->free_channel =
6768               MAX (transport.interleaved.max, src->free_channel);
6769           src->free_channel++;
6770           break;
6771         case GST_RTSP_LOWER_TRANS_UDP_MCAST:
6772           /* only allow multicast for other streams */
6773           GST_DEBUG_OBJECT (src, "stream %p as UDP multicast", stream);
6774           protocols = GST_RTSP_LOWER_TRANS_UDP_MCAST;
6775           /* if the server selected our ports, increment our counters so that
6776            * we select a new port later */
6777           if (src->next_port_num == transport.port.min &&
6778               src->next_port_num + 1 == transport.port.max) {
6779             src->next_port_num += 2;
6780           }
6781           break;
6782         case GST_RTSP_LOWER_TRANS_UDP:
6783           /* only allow unicast for other streams */
6784           GST_DEBUG_OBJECT (src, "stream %p as UDP unicast", stream);
6785           protocols = GST_RTSP_LOWER_TRANS_UDP;
6786           break;
6787         default:
6788           GST_DEBUG_OBJECT (src, "stream %p unknown transport %d", stream,
6789               transport.lower_transport);
6790           break;
6791       }
6792
6793       if (!src->interleaved || !retry) {
6794         /* now configure the stream with the selected transport */
6795         if (!gst_rtspsrc_stream_configure_transport (stream, &transport)) {
6796           GST_DEBUG_OBJECT (src,
6797               "could not configure stream %p transport, skipping stream",
6798               stream);
6799           goto next;
6800         } else if (stream->udpsrc[0] && stream->udpsrc[1]) {
6801           /* retain the first allocated UDP port pair */
6802           g_object_get (G_OBJECT (stream->udpsrc[0]), "port", &rtpport, NULL);
6803           g_object_get (G_OBJECT (stream->udpsrc[1]), "port", &rtcpport, NULL);
6804         }
6805       }
6806       /* we need to activate at least one streams when we detect activity */
6807       src->need_activate = TRUE;
6808
6809       /* stream is setup now */
6810       stream->setup = TRUE;
6811       {
6812         GList *skip = walk;
6813
6814         while (TRUE) {
6815           GstRTSPStream *sskip;
6816
6817           skip = g_list_next (skip);
6818           if (skip == NULL)
6819             break;
6820
6821           sskip = (GstRTSPStream *) skip->data;
6822
6823           /* skip all streams with the same control url */
6824           if (g_str_equal (stream->conninfo.location, sskip->conninfo.location)) {
6825             GST_DEBUG_OBJECT (src, "found stream %p with same control %s",
6826                 sskip, sskip->conninfo.location);
6827             sskip->skipped = TRUE;
6828           }
6829         }
6830       }
6831     next:
6832       /* clean up our transport struct */
6833       gst_rtsp_transport_init (&transport);
6834       /* clean up used RTSP messages */
6835       gst_rtsp_message_unset (&request);
6836       gst_rtsp_message_unset (&response);
6837     }
6838   }
6839
6840   /* store the transport protocol that was configured */
6841   src->cur_protocols = protocols;
6842
6843   gst_rtsp_ext_list_stream_select (src->extensions, url);
6844
6845   /* if there is nothing to activate, error out */
6846   if (!src->need_activate)
6847     goto nothing_to_activate;
6848
6849   return res;
6850
6851   /* ERRORS */
6852 no_protocols:
6853   {
6854     /* no transport possible, post an error and stop */
6855     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
6856         ("Could not connect to server, no protocols left"));
6857     return GST_RTSP_ERROR;
6858   }
6859 no_streams:
6860   {
6861     GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
6862         ("SDP contains no streams"));
6863     return GST_RTSP_ERROR;
6864   }
6865 create_request_failed:
6866   {
6867     gchar *str = gst_rtsp_strresult (res);
6868
6869     GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
6870         ("Could not create request. (%s)", str));
6871     g_free (str);
6872     goto cleanup_error;
6873   }
6874 setup_transport_failed:
6875   {
6876     GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
6877         ("Could not setup transport."));
6878     res = GST_RTSP_ERROR;
6879     goto cleanup_error;
6880   }
6881 response_error:
6882   {
6883     const gchar *str = gst_rtsp_status_as_text (code);
6884
6885     GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
6886         ("Error (%d): %s", code, GST_STR_NULL (str)));
6887     res = GST_RTSP_ERROR;
6888     goto cleanup_error;
6889   }
6890 send_error:
6891   {
6892     gchar *str = gst_rtsp_strresult (res);
6893
6894     if (res != GST_RTSP_EINTR) {
6895       GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
6896           ("Could not send message. (%s)", str));
6897     } else {
6898       GST_WARNING_OBJECT (src, "send interrupted");
6899     }
6900     g_free (str);
6901     goto cleanup_error;
6902   }
6903 no_transport:
6904   {
6905     GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
6906         ("Server did not select transport."));
6907     res = GST_RTSP_ERROR;
6908     goto cleanup_error;
6909   }
6910 nothing_to_activate:
6911   {
6912     /* none of the available error codes is really right .. */
6913     if (unsupported_real) {
6914       GST_ELEMENT_ERROR (src, STREAM, CODEC_NOT_FOUND,
6915           (_("No supported stream was found. You might need to install a "
6916                   "GStreamer RTSP extension plugin for Real media streams.")),
6917           (NULL));
6918     } else {
6919       GST_ELEMENT_ERROR (src, STREAM, CODEC_NOT_FOUND,
6920           (_("No supported stream was found. You might need to allow "
6921                   "more transport protocols or may otherwise be missing "
6922                   "the right GStreamer RTSP extension plugin.")), (NULL));
6923     }
6924     return GST_RTSP_ERROR;
6925   }
6926 cleanup_error:
6927   {
6928     gst_rtsp_message_unset (&request);
6929     gst_rtsp_message_unset (&response);
6930     return res;
6931   }
6932 }
6933
6934 static gboolean
6935 gst_rtspsrc_parse_range (GstRTSPSrc * src, const gchar * range,
6936     GstSegment * segment)
6937 {
6938   gint64 seconds;
6939   GstRTSPTimeRange *therange;
6940
6941   if (src->range)
6942     gst_rtsp_range_free (src->range);
6943
6944   if (gst_rtsp_range_parse (range, &therange) == GST_RTSP_OK) {
6945     GST_DEBUG_OBJECT (src, "parsed range %s", range);
6946     src->range = therange;
6947   } else {
6948     GST_DEBUG_OBJECT (src, "failed to parse range %s", range);
6949     src->range = NULL;
6950     gst_segment_init (segment, GST_FORMAT_TIME);
6951     return FALSE;
6952   }
6953
6954   GST_DEBUG_OBJECT (src, "range: type %d, min %f - type %d,  max %f ",
6955       therange->min.type, therange->min.seconds, therange->max.type,
6956       therange->max.seconds);
6957
6958   if (therange->min.type == GST_RTSP_TIME_NOW)
6959     seconds = 0;
6960   else if (therange->min.type == GST_RTSP_TIME_END)
6961     seconds = 0;
6962   else
6963     seconds = therange->min.seconds * GST_SECOND;
6964
6965   GST_DEBUG_OBJECT (src, "range: min %" GST_TIME_FORMAT,
6966       GST_TIME_ARGS (seconds));
6967
6968   /* we need to start playback without clipping from the position reported by
6969    * the server */
6970   segment->start = seconds;
6971   segment->position = seconds;
6972
6973   if (therange->max.type == GST_RTSP_TIME_NOW)
6974     seconds = -1;
6975   else if (therange->max.type == GST_RTSP_TIME_END)
6976     seconds = -1;
6977   else
6978     seconds = therange->max.seconds * GST_SECOND;
6979
6980   GST_DEBUG_OBJECT (src, "range: max %" GST_TIME_FORMAT,
6981       GST_TIME_ARGS (seconds));
6982
6983   /* live (WMS) server might send overflowed large max as its idea of infinity,
6984    * compensate to prevent problems later on */
6985   if (seconds != -1 && seconds < 0) {
6986     seconds = -1;
6987     GST_DEBUG_OBJECT (src, "insane range, set to NONE");
6988   }
6989
6990   /* live (WMS) might send min == max, which is not worth recording */
6991   if (segment->duration == -1 && seconds == segment->start)
6992     seconds = -1;
6993
6994   /* don't change duration with unknown value, we might have a valid value
6995    * there that we want to keep. */
6996   if (seconds != -1)
6997     segment->duration = seconds;
6998
6999   return TRUE;
7000 }
7001
7002 /* Parse clock profived by the server with following syntax:
7003  *
7004  * "GstNetTimeProvider <wrapped-clock> <server-IP:port> <clock-time>"
7005  */
7006 static gboolean
7007 gst_rtspsrc_parse_gst_clock (GstRTSPSrc * src, const gchar * gstclock)
7008 {
7009   gboolean res = FALSE;
7010
7011   if (g_str_has_prefix (gstclock, "GstNetTimeProvider ")) {
7012     gchar **fields = NULL, **parts = NULL;
7013     gchar *remote_ip, *str;
7014     gint port;
7015     GstClockTime base_time;
7016     GstClock *netclock;
7017
7018     fields = g_strsplit (gstclock, " ", 0);
7019
7020     /* wrapped clock, not very interesting for now */
7021     if (fields[1] == NULL)
7022       goto cleanup;
7023
7024     /* remote IP address and port */
7025     if ((str = fields[2]) == NULL)
7026       goto cleanup;
7027
7028     parts = g_strsplit (str, ":", 0);
7029
7030     if ((remote_ip = parts[0]) == NULL)
7031       goto cleanup;
7032
7033     if ((str = parts[1]) == NULL)
7034       goto cleanup;
7035
7036     port = atoi (str);
7037     if (port == 0)
7038       goto cleanup;
7039
7040     /* base-time */
7041     if ((str = fields[3]) == NULL)
7042       goto cleanup;
7043
7044     base_time = g_ascii_strtoull (str, NULL, 10);
7045
7046     netclock =
7047         gst_net_client_clock_new ((gchar *) "GstRTSPClock", remote_ip, port,
7048         base_time);
7049
7050     if (src->provided_clock)
7051       gst_object_unref (src->provided_clock);
7052     src->provided_clock = netclock;
7053
7054     gst_element_post_message (GST_ELEMENT_CAST (src),
7055         gst_message_new_clock_provide (GST_OBJECT_CAST (src),
7056             src->provided_clock, TRUE));
7057
7058     res = TRUE;
7059   cleanup:
7060     g_strfreev (fields);
7061     g_strfreev (parts);
7062   }
7063   return res;
7064 }
7065
7066 /* must be called with the RTSP state lock */
7067 static GstRTSPResult
7068 gst_rtspsrc_open_from_sdp (GstRTSPSrc * src, GstSDPMessage * sdp,
7069     gboolean async)
7070 {
7071   GstRTSPResult res;
7072   gint i, n_streams;
7073
7074   /* prepare global stream caps properties */
7075   if (src->props)
7076     gst_structure_remove_all_fields (src->props);
7077   else
7078     src->props = gst_structure_new_empty ("RTSPProperties");
7079
7080   if (src->debug)
7081     gst_sdp_message_dump (sdp);
7082
7083   gst_rtsp_ext_list_parse_sdp (src->extensions, sdp, src->props);
7084
7085   /* let the app inspect and change the SDP */
7086   g_signal_emit (src, gst_rtspsrc_signals[SIGNAL_ON_SDP], 0, sdp);
7087
7088   gst_segment_init (&src->segment, GST_FORMAT_TIME);
7089
7090   /* parse range for duration reporting. */
7091   {
7092     const gchar *range;
7093
7094     for (i = 0;; i++) {
7095       range = gst_sdp_message_get_attribute_val_n (sdp, "range", i);
7096       if (range == NULL)
7097         break;
7098
7099       /* keep track of the range and configure it in the segment */
7100       if (gst_rtspsrc_parse_range (src, range, &src->segment))
7101         break;
7102     }
7103   }
7104   /* parse clock information. This is GStreamer specific, a server can tell the
7105    * client what clock it is using and wrap that in a network clock. The
7106    * advantage of that is that we can slave to it. */
7107   {
7108     const gchar *gstclock;
7109
7110     for (i = 0;; i++) {
7111       gstclock = gst_sdp_message_get_attribute_val_n (sdp, "x-gst-clock", i);
7112       if (gstclock == NULL)
7113         break;
7114
7115       /* parse the clock and expose it in the provide_clock method */
7116       if (gst_rtspsrc_parse_gst_clock (src, gstclock))
7117         break;
7118     }
7119   }
7120   /* try to find a global control attribute. Note that a '*' means that we should
7121    * do aggregate control with the current url (so we don't do anything and
7122    * leave the current connection as is) */
7123   {
7124     const gchar *control;
7125
7126     for (i = 0;; i++) {
7127       control = gst_sdp_message_get_attribute_val_n (sdp, "control", i);
7128       if (control == NULL)
7129         break;
7130
7131       /* only take fully qualified urls */
7132       if (g_str_has_prefix (control, "rtsp://"))
7133         break;
7134     }
7135     if (control) {
7136       g_free (src->conninfo.location);
7137       src->conninfo.location = g_strdup (control);
7138       /* make a connection for this, if there was a connection already, nothing
7139        * happens. */
7140       if (gst_rtsp_conninfo_connect (src, &src->conninfo, async) < 0) {
7141         GST_ERROR_OBJECT (src, "could not connect");
7142       }
7143     }
7144     /* we need to keep the control url separate from the connection url because
7145      * the rules for constructing the media control url need it */
7146     g_free (src->control);
7147     src->control = g_strdup (control);
7148   }
7149
7150   /* create streams */
7151   n_streams = gst_sdp_message_medias_len (sdp);
7152   for (i = 0; i < n_streams; i++) {
7153     gst_rtspsrc_create_stream (src, sdp, i);
7154   }
7155
7156   src->state = GST_RTSP_STATE_INIT;
7157
7158   /* setup streams */
7159   if ((res = gst_rtspsrc_setup_streams (src, async)) < 0)
7160     goto setup_failed;
7161
7162   /* reset our state */
7163   src->need_range = TRUE;
7164   src->skip = FALSE;
7165
7166   src->state = GST_RTSP_STATE_READY;
7167
7168   return res;
7169
7170   /* ERRORS */
7171 setup_failed:
7172   {
7173     GST_ERROR_OBJECT (src, "setup failed");
7174     gst_rtspsrc_cleanup (src);
7175     return res;
7176   }
7177 }
7178
7179 static GstRTSPResult
7180 gst_rtspsrc_retrieve_sdp (GstRTSPSrc * src, GstSDPMessage ** sdp,
7181     gboolean async)
7182 {
7183   GstRTSPResult res;
7184   GstRTSPMessage request = { 0 };
7185   GstRTSPMessage response = { 0 };
7186   guint8 *data;
7187   guint size;
7188   gchar *respcont = NULL;
7189
7190 restart:
7191   src->need_redirect = FALSE;
7192
7193   /* can't continue without a valid url */
7194   if (G_UNLIKELY (src->conninfo.url == NULL)) {
7195     res = GST_RTSP_EINVAL;
7196     goto no_url;
7197   }
7198   src->tried_url_auth = FALSE;
7199
7200   if ((res = gst_rtsp_conninfo_connect (src, &src->conninfo, async)) < 0)
7201     goto connect_failed;
7202
7203   /* create OPTIONS */
7204   GST_DEBUG_OBJECT (src, "create options...");
7205   res =
7206       gst_rtspsrc_init_request (src, &request, GST_RTSP_OPTIONS,
7207       src->conninfo.url_str);
7208   if (res < 0)
7209     goto create_request_failed;
7210
7211   /* send OPTIONS */
7212   GST_DEBUG_OBJECT (src, "send options...");
7213
7214   if (async)
7215     GST_ELEMENT_PROGRESS (src, CONTINUE, "open", ("Retrieving server options"));
7216
7217   if ((res =
7218           gst_rtspsrc_send (src, src->conninfo.connection, &request, &response,
7219               NULL)) < 0)
7220     goto send_error;
7221
7222   /* parse OPTIONS */
7223   if (!gst_rtspsrc_parse_methods (src, &response))
7224     goto methods_error;
7225
7226   /* create DESCRIBE */
7227   GST_DEBUG_OBJECT (src, "create describe...");
7228   res =
7229       gst_rtspsrc_init_request (src, &request, GST_RTSP_DESCRIBE,
7230       src->conninfo.url_str);
7231   if (res < 0)
7232     goto create_request_failed;
7233
7234   /* we only accept SDP for now */
7235   gst_rtsp_message_add_header (&request, GST_RTSP_HDR_ACCEPT,
7236       "application/sdp");
7237
7238   /* send DESCRIBE */
7239   GST_DEBUG_OBJECT (src, "send describe...");
7240
7241   if (async)
7242     GST_ELEMENT_PROGRESS (src, CONTINUE, "open", ("Retrieving media info"));
7243
7244   if ((res =
7245           gst_rtspsrc_send (src, src->conninfo.connection, &request, &response,
7246               NULL)) < 0)
7247     goto send_error;
7248
7249   /* we only perform redirect for the describe, currently */
7250   if (src->need_redirect) {
7251     /* close connection, we don't have to send a TEARDOWN yet, ignore the
7252      * result. */
7253     gst_rtsp_conninfo_close (src, &src->conninfo, TRUE);
7254
7255     gst_rtsp_message_unset (&request);
7256     gst_rtsp_message_unset (&response);
7257
7258     /* and now retry */
7259     goto restart;
7260   }
7261
7262   /* it could be that the DESCRIBE method was not implemented */
7263   if (!(src->methods & GST_RTSP_DESCRIBE))
7264     goto no_describe;
7265
7266   /* check if reply is SDP */
7267   gst_rtsp_message_get_header (&response, GST_RTSP_HDR_CONTENT_TYPE, &respcont,
7268       0);
7269   /* could not be set but since the request returned OK, we assume it
7270    * was SDP, else check it. */
7271   if (respcont) {
7272     if (g_ascii_strcasecmp (respcont, "application/sdp") != 0)
7273       goto wrong_content_type;
7274   }
7275
7276   /* get message body and parse as SDP */
7277   gst_rtsp_message_get_body (&response, &data, &size);
7278   if (data == NULL || size == 0)
7279     goto no_describe;
7280
7281   GST_DEBUG_OBJECT (src, "parse SDP...");
7282   gst_sdp_message_new (sdp);
7283   gst_sdp_message_parse_buffer (data, size, *sdp);
7284
7285   /* clean up any messages */
7286   gst_rtsp_message_unset (&request);
7287   gst_rtsp_message_unset (&response);
7288
7289   return res;
7290
7291   /* ERRORS */
7292 no_url:
7293   {
7294     GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
7295         ("No valid RTSP URL was provided"));
7296     goto cleanup_error;
7297   }
7298 connect_failed:
7299   {
7300     gchar *str = gst_rtsp_strresult (res);
7301
7302     if (res != GST_RTSP_EINTR) {
7303       GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
7304           ("Failed to connect. (%s)", str));
7305     } else {
7306       GST_WARNING_OBJECT (src, "connect interrupted");
7307     }
7308     g_free (str);
7309     goto cleanup_error;
7310   }
7311 create_request_failed:
7312   {
7313     gchar *str = gst_rtsp_strresult (res);
7314
7315     GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
7316         ("Could not create request. (%s)", str));
7317     g_free (str);
7318     goto cleanup_error;
7319   }
7320 send_error:
7321   {
7322     /* Don't post a message - the rtsp_send method will have
7323      * taken care of it because we passed NULL for the response code */
7324     goto cleanup_error;
7325   }
7326 methods_error:
7327   {
7328     /* error was posted */
7329     res = GST_RTSP_ERROR;
7330     goto cleanup_error;
7331   }
7332 wrong_content_type:
7333   {
7334     GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
7335         ("Server does not support SDP, got %s.", respcont));
7336     res = GST_RTSP_ERROR;
7337     goto cleanup_error;
7338   }
7339 no_describe:
7340   {
7341     GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
7342         ("Server can not provide an SDP."));
7343     res = GST_RTSP_ERROR;
7344     goto cleanup_error;
7345   }
7346 cleanup_error:
7347   {
7348     if (src->conninfo.connection) {
7349       GST_DEBUG_OBJECT (src, "free connection");
7350       gst_rtsp_conninfo_close (src, &src->conninfo, TRUE);
7351     }
7352     gst_rtsp_message_unset (&request);
7353     gst_rtsp_message_unset (&response);
7354     return res;
7355   }
7356 }
7357
7358 static GstRTSPResult
7359 gst_rtspsrc_open (GstRTSPSrc * src, gboolean async)
7360 {
7361   GstRTSPResult ret;
7362
7363   src->methods =
7364       GST_RTSP_SETUP | GST_RTSP_PLAY | GST_RTSP_PAUSE | GST_RTSP_TEARDOWN;
7365
7366   if (src->sdp == NULL) {
7367     if ((ret = gst_rtspsrc_retrieve_sdp (src, &src->sdp, async)) < 0)
7368       goto no_sdp;
7369   }
7370
7371   if ((ret = gst_rtspsrc_open_from_sdp (src, src->sdp, async)) < 0)
7372     goto open_failed;
7373
7374 done:
7375   if (async)
7376     gst_rtspsrc_loop_end_cmd (src, CMD_OPEN, ret);
7377
7378   return ret;
7379
7380   /* ERRORS */
7381 no_sdp:
7382   {
7383     GST_WARNING_OBJECT (src, "can't get sdp");
7384     src->open_error = TRUE;
7385     goto done;
7386   }
7387 open_failed:
7388   {
7389     GST_WARNING_OBJECT (src, "can't setup streaming from sdp");
7390     src->open_error = TRUE;
7391     goto done;
7392   }
7393 }
7394
7395 static GstRTSPResult
7396 gst_rtspsrc_close (GstRTSPSrc * src, gboolean async, gboolean only_close)
7397 {
7398   GstRTSPMessage request = { 0 };
7399   GstRTSPMessage response = { 0 };
7400   GstRTSPResult res = GST_RTSP_OK;
7401   GList *walk;
7402   const gchar *control;
7403
7404   GST_DEBUG_OBJECT (src, "TEARDOWN...");
7405
7406   gst_rtspsrc_set_state (src, GST_STATE_READY);
7407
7408   if (src->state < GST_RTSP_STATE_READY) {
7409     GST_DEBUG_OBJECT (src, "not ready, doing cleanup");
7410     goto close;
7411   }
7412
7413   if (only_close)
7414     goto close;
7415
7416   /* construct a control url */
7417   control = get_aggregate_control (src);
7418
7419   if (!(src->methods & (GST_RTSP_PLAY | GST_RTSP_TEARDOWN)))
7420     goto not_supported;
7421
7422   for (walk = src->streams; walk; walk = g_list_next (walk)) {
7423     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
7424     const gchar *setup_url;
7425     GstRTSPConnInfo *info;
7426
7427     /* try aggregate control first but do non-aggregate control otherwise */
7428     if (control)
7429       setup_url = control;
7430     else if ((setup_url = stream->conninfo.location) == NULL)
7431       continue;
7432
7433     if (src->conninfo.connection) {
7434       info = &src->conninfo;
7435     } else if (stream->conninfo.connection) {
7436       info = &stream->conninfo;
7437     } else {
7438       continue;
7439     }
7440     if (!info->connected)
7441       goto next;
7442
7443     /* do TEARDOWN */
7444     res =
7445         gst_rtspsrc_init_request (src, &request, GST_RTSP_TEARDOWN, setup_url);
7446     if (res < 0)
7447       goto create_request_failed;
7448
7449     if (async)
7450       GST_ELEMENT_PROGRESS (src, CONTINUE, "close", ("Closing stream"));
7451
7452     if ((res =
7453             gst_rtspsrc_send (src, info->connection, &request, &response,
7454                 NULL)) < 0)
7455       goto send_error;
7456
7457     /* FIXME, parse result? */
7458     gst_rtsp_message_unset (&request);
7459     gst_rtsp_message_unset (&response);
7460
7461   next:
7462     /* early exit when we did aggregate control */
7463     if (control)
7464       break;
7465   }
7466
7467 close:
7468   /* close connections */
7469   GST_DEBUG_OBJECT (src, "closing connection...");
7470   gst_rtsp_conninfo_close (src, &src->conninfo, TRUE);
7471   for (walk = src->streams; walk; walk = g_list_next (walk)) {
7472     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
7473     gst_rtsp_conninfo_close (src, &stream->conninfo, TRUE);
7474   }
7475
7476   /* cleanup */
7477   gst_rtspsrc_cleanup (src);
7478
7479   src->state = GST_RTSP_STATE_INVALID;
7480
7481   if (async)
7482     gst_rtspsrc_loop_end_cmd (src, CMD_CLOSE, res);
7483
7484   return res;
7485
7486   /* ERRORS */
7487 create_request_failed:
7488   {
7489     gchar *str = gst_rtsp_strresult (res);
7490
7491     GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
7492         ("Could not create request. (%s)", str));
7493     g_free (str);
7494     goto close;
7495   }
7496 send_error:
7497   {
7498     gchar *str = gst_rtsp_strresult (res);
7499
7500     gst_rtsp_message_unset (&request);
7501     if (res != GST_RTSP_EINTR) {
7502       GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
7503           ("Could not send message. (%s)", str));
7504     } else {
7505       GST_WARNING_OBJECT (src, "TEARDOWN interrupted");
7506     }
7507     g_free (str);
7508     goto close;
7509   }
7510 not_supported:
7511   {
7512     GST_DEBUG_OBJECT (src,
7513         "TEARDOWN and PLAY not supported, can't do TEARDOWN");
7514     goto close;
7515   }
7516 }
7517
7518 /* RTP-Info is of the format:
7519  *
7520  * url=<URL>;[seq=<seqbase>;rtptime=<timebase>] [, url=...]
7521  *
7522  * rtptime corresponds to the timestamp for the NPT time given in the header
7523  * seqbase corresponds to the next sequence number we received. This number
7524  * indicates the first seqnum after the seek and should be used to discard
7525  * packets that are from before the seek.
7526  */
7527 static gboolean
7528 gst_rtspsrc_parse_rtpinfo (GstRTSPSrc * src, gchar * rtpinfo)
7529 {
7530   gchar **infos;
7531   gint i, j;
7532
7533   GST_DEBUG_OBJECT (src, "parsing RTP-Info %s", rtpinfo);
7534
7535   infos = g_strsplit (rtpinfo, ",", 0);
7536   for (i = 0; infos[i]; i++) {
7537     gchar **fields;
7538     GstRTSPStream *stream;
7539     gint32 seqbase;
7540     gint64 timebase;
7541
7542     GST_DEBUG_OBJECT (src, "parsing info %s", infos[i]);
7543
7544     /* init values, types of seqbase and timebase are bigger than needed so we
7545      * can store -1 as uninitialized values */
7546     stream = NULL;
7547     seqbase = -1;
7548     timebase = -1;
7549
7550     /* parse url, find stream for url.
7551      * parse seq and rtptime. The seq number should be configured in the rtp
7552      * depayloader or session manager to detect gaps. Same for the rtptime, it
7553      * should be used to create an initial time newsegment. */
7554     fields = g_strsplit (infos[i], ";", 0);
7555     for (j = 0; fields[j]; j++) {
7556       GST_DEBUG_OBJECT (src, "parsing field %s", fields[j]);
7557       /* remove leading whitespace */
7558       fields[j] = g_strchug (fields[j]);
7559       if (g_str_has_prefix (fields[j], "url=")) {
7560         /* get the url and the stream */
7561         stream =
7562             find_stream (src, (fields[j] + 4), (gpointer) find_stream_by_setup);
7563       } else if (g_str_has_prefix (fields[j], "seq=")) {
7564         seqbase = atoi (fields[j] + 4);
7565       } else if (g_str_has_prefix (fields[j], "rtptime=")) {
7566         timebase = g_ascii_strtoll (fields[j] + 8, NULL, 10);
7567       }
7568     }
7569     g_strfreev (fields);
7570     /* now we need to store the values for the caps of the stream */
7571     if (stream != NULL) {
7572       GST_DEBUG_OBJECT (src,
7573           "found stream %p, setting: seqbase %d, timebase %" G_GINT64_FORMAT,
7574           stream, seqbase, timebase);
7575
7576       /* we have a stream, configure detected params */
7577       stream->seqbase = seqbase;
7578       stream->timebase = timebase;
7579     }
7580   }
7581   g_strfreev (infos);
7582
7583   return TRUE;
7584 }
7585
7586 static void
7587 gst_rtspsrc_handle_rtcp_interval (GstRTSPSrc * src, gchar * rtcp)
7588 {
7589   guint64 interval;
7590   GList *walk;
7591
7592   interval = strtoul (rtcp, NULL, 10);
7593   GST_DEBUG_OBJECT (src, "rtcp interval: %" G_GUINT64_FORMAT " ms", interval);
7594
7595   if (!interval)
7596     return;
7597
7598   interval *= GST_MSECOND;
7599
7600   for (walk = src->streams; walk; walk = g_list_next (walk)) {
7601     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
7602
7603     /* already (optionally) retrieved this when configuring manager */
7604     if (stream->session) {
7605       GObject *rtpsession = stream->session;
7606
7607       GST_DEBUG_OBJECT (src, "configure rtcp interval in session %p",
7608           rtpsession);
7609       g_object_set (rtpsession, "rtcp-min-interval", interval, NULL);
7610     }
7611   }
7612
7613   /* now it happens that (Xenon) server sending this may also provide bogus
7614    * RTCP SR sync data (i.e. with quite some jitter), so never mind those
7615    * and just use RTP-Info to sync */
7616   if (src->manager) {
7617     GObjectClass *klass;
7618
7619     klass = G_OBJECT_GET_CLASS (G_OBJECT (src->manager));
7620     if (g_object_class_find_property (klass, "rtcp-sync")) {
7621       GST_DEBUG_OBJECT (src, "configuring rtp sync method");
7622       g_object_set (src->manager, "rtcp-sync", RTCP_SYNC_RTP, NULL);
7623     }
7624   }
7625 }
7626
7627 static gdouble
7628 gst_rtspsrc_get_float (const gchar * dstr)
7629 {
7630   gchar s[G_ASCII_DTOSTR_BUF_SIZE] = { 0, };
7631
7632   /* canonicalise floating point string so we can handle float strings
7633    * in the form "24.930" or "24,930" irrespective of the current locale */
7634   g_strlcpy (s, dstr, sizeof (s));
7635   g_strdelimit (s, ",", '.');
7636   return g_ascii_strtod (s, NULL);
7637 }
7638
7639 static gchar *
7640 gen_range_header (GstRTSPSrc * src, GstSegment * segment)
7641 {
7642   gchar val_str[G_ASCII_DTOSTR_BUF_SIZE] = { 0, };
7643
7644   if (src->range && src->range->min.type == GST_RTSP_TIME_NOW) {
7645     g_strlcpy (val_str, "now", sizeof (val_str));
7646   } else {
7647     if (segment->position == 0) {
7648       g_strlcpy (val_str, "0", sizeof (val_str));
7649     } else {
7650       g_ascii_dtostr (val_str, sizeof (val_str),
7651           ((gdouble) segment->position) / GST_SECOND);
7652     }
7653   }
7654   return g_strdup_printf ("npt=%s-", val_str);
7655 }
7656
7657 static void
7658 clear_rtp_base (GstRTSPSrc * src, GstRTSPStream * stream)
7659 {
7660   guint i, len;
7661
7662   stream->timebase = -1;
7663   stream->seqbase = -1;
7664
7665   len = stream->ptmap->len;
7666   for (i = 0; i < len; i++) {
7667     PtMapItem *item = &g_array_index (stream->ptmap, PtMapItem, i);
7668     GstStructure *s;
7669
7670     if (item->caps == NULL)
7671       continue;
7672
7673     item->caps = gst_caps_make_writable (item->caps);
7674     s = gst_caps_get_structure (item->caps, 0);
7675     gst_structure_remove_fields (s, "clock-base", "seqnum-base", NULL);
7676   }
7677 }
7678
7679 static GstRTSPResult
7680 gst_rtspsrc_ensure_open (GstRTSPSrc * src, gboolean async)
7681 {
7682   GstRTSPResult res = GST_RTSP_OK;
7683
7684   if (src->state < GST_RTSP_STATE_READY) {
7685     res = GST_RTSP_ERROR;
7686     if (src->open_error) {
7687       GST_DEBUG_OBJECT (src, "the stream was in error");
7688       goto done;
7689     }
7690     if (async)
7691       gst_rtspsrc_loop_start_cmd (src, CMD_OPEN);
7692
7693     if ((res = gst_rtspsrc_open (src, async)) < 0) {
7694       GST_DEBUG_OBJECT (src, "failed to open stream");
7695       goto done;
7696     }
7697   }
7698
7699 done:
7700   return res;
7701 }
7702
7703 static GstRTSPResult
7704 gst_rtspsrc_play (GstRTSPSrc * src, GstSegment * segment, gboolean async)
7705 {
7706   GstRTSPMessage request = { 0 };
7707   GstRTSPMessage response = { 0 };
7708   GstRTSPResult res = GST_RTSP_OK;
7709   GList *walk;
7710   gchar *hval;
7711   gint hval_idx;
7712   const gchar *control;
7713
7714   GST_DEBUG_OBJECT (src, "PLAY...");
7715
7716   if ((res = gst_rtspsrc_ensure_open (src, async)) < 0)
7717     goto open_failed;
7718
7719   if (!(src->methods & GST_RTSP_PLAY))
7720     goto not_supported;
7721
7722   if (src->state == GST_RTSP_STATE_PLAYING)
7723     goto was_playing;
7724
7725   if (!src->conninfo.connection || !src->conninfo.connected)
7726     goto done;
7727
7728   /* send some dummy packets before we activate the receive in the
7729    * udp sources */
7730   gst_rtspsrc_send_dummy_packets (src);
7731
7732   /* require new SR packets */
7733   if (src->manager)
7734     g_signal_emit_by_name (src->manager, "reset-sync", NULL);
7735
7736   /* construct a control url */
7737   control = get_aggregate_control (src);
7738
7739   for (walk = src->streams; walk; walk = g_list_next (walk)) {
7740     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
7741     const gchar *setup_url;
7742     GstRTSPConnection *conn;
7743
7744     /* try aggregate control first but do non-aggregate control otherwise */
7745     if (control)
7746       setup_url = control;
7747     else if ((setup_url = stream->conninfo.location) == NULL)
7748       continue;
7749
7750     if (src->conninfo.connection) {
7751       conn = src->conninfo.connection;
7752     } else if (stream->conninfo.connection) {
7753       conn = stream->conninfo.connection;
7754     } else {
7755       continue;
7756     }
7757
7758     /* do play */
7759     res = gst_rtspsrc_init_request (src, &request, GST_RTSP_PLAY, setup_url);
7760     if (res < 0)
7761       goto create_request_failed;
7762
7763     if (src->need_range) {
7764       hval = gen_range_header (src, segment);
7765
7766       gst_rtsp_message_take_header (&request, GST_RTSP_HDR_RANGE, hval);
7767
7768       /* store the newsegment event so it can be sent from the streaming thread. */
7769       src->need_segment = TRUE;
7770     }
7771
7772     if (segment->rate != 1.0) {
7773       gchar hval[G_ASCII_DTOSTR_BUF_SIZE];
7774
7775       g_ascii_dtostr (hval, sizeof (hval), segment->rate);
7776       if (src->skip)
7777         gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SCALE, hval);
7778       else
7779         gst_rtsp_message_add_header (&request, GST_RTSP_HDR_SPEED, hval);
7780     }
7781
7782     if (async)
7783       GST_ELEMENT_PROGRESS (src, CONTINUE, "request", ("Sending PLAY request"));
7784
7785     if ((res = gst_rtspsrc_send (src, conn, &request, &response, NULL)) < 0)
7786       goto send_error;
7787
7788     /* seek may have silently failed as it is not supported */
7789     if (!(src->methods & GST_RTSP_PLAY)) {
7790       GST_DEBUG_OBJECT (src, "PLAY Range not supported; re-enable PLAY");
7791       /* obviously it is supported as we made it here */
7792       src->methods |= GST_RTSP_PLAY;
7793       src->seekable = FALSE;
7794       /* but there is nothing to parse in the response,
7795        * so convey we have no idea and not to expect anything particular */
7796       clear_rtp_base (src, stream);
7797       if (control) {
7798         GList *run;
7799
7800         /* need to do for all streams */
7801         for (run = src->streams; run; run = g_list_next (run))
7802           clear_rtp_base (src, (GstRTSPStream *) run->data);
7803       }
7804       /* NOTE the above also disables npt based eos detection */
7805       /* and below forces position to 0,
7806        * which is visible feedback we lost the plot */
7807       segment->start = segment->position = src->last_pos;
7808     }
7809
7810     gst_rtsp_message_unset (&request);
7811
7812     /* parse RTP npt field. This is the current position in the stream (Normal
7813      * Play Time) and should be put in the NEWSEGMENT position field. */
7814     if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RANGE, &hval,
7815             0) == GST_RTSP_OK)
7816       gst_rtspsrc_parse_range (src, hval, segment);
7817
7818     /* assume 1.0 rate now, overwrite when the SCALE or SPEED headers are present. */
7819     segment->rate = 1.0;
7820
7821     /* parse Speed header. This is the intended playback rate of the stream
7822      * and should be put in the NEWSEGMENT rate field. */
7823     if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_SPEED, &hval,
7824             0) == GST_RTSP_OK) {
7825       segment->rate = gst_rtspsrc_get_float (hval);
7826     } else if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_SCALE,
7827             &hval, 0) == GST_RTSP_OK) {
7828       segment->rate = gst_rtspsrc_get_float (hval);
7829     }
7830
7831     /* parse the RTP-Info header field (if ANY) to get the base seqnum and timestamp
7832      * for the RTP packets. If this is not present, we assume all starts from 0...
7833      * This is info for the RTP session manager that we pass to it in caps. */
7834     hval_idx = 0;
7835     while (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RTP_INFO,
7836             &hval, hval_idx++) == GST_RTSP_OK)
7837       gst_rtspsrc_parse_rtpinfo (src, hval);
7838
7839     /* some servers indicate RTCP parameters in PLAY response,
7840      * rather than properly in SDP */
7841     if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_RTCP_INTERVAL,
7842             &hval, 0) == GST_RTSP_OK)
7843       gst_rtspsrc_handle_rtcp_interval (src, hval);
7844
7845     gst_rtsp_message_unset (&response);
7846
7847     /* early exit when we did aggregate control */
7848     if (control)
7849       break;
7850   }
7851   /* configure the caps of the streams after we parsed all headers. Only reset
7852    * the manager object when we set a new Range header (we did a seek) */
7853   gst_rtspsrc_configure_caps (src, segment, src->need_range);
7854
7855   /* set to PLAYING after we have configured the caps, otherwise we
7856    * might end up calling request_key (with SRTP) while caps are still
7857    * being configured. */
7858   gst_rtspsrc_set_state (src, GST_STATE_PLAYING);
7859
7860   /* set again when needed */
7861   src->need_range = FALSE;
7862
7863   src->running = TRUE;
7864   src->base_time = -1;
7865   src->state = GST_RTSP_STATE_PLAYING;
7866
7867   /* mark discont */
7868   GST_DEBUG_OBJECT (src, "mark DISCONT, we did a seek to another position");
7869   for (walk = src->streams; walk; walk = g_list_next (walk)) {
7870     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
7871     stream->discont = TRUE;
7872   }
7873
7874 done:
7875   if (async)
7876     gst_rtspsrc_loop_end_cmd (src, CMD_PLAY, res);
7877
7878   return res;
7879
7880   /* ERRORS */
7881 open_failed:
7882   {
7883     GST_DEBUG_OBJECT (src, "failed to open stream");
7884     goto done;
7885   }
7886 not_supported:
7887   {
7888     GST_DEBUG_OBJECT (src, "PLAY is not supported");
7889     goto done;
7890   }
7891 was_playing:
7892   {
7893     GST_DEBUG_OBJECT (src, "we were already PLAYING");
7894     goto done;
7895   }
7896 create_request_failed:
7897   {
7898     gchar *str = gst_rtsp_strresult (res);
7899
7900     GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
7901         ("Could not create request. (%s)", str));
7902     g_free (str);
7903     goto done;
7904   }
7905 send_error:
7906   {
7907     gchar *str = gst_rtsp_strresult (res);
7908
7909     gst_rtsp_message_unset (&request);
7910     if (res != GST_RTSP_EINTR) {
7911       GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
7912           ("Could not send message. (%s)", str));
7913     } else {
7914       GST_WARNING_OBJECT (src, "PLAY interrupted");
7915     }
7916     g_free (str);
7917     goto done;
7918   }
7919 }
7920
7921 static GstRTSPResult
7922 gst_rtspsrc_pause (GstRTSPSrc * src, gboolean async)
7923 {
7924   GstRTSPResult res = GST_RTSP_OK;
7925   GstRTSPMessage request = { 0 };
7926   GstRTSPMessage response = { 0 };
7927   GList *walk;
7928   const gchar *control;
7929
7930   GST_DEBUG_OBJECT (src, "PAUSE...");
7931
7932   if ((res = gst_rtspsrc_ensure_open (src, async)) < 0)
7933     goto open_failed;
7934
7935   if (!(src->methods & GST_RTSP_PAUSE))
7936     goto not_supported;
7937
7938   if (src->state == GST_RTSP_STATE_READY)
7939     goto was_paused;
7940
7941   if (!src->conninfo.connection || !src->conninfo.connected)
7942     goto no_connection;
7943
7944   /* construct a control url */
7945   control = get_aggregate_control (src);
7946
7947   /* loop over the streams. We might exit the loop early when we could do an
7948    * aggregate control */
7949   for (walk = src->streams; walk; walk = g_list_next (walk)) {
7950     GstRTSPStream *stream = (GstRTSPStream *) walk->data;
7951     GstRTSPConnection *conn;
7952     const gchar *setup_url;
7953
7954     /* try aggregate control first but do non-aggregate control otherwise */
7955     if (control)
7956       setup_url = control;
7957     else if ((setup_url = stream->conninfo.location) == NULL)
7958       continue;
7959
7960     if (src->conninfo.connection) {
7961       conn = src->conninfo.connection;
7962     } else if (stream->conninfo.connection) {
7963       conn = stream->conninfo.connection;
7964     } else {
7965       continue;
7966     }
7967
7968     if (async)
7969       GST_ELEMENT_PROGRESS (src, CONTINUE, "request",
7970           ("Sending PAUSE request"));
7971
7972     if ((res =
7973             gst_rtspsrc_init_request (src, &request, GST_RTSP_PAUSE,
7974                 setup_url)) < 0)
7975       goto create_request_failed;
7976
7977     if ((res = gst_rtspsrc_send (src, conn, &request, &response, NULL)) < 0)
7978       goto send_error;
7979
7980     gst_rtsp_message_unset (&request);
7981     gst_rtsp_message_unset (&response);
7982
7983     /* exit early when we did agregate control */
7984     if (control)
7985       break;
7986   }
7987
7988   /* change element states now */
7989   gst_rtspsrc_set_state (src, GST_STATE_PAUSED);
7990
7991 no_connection:
7992   src->state = GST_RTSP_STATE_READY;
7993
7994 done:
7995   if (async)
7996     gst_rtspsrc_loop_end_cmd (src, CMD_PAUSE, res);
7997
7998   return res;
7999
8000   /* ERRORS */
8001 open_failed:
8002   {
8003     GST_DEBUG_OBJECT (src, "failed to open stream");
8004     goto done;
8005   }
8006 not_supported:
8007   {
8008     GST_DEBUG_OBJECT (src, "PAUSE is not supported");
8009     goto done;
8010   }
8011 was_paused:
8012   {
8013     GST_DEBUG_OBJECT (src, "we were already PAUSED");
8014     goto done;
8015   }
8016 create_request_failed:
8017   {
8018     gchar *str = gst_rtsp_strresult (res);
8019
8020     GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL),
8021         ("Could not create request. (%s)", str));
8022     g_free (str);
8023     goto done;
8024   }
8025 send_error:
8026   {
8027     gchar *str = gst_rtsp_strresult (res);
8028
8029     gst_rtsp_message_unset (&request);
8030     if (res != GST_RTSP_EINTR) {
8031       GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
8032           ("Could not send message. (%s)", str));
8033     } else {
8034       GST_WARNING_OBJECT (src, "PAUSE interrupted");
8035     }
8036     g_free (str);
8037     goto done;
8038   }
8039 }
8040
8041 static void
8042 gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message)
8043 {
8044   GstRTSPSrc *rtspsrc;
8045
8046   rtspsrc = GST_RTSPSRC (bin);
8047
8048   switch (GST_MESSAGE_TYPE (message)) {
8049     case GST_MESSAGE_EOS:
8050       gst_message_unref (message);
8051       break;
8052     case GST_MESSAGE_ELEMENT:
8053     {
8054       const GstStructure *s = gst_message_get_structure (message);
8055
8056       if (gst_structure_has_name (s, "GstUDPSrcTimeout")) {
8057         gboolean ignore_timeout;
8058
8059         GST_DEBUG_OBJECT (bin, "timeout on UDP port");
8060
8061         GST_OBJECT_LOCK (rtspsrc);
8062         ignore_timeout = rtspsrc->ignore_timeout;
8063         rtspsrc->ignore_timeout = TRUE;
8064         GST_OBJECT_UNLOCK (rtspsrc);
8065
8066         /* we only act on the first udp timeout message, others are irrelevant
8067          * and can be ignored. */
8068         if (!ignore_timeout)
8069           gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_RECONNECT, CMD_LOOP);
8070         /* eat and free */
8071         gst_message_unref (message);
8072         return;
8073       }
8074       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
8075       break;
8076     }
8077     case GST_MESSAGE_ERROR:
8078     {
8079       GstObject *udpsrc;
8080       GstRTSPStream *stream;
8081       GstFlowReturn ret;
8082
8083       udpsrc = GST_MESSAGE_SRC (message);
8084
8085       GST_DEBUG_OBJECT (rtspsrc, "got error from %s",
8086           GST_ELEMENT_NAME (udpsrc));
8087
8088       stream = find_stream (rtspsrc, udpsrc, (gpointer) find_stream_by_udpsrc);
8089       if (!stream)
8090         goto forward;
8091
8092       /* we ignore the RTCP udpsrc */
8093       if (stream->udpsrc[1] == GST_ELEMENT_CAST (udpsrc))
8094         goto done;
8095
8096       /* if we get error messages from the udp sources, that's not a problem as
8097        * long as not all of them error out. We also don't really know what the
8098        * problem is, the message does not give enough detail... */
8099       ret = gst_rtspsrc_combine_flows (rtspsrc, stream, GST_FLOW_NOT_LINKED);
8100       GST_DEBUG_OBJECT (rtspsrc, "combined flows: %s", gst_flow_get_name (ret));
8101       if (ret != GST_FLOW_OK)
8102         goto forward;
8103
8104     done:
8105       gst_message_unref (message);
8106       break;
8107
8108     forward:
8109       /* fatal but not our message, forward */
8110       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
8111       break;
8112     }
8113     default:
8114     {
8115       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
8116       break;
8117     }
8118   }
8119 }
8120
8121 /* the thread where everything happens */
8122 static void
8123 gst_rtspsrc_thread (GstRTSPSrc * src)
8124 {
8125   gint cmd;
8126
8127   GST_OBJECT_LOCK (src);
8128   cmd = src->pending_cmd;
8129   if (cmd == CMD_RECONNECT || cmd == CMD_PLAY || cmd == CMD_PAUSE
8130       || cmd == CMD_LOOP || cmd == CMD_OPEN)
8131     src->pending_cmd = CMD_LOOP;
8132   else
8133     src->pending_cmd = CMD_WAIT;
8134   GST_DEBUG_OBJECT (src, "got command %s", cmd_to_string (cmd));
8135
8136   /* we got the message command, so ensure communication is possible again */
8137   gst_rtspsrc_connection_flush (src, FALSE);
8138
8139   src->busy_cmd = cmd;
8140   GST_OBJECT_UNLOCK (src);
8141
8142   switch (cmd) {
8143     case CMD_OPEN:
8144       gst_rtspsrc_open (src, TRUE);
8145       break;
8146     case CMD_PLAY:
8147       gst_rtspsrc_play (src, &src->segment, TRUE);
8148       break;
8149     case CMD_PAUSE:
8150       gst_rtspsrc_pause (src, TRUE);
8151       break;
8152     case CMD_CLOSE:
8153       gst_rtspsrc_close (src, TRUE, FALSE);
8154       break;
8155     case CMD_LOOP:
8156       gst_rtspsrc_loop (src);
8157       break;
8158     case CMD_RECONNECT:
8159       gst_rtspsrc_reconnect (src, FALSE);
8160       break;
8161     default:
8162       break;
8163   }
8164
8165   GST_OBJECT_LOCK (src);
8166   /* and go back to sleep */
8167   if (src->pending_cmd == CMD_WAIT) {
8168     if (src->task)
8169       gst_task_pause (src->task);
8170   }
8171   /* reset waiting */
8172   src->busy_cmd = CMD_WAIT;
8173   GST_OBJECT_UNLOCK (src);
8174 }
8175
8176 static gboolean
8177 gst_rtspsrc_start (GstRTSPSrc * src)
8178 {
8179   GST_DEBUG_OBJECT (src, "starting");
8180
8181   GST_OBJECT_LOCK (src);
8182
8183   src->pending_cmd = CMD_WAIT;
8184
8185   if (src->task == NULL) {
8186     src->task = gst_task_new ((GstTaskFunction) gst_rtspsrc_thread, src, NULL);
8187     if (src->task == NULL)
8188       goto task_error;
8189
8190     gst_task_set_lock (src->task, GST_RTSP_STREAM_GET_LOCK (src));
8191   }
8192   GST_OBJECT_UNLOCK (src);
8193
8194   return TRUE;
8195
8196   /* ERRORS */
8197 task_error:
8198   {
8199     GST_OBJECT_UNLOCK (src);
8200     GST_ERROR_OBJECT (src, "failed to create task");
8201     return FALSE;
8202   }
8203 }
8204
8205 static gboolean
8206 gst_rtspsrc_stop (GstRTSPSrc * src)
8207 {
8208   GstTask *task;
8209
8210   GST_DEBUG_OBJECT (src, "stopping");
8211
8212   /* also cancels pending task */
8213   gst_rtspsrc_loop_send_cmd (src, CMD_WAIT, CMD_ALL);
8214
8215   GST_OBJECT_LOCK (src);
8216   if ((task = src->task)) {
8217     src->task = NULL;
8218     GST_OBJECT_UNLOCK (src);
8219
8220     gst_task_stop (task);
8221
8222     /* make sure it is not running */
8223     GST_RTSP_STREAM_LOCK (src);
8224     GST_RTSP_STREAM_UNLOCK (src);
8225
8226     /* now wait for the task to finish */
8227     gst_task_join (task);
8228
8229     /* and free the task */
8230     gst_object_unref (GST_OBJECT (task));
8231
8232     GST_OBJECT_LOCK (src);
8233   }
8234   GST_OBJECT_UNLOCK (src);
8235
8236   /* ensure synchronously all is closed and clean */
8237   gst_rtspsrc_close (src, FALSE, TRUE);
8238
8239   return TRUE;
8240 }
8241
8242 static GstStateChangeReturn
8243 gst_rtspsrc_change_state (GstElement * element, GstStateChange transition)
8244 {
8245   GstRTSPSrc *rtspsrc;
8246   GstStateChangeReturn ret;
8247
8248   rtspsrc = GST_RTSPSRC (element);
8249
8250   switch (transition) {
8251     case GST_STATE_CHANGE_NULL_TO_READY:
8252       if (!gst_rtspsrc_start (rtspsrc))
8253         goto start_failed;
8254       break;
8255     case GST_STATE_CHANGE_READY_TO_PAUSED:
8256       /* init some state */
8257       rtspsrc->cur_protocols = rtspsrc->protocols;
8258       /* first attempt, don't ignore timeouts */
8259       rtspsrc->ignore_timeout = FALSE;
8260       rtspsrc->open_error = FALSE;
8261       gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_OPEN, 0);
8262       break;
8263     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
8264       set_manager_buffer_mode (rtspsrc);
8265       /* fall-through */
8266     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
8267       /* unblock the tcp tasks and make the loop waiting */
8268       if (gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_WAIT, CMD_LOOP)) {
8269         /* make sure it is waiting before we send PAUSE or PLAY below */
8270         GST_RTSP_STREAM_LOCK (rtspsrc);
8271         GST_RTSP_STREAM_UNLOCK (rtspsrc);
8272       }
8273       break;
8274     case GST_STATE_CHANGE_PAUSED_TO_READY:
8275       break;
8276     default:
8277       break;
8278   }
8279
8280   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
8281   if (ret == GST_STATE_CHANGE_FAILURE)
8282     goto done;
8283
8284   switch (transition) {
8285     case GST_STATE_CHANGE_NULL_TO_READY:
8286       ret = GST_STATE_CHANGE_SUCCESS;
8287       break;
8288     case GST_STATE_CHANGE_READY_TO_PAUSED:
8289       ret = GST_STATE_CHANGE_NO_PREROLL;
8290       break;
8291     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
8292       gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_PLAY, 0);
8293       ret = GST_STATE_CHANGE_SUCCESS;
8294       break;
8295     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
8296       /* send pause request and keep the idle task around */
8297       gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_PAUSE, CMD_LOOP);
8298       ret = GST_STATE_CHANGE_NO_PREROLL;
8299       break;
8300     case GST_STATE_CHANGE_PAUSED_TO_READY:
8301       gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_CLOSE, CMD_PAUSE);
8302       ret = GST_STATE_CHANGE_SUCCESS;
8303       break;
8304     case GST_STATE_CHANGE_READY_TO_NULL:
8305       gst_rtspsrc_stop (rtspsrc);
8306       ret = GST_STATE_CHANGE_SUCCESS;
8307       break;
8308     default:
8309       break;
8310   }
8311
8312 done:
8313   return ret;
8314
8315 start_failed:
8316   {
8317     GST_DEBUG_OBJECT (rtspsrc, "start failed");
8318     return GST_STATE_CHANGE_FAILURE;
8319   }
8320 }
8321
8322 static gboolean
8323 gst_rtspsrc_send_event (GstElement * element, GstEvent * event)
8324 {
8325   gboolean res;
8326   GstRTSPSrc *rtspsrc;
8327
8328   rtspsrc = GST_RTSPSRC (element);
8329
8330   if (GST_EVENT_IS_DOWNSTREAM (event)) {
8331     res = gst_rtspsrc_push_event (rtspsrc, event);
8332   } else {
8333     res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
8334   }
8335
8336   return res;
8337 }
8338
8339
8340 /*** GSTURIHANDLER INTERFACE *************************************************/
8341
8342 static GstURIType
8343 gst_rtspsrc_uri_get_type (GType type)
8344 {
8345   return GST_URI_SRC;
8346 }
8347
8348 static const gchar *const *
8349 gst_rtspsrc_uri_get_protocols (GType type)
8350 {
8351   static const gchar *protocols[] =
8352       { "rtsp", "rtspu", "rtspt", "rtsph", "rtsp-sdp",
8353     "rtsps", "rtspsu", "rtspst", "rtspsh", NULL
8354   };
8355
8356   return protocols;
8357 }
8358
8359 static gchar *
8360 gst_rtspsrc_uri_get_uri (GstURIHandler * handler)
8361 {
8362   GstRTSPSrc *src = GST_RTSPSRC (handler);
8363
8364   /* FIXME: make thread-safe */
8365   return g_strdup (src->conninfo.location);
8366 }
8367
8368 static gboolean
8369 gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri,
8370     GError ** error)
8371 {
8372   GstRTSPSrc *src;
8373   GstRTSPResult res;
8374   GstSDPResult sres;
8375   GstRTSPUrl *newurl = NULL;
8376   GstSDPMessage *sdp = NULL;
8377
8378   src = GST_RTSPSRC (handler);
8379
8380   /* same URI, we're fine */
8381   if (src->conninfo.location && uri && !strcmp (uri, src->conninfo.location))
8382     goto was_ok;
8383
8384   if (g_str_has_prefix (uri, "rtsp-sdp://")) {
8385     sres = gst_sdp_message_new (&sdp);
8386     if (sres < 0)
8387       goto sdp_failed;
8388
8389     GST_DEBUG_OBJECT (src, "parsing SDP message");
8390     sres = gst_sdp_message_parse_uri (uri, sdp);
8391     if (sres < 0)
8392       goto invalid_sdp;
8393   } else {
8394     /* try to parse */
8395     GST_DEBUG_OBJECT (src, "parsing URI");
8396     if ((res = gst_rtsp_url_parse (uri, &newurl)) < 0)
8397       goto parse_error;
8398   }
8399
8400   /* if worked, free previous and store new url object along with the original
8401    * location. */
8402   GST_DEBUG_OBJECT (src, "configuring URI");
8403   g_free (src->conninfo.location);
8404   src->conninfo.location = g_strdup (uri);
8405   gst_rtsp_url_free (src->conninfo.url);
8406   src->conninfo.url = newurl;
8407   g_free (src->conninfo.url_str);
8408   if (newurl)
8409     src->conninfo.url_str = gst_rtsp_url_get_request_uri (src->conninfo.url);
8410   else
8411     src->conninfo.url_str = NULL;
8412
8413   if (src->sdp)
8414     gst_sdp_message_free (src->sdp);
8415   src->sdp = sdp;
8416   src->from_sdp = sdp != NULL;
8417
8418   GST_DEBUG_OBJECT (src, "set uri: %s", GST_STR_NULL (uri));
8419   GST_DEBUG_OBJECT (src, "request uri is: %s",
8420       GST_STR_NULL (src->conninfo.url_str));
8421
8422   return TRUE;
8423
8424   /* Special cases */
8425 was_ok:
8426   {
8427     GST_DEBUG_OBJECT (src, "URI was ok: '%s'", GST_STR_NULL (uri));
8428     return TRUE;
8429   }
8430 sdp_failed:
8431   {
8432     GST_ERROR_OBJECT (src, "Could not create new SDP (%d)", sres);
8433     g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
8434         "Could not create SDP");
8435     return FALSE;
8436   }
8437 invalid_sdp:
8438   {
8439     GST_ERROR_OBJECT (src, "Not a valid SDP (%d) '%s'", sres,
8440         GST_STR_NULL (uri));
8441     gst_sdp_message_free (sdp);
8442     g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
8443         "Invalid SDP");
8444     return FALSE;
8445   }
8446 parse_error:
8447   {
8448     GST_ERROR_OBJECT (src, "Not a valid RTSP url '%s' (%d)",
8449         GST_STR_NULL (uri), res);
8450     g_set_error_literal (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
8451         "Invalid RTSP URI");
8452     return FALSE;
8453   }
8454 }
8455
8456 static void
8457 gst_rtspsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
8458 {
8459   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
8460
8461   iface->get_type = gst_rtspsrc_uri_get_type;
8462   iface->get_protocols = gst_rtspsrc_uri_get_protocols;
8463   iface->get_uri = gst_rtspsrc_uri_get_uri;
8464   iface->set_uri = gst_rtspsrc_uri_set_uri;
8465 }