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