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