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