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