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