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