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