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