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