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