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