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