10bbedab6b93655dc16e1cf332b1c4ebd98a49c5
[platform/upstream/gstreamer.git] / gst / rtsp / gstrtspsrc.c
1 /* GStreamer
2  * Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 /**
20  * SECTION:element-rtspsrc
21  *
22  * <refsect2>
23  * <para>
24  * Makes a connection to an RTSP server and read the data.
25  * rtspsrc strictly follows RFC 2326 and therefore does not (yet) support
26  * RealMedia/Quicktime/Microsoft extensions.
27  * </para>
28  * <para>
29  * RTSP supports transport over TCP or UDP in unicast or multicast mode. By
30  * default rtspsrc will negotiate a connection in the following order:
31  * UDP unicast/UDP multicast/TCP. The order cannot be changed but the allowed
32  * protocols can be controlled with the "protocols" property.
33  * </para>
34  * <para>
35  * rtspsrc currently understands SDP as the format of the session description.
36  * For each stream listed in the SDP a new rtp_stream%d pad will be created
37  * with caps derived from the SDP media description. This is a caps of mime type
38  * "application/x-rtp" that can be connected to any available rtp depayloader
39  * element. 
40  * </para>
41  * <para>
42  * rtspsrc will internally instantiate an RTP session manager element
43  * that will handle the RTCP messages to and from the server, jitter removal,
44  * packet reordering along with providing a clock for the pipeline. 
45  * This feature is however currently not yet implemented.
46  * </para>
47  * <para>
48  * rtspsrc acts like a live source and will therefore only generate data in the 
49  * PLAYING state.
50  * </para>
51  * <title>Example launch line</title>
52  * <para>
53  * <programlisting>
54  * gst-launch rtspsrc location=rtsp://some.server/url ! fakesink
55  * </programlisting>
56  * Establish a connection to an RTSP server and send the stream to a fakesink.
57  * </para>
58  * </refsect2>
59  *
60  * Last reviewed on 2006-06-20 (0.10.4)
61  */
62
63 #ifdef HAVE_CONFIG_H
64 #include "config.h"
65 #endif
66
67 #include <unistd.h>
68 #include <string.h>
69
70 #include "gstrtspsrc.h"
71 #include "sdp.h"
72
73 GST_DEBUG_CATEGORY_STATIC (rtspsrc_debug);
74 #define GST_CAT_DEFAULT (rtspsrc_debug)
75
76 /* elementfactory information */
77 static const GstElementDetails gst_rtspsrc_details =
78 GST_ELEMENT_DETAILS ("RTSP packet receiver",
79     "Source/Network",
80     "Receive data over the network via RTSP (RFC 2326)",
81     "Wim Taymans <wim@fluendo.com>");
82
83 static GstStaticPadTemplate rtptemplate =
84 GST_STATIC_PAD_TEMPLATE ("rtp_stream%d",
85     GST_PAD_SRC,
86     GST_PAD_SOMETIMES,
87     GST_STATIC_CAPS_ANY);
88
89 static GstStaticPadTemplate rtcptemplate =
90 GST_STATIC_PAD_TEMPLATE ("rtcp_stream%d",
91     GST_PAD_SRC,
92     GST_PAD_SOMETIMES,
93     GST_STATIC_CAPS_ANY);
94
95 enum
96 {
97   /* FILL ME */
98   LAST_SIGNAL
99 };
100
101 #define DEFAULT_LOCATION        NULL
102 #define DEFAULT_PROTOCOLS       GST_RTSP_PROTO_UDP_UNICAST | GST_RTSP_PROTO_UDP_MULTICAST | GST_RTSP_PROTO_TCP
103 #define DEFAULT_DEBUG           FALSE
104 #define DEFAULT_RETRY           20
105
106 enum
107 {
108   PROP_0,
109   PROP_LOCATION,
110   PROP_PROTOCOLS,
111   PROP_DEBUG,
112   PROP_RETRY,
113   /* FILL ME */
114 };
115
116 #define GST_TYPE_RTSP_PROTO (gst_rtsp_proto_get_type())
117 static GType
118 gst_rtsp_proto_get_type (void)
119 {
120   static GType rtsp_proto_type = 0;
121   static const GFlagsValue rtsp_proto[] = {
122     {GST_RTSP_PROTO_UDP_UNICAST, "UDP Unicast", "UDP unicast mode"},
123     {GST_RTSP_PROTO_UDP_MULTICAST, "UDP Multicast", "UDP Multicast mode"},
124     {GST_RTSP_PROTO_TCP, "TCP", "TCP interleaved mode"},
125     {0, NULL, NULL},
126   };
127
128   if (!rtsp_proto_type) {
129     rtsp_proto_type = g_flags_register_static ("GstRTSPProto", rtsp_proto);
130   }
131   return rtsp_proto_type;
132 }
133
134
135 static void gst_rtspsrc_base_init (gpointer g_class);
136 static void gst_rtspsrc_class_init (GstRTSPSrc * klass);
137 static void gst_rtspsrc_init (GstRTSPSrc * rtspsrc);
138 static void gst_rtspsrc_finalize (GObject * object);
139
140 static void gst_rtspsrc_uri_handler_init (gpointer g_iface,
141     gpointer iface_data);
142
143 static GstStateChangeReturn gst_rtspsrc_change_state (GstElement * element,
144     GstStateChange transition);
145
146 static void gst_rtspsrc_set_property (GObject * object, guint prop_id,
147     const GValue * value, GParamSpec * pspec);
148 static void gst_rtspsrc_get_property (GObject * object, guint prop_id,
149     GValue * value, GParamSpec * pspec);
150
151 static void gst_rtspsrc_loop (GstRTSPSrc * src);
152
153 static GstElementClass *parent_class = NULL;
154
155 /*static guint gst_rtspsrc_signals[LAST_SIGNAL] = { 0 }; */
156
157 GType
158 gst_rtspsrc_get_type (void)
159 {
160   static GType rtspsrc_type = 0;
161
162   if (!rtspsrc_type) {
163     static const GTypeInfo rtspsrc_info = {
164       sizeof (GstRTSPSrcClass),
165       gst_rtspsrc_base_init,
166       NULL,
167       (GClassInitFunc) gst_rtspsrc_class_init,
168       NULL,
169       NULL,
170       sizeof (GstRTSPSrc),
171       0,
172       (GInstanceInitFunc) gst_rtspsrc_init,
173       NULL
174     };
175     static const GInterfaceInfo urihandler_info = {
176       gst_rtspsrc_uri_handler_init,
177       NULL,
178       NULL
179     };
180
181     GST_DEBUG_CATEGORY_INIT (rtspsrc_debug, "rtspsrc", 0, "RTSP src");
182
183     rtspsrc_type =
184         g_type_register_static (GST_TYPE_ELEMENT, "GstRTSPSrc", &rtspsrc_info,
185         0);
186
187     g_type_add_interface_static (rtspsrc_type, GST_TYPE_URI_HANDLER,
188         &urihandler_info);
189   }
190   return rtspsrc_type;
191 }
192
193 static void
194 gst_rtspsrc_base_init (gpointer g_class)
195 {
196   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
197
198   gst_element_class_add_pad_template (element_class,
199       gst_static_pad_template_get (&rtptemplate));
200   gst_element_class_add_pad_template (element_class,
201       gst_static_pad_template_get (&rtcptemplate));
202
203   gst_element_class_set_details (element_class, &gst_rtspsrc_details);
204 }
205
206 static void
207 gst_rtspsrc_class_init (GstRTSPSrc * klass)
208 {
209   GObjectClass *gobject_class;
210   GstElementClass *gstelement_class;
211
212   gobject_class = (GObjectClass *) klass;
213   gstelement_class = (GstElementClass *) klass;
214
215   parent_class = g_type_class_peek_parent (klass);
216
217   gobject_class->set_property = gst_rtspsrc_set_property;
218   gobject_class->get_property = gst_rtspsrc_get_property;
219
220   gobject_class->finalize = gst_rtspsrc_finalize;
221
222   g_object_class_install_property (gobject_class, PROP_LOCATION,
223       g_param_spec_string ("location", "RTSP Location",
224           "Location of the RTSP url to read",
225           DEFAULT_LOCATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
226
227   g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
228       g_param_spec_flags ("protocols", "Protocols", "Allowed protocols",
229           GST_TYPE_RTSP_PROTO, DEFAULT_PROTOCOLS,
230           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
231
232   g_object_class_install_property (gobject_class, PROP_DEBUG,
233       g_param_spec_boolean ("debug", "Debug",
234           "Dump request and response messages to stdout",
235           DEFAULT_DEBUG, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
236
237   g_object_class_install_property (gobject_class, PROP_RETRY,
238       g_param_spec_uint ("retry", "Retry",
239           "Max number of retries when allocating RTP ports.",
240           0, G_MAXUINT16, DEFAULT_RETRY,
241           G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
242
243   gstelement_class->change_state = gst_rtspsrc_change_state;
244 }
245
246 static void
247 gst_rtspsrc_init (GstRTSPSrc * src)
248 {
249   src->stream_rec_lock = g_new (GStaticRecMutex, 1);
250   g_static_rec_mutex_init (src->stream_rec_lock);
251 }
252
253 static void
254 gst_rtspsrc_finalize (GObject * object)
255 {
256   GstRTSPSrc *rtspsrc;
257
258   rtspsrc = GST_RTSPSRC (object);
259
260   g_static_rec_mutex_free (rtspsrc->stream_rec_lock);
261   g_free (rtspsrc->stream_rec_lock);
262
263   G_OBJECT_CLASS (parent_class)->finalize (object);
264 }
265
266 static void
267 gst_rtspsrc_set_property (GObject * object, guint prop_id, const GValue * value,
268     GParamSpec * pspec)
269 {
270   GstRTSPSrc *rtspsrc;
271
272   rtspsrc = GST_RTSPSRC (object);
273
274   switch (prop_id) {
275     case PROP_LOCATION:
276       g_free (rtspsrc->location);
277       rtspsrc->location = g_value_dup_string (value);
278       break;
279     case PROP_PROTOCOLS:
280       rtspsrc->protocols = g_value_get_flags (value);
281       break;
282     case PROP_DEBUG:
283       rtspsrc->debug = g_value_get_boolean (value);
284       break;
285     case PROP_RETRY:
286       rtspsrc->retry = g_value_get_uint (value);
287       break;
288     default:
289       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
290       break;
291   }
292 }
293
294 static void
295 gst_rtspsrc_get_property (GObject * object, guint prop_id, GValue * value,
296     GParamSpec * pspec)
297 {
298   GstRTSPSrc *rtspsrc;
299
300   rtspsrc = GST_RTSPSRC (object);
301
302   switch (prop_id) {
303     case PROP_LOCATION:
304       g_value_set_string (value, rtspsrc->location);
305       break;
306     case PROP_PROTOCOLS:
307       g_value_set_flags (value, rtspsrc->protocols);
308       break;
309     case PROP_DEBUG:
310       g_value_set_boolean (value, rtspsrc->debug);
311       break;
312     case PROP_RETRY:
313       g_value_set_uint (value, rtspsrc->retry);
314       break;
315     default:
316       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
317       break;
318   }
319 }
320
321 static GstRTSPStream *
322 gst_rtspsrc_create_stream (GstRTSPSrc * src)
323 {
324   GstRTSPStream *s;
325
326   s = g_new0 (GstRTSPStream, 1);
327   s->parent = src;
328   s->id = src->numstreams++;
329
330   src->streams = g_list_append (src->streams, s);
331
332   return s;
333 }
334
335 #if 0
336 static void
337 gst_rtspsrc_free_stream (GstRTSPSrc * src, GstRTSPStream * stream)
338 {
339   if (stream->caps) {
340     gst_caps_unref (stream->caps);
341     stream->caps = NULL;
342   }
343
344   src->streams = g_list_remove (src->streams, stream);
345   src->numstreams--;
346
347   g_free (stream);
348 }
349 #endif
350
351 static gboolean
352 gst_rtspsrc_add_element (GstRTSPSrc * src, GstElement * element)
353 {
354   gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (src));
355
356   return TRUE;
357 }
358
359 static GstStateChangeReturn
360 gst_rtspsrc_set_state (GstRTSPSrc * src, GstState state)
361 {
362   GstStateChangeReturn ret;
363   GList *streams;
364
365   ret = GST_STATE_CHANGE_SUCCESS;
366
367   /* for all streams */
368   for (streams = src->streams; streams; streams = g_list_next (streams)) {
369     GstRTSPStream *stream;
370
371     stream = (GstRTSPStream *) streams->data;
372
373     /* first our rtp session manager */
374     if (stream->rtpdec) {
375       if ((ret =
376               gst_element_set_state (stream->rtpdec,
377                   state)) == GST_STATE_CHANGE_FAILURE)
378         goto done;
379     }
380
381     /* then our sources */
382     if (stream->rtpsrc) {
383       if ((ret =
384               gst_element_set_state (stream->rtpsrc,
385                   state)) == GST_STATE_CHANGE_FAILURE)
386         goto done;
387     }
388
389     if (stream->rtcpsrc) {
390       if ((ret =
391               gst_element_set_state (stream->rtcpsrc,
392                   state)) == GST_STATE_CHANGE_FAILURE)
393         goto done;
394     }
395   }
396
397 done:
398   return ret;
399 }
400
401 #define PARSE_INT(p, del, res)          \
402 G_STMT_START {                          \
403   gchar *t = p;                         \
404   p = strstr (p, del);                  \
405   if (p == NULL)                        \
406     res = -1;                           \
407   else {                                \
408     *p = '\0';                          \
409     p++;                                \
410     res = atoi (t);                     \
411   }                                     \
412 } G_STMT_END
413
414 #define PARSE_STRING(p, del, res)       \
415 G_STMT_START {                          \
416   gchar *t = p;                         \
417   p = strstr (p, del);                  \
418   if (p == NULL)                        \
419     res = NULL;                         \
420   else {                                \
421     *p = '\0';                          \
422     p++;                                \
423     res = t;                            \
424   }                                     \
425 } G_STMT_END
426
427 #define SKIP_SPACES(p)                  \
428   while (*p && g_ascii_isspace (*p))    \
429     p++;
430
431 static gboolean
432 gst_rtspsrc_parse_rtpmap (gchar * rtpmap, gint * payload, gchar ** name,
433     gint * rate, gchar ** params)
434 {
435   gchar *p, *t;
436
437   t = p = rtpmap;
438
439   PARSE_INT (p, " ", *payload);
440   if (*payload == -1)
441     return FALSE;
442
443   SKIP_SPACES (p);
444   if (*p == '\0')
445     return FALSE;
446
447   PARSE_STRING (p, "/", *name);
448   if (*name == NULL)
449     return FALSE;
450
451   t = p;
452   p = strstr (p, "/");
453   if (p == NULL) {
454     *rate = atoi (t);
455     return TRUE;
456   }
457   *p = '\0';
458   p++;
459   *rate = atoi (t);
460
461   t = p;
462   if (*p == '\0')
463     return TRUE;
464   *params = t;
465
466   return TRUE;
467 }
468
469 /*
470  *  Mapping of caps to and from SDP fields:
471  *
472  *   m=<media> <udp port> RTP/AVP <payload> 
473  *   a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
474  *   a=fmtp:<payload> <param>[=<value>];...
475  */
476 static GstCaps *
477 gst_rtspsrc_media_to_caps (SDPMedia * media)
478 {
479   GstCaps *caps;
480   gchar *payload;
481   gchar *rtpmap;
482   gchar *fmtp;
483   gint pt;
484   gchar *name = NULL;
485   gint rate = -1;
486   gchar *params = NULL;
487   GstStructure *s;
488
489   payload = sdp_media_get_format (media, 0);
490   if (payload == NULL) {
491     g_warning ("payload type not given");
492     return NULL;
493   }
494   pt = atoi (payload);
495
496   if (pt >= 96) {
497     gint payload = 0;
498     gboolean ret;
499
500     if ((rtpmap = sdp_media_get_attribute_val (media, "rtpmap"))) {
501       if ((ret =
502               gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate,
503                   &params))) {
504         if (payload != pt) {
505           g_warning ("rtpmap of wrong payload type");
506           name = NULL;
507           rate = -1;
508           params = NULL;
509         }
510       } else {
511         g_warning ("error parsing rtpmap");
512       }
513     } else {
514       g_warning ("rtpmap type not given fot dynamic payload %d", pt);
515       return NULL;
516     }
517   }
518
519   caps = gst_caps_new_simple ("application/x-rtp",
520       "media", G_TYPE_STRING, media->media, "payload", G_TYPE_INT, pt, NULL);
521   s = gst_caps_get_structure (caps, 0);
522
523   if (rate != -1)
524     gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);
525
526   if (name != NULL)
527     gst_structure_set (s, "encoding-name", G_TYPE_STRING, name, NULL);
528
529   if (params != NULL)
530     gst_structure_set (s, "encoding-params", G_TYPE_STRING, params, NULL);
531
532   /* parse optional fmtp: field */
533   if ((fmtp = sdp_media_get_attribute_val (media, "fmtp"))) {
534     gchar *p;
535     gint payload = 0;
536
537     p = fmtp;
538
539     /* p is now of the format <payload> <param>[=<value>];... */
540     PARSE_INT (p, " ", payload);
541     if (payload != -1 && payload == pt) {
542       gchar **pairs;
543       gint i;
544
545       /* <param>[=<value>] are separated with ';' */
546       pairs = g_strsplit (p, ";", 0);
547       for (i = 0; pairs[i]; i++) {
548         gchar *valpos;
549         gchar *val, *key;
550
551         /* the key may not have a '=', the value can have other '='s */
552         valpos = strstr (pairs[i], "=");
553         if (valpos) {
554           /* we have a '=' and thus a value, remove the '=' with \0 */
555           *valpos = '\0';
556           /* value is everything between '=' and ';' */
557           val = g_strstrip (valpos + 1);
558         } else {
559           /* simple <param>;.. is translated into <param>=1;... */
560           val = "1";
561         }
562         /* strip the key of spaces */
563         key = g_strstrip (pairs[i]);
564
565         gst_structure_set (s, key, G_TYPE_STRING, val, NULL);
566       }
567       g_strfreev (pairs);
568     }
569   }
570   return caps;
571 }
572
573 static gboolean
574 gst_rtspsrc_stream_setup_rtp (GstRTSPStream * stream, SDPMedia * media,
575     gint * rtpport, gint * rtcpport)
576 {
577   GstStateChangeReturn ret;
578   GstRTSPSrc *src;
579   GstCaps *caps;
580   GstElement *tmp, *rtp, *rtcp;
581   gint tmp_rtp, tmp_rtcp;
582   guint count;
583
584   src = stream->parent;
585
586   tmp = NULL;
587   rtp = NULL;
588   rtcp = NULL;
589   count = 0;
590
591   /* try to allocate 2 udp ports, the RTP port should be an even
592    * number and the RTCP port should be the next (uneven) port */
593 again:
594   rtp = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0:0", NULL);
595   if (rtp == NULL)
596     goto no_udp_rtp_protocol;
597
598   ret = gst_element_set_state (rtp, GST_STATE_PAUSED);
599   if (ret == GST_STATE_CHANGE_FAILURE)
600     goto start_rtp_failure;
601
602   g_object_get (G_OBJECT (rtp), "port", &tmp_rtp, NULL);
603   GST_DEBUG_OBJECT (src, "got RTP port %d", tmp_rtp);
604
605   /* check if port is even */
606   if ((tmp_rtp & 0x01) != 0) {
607     /* port not even, close and allocate another */
608     count++;
609     if (count > src->retry)
610       goto no_ports;
611
612     GST_DEBUG_OBJECT (src, "RTP port not even, retry %d", count);
613     /* have to keep port allocated so we can get a new one */
614     if (tmp != NULL) {
615       GST_DEBUG_OBJECT (src, "free temp");
616       gst_element_set_state (tmp, GST_STATE_NULL);
617       gst_object_unref (tmp);
618     }
619     tmp = rtp;
620     GST_DEBUG_OBJECT (src, "retry %d", count);
621     goto again;
622   }
623   /* free leftover temp element/port */
624   if (tmp) {
625     gst_element_set_state (tmp, GST_STATE_NULL);
626     gst_object_unref (tmp);
627     tmp = NULL;
628   }
629
630   /* allocate port+1 for RTCP now */
631   rtcp = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL);
632   if (rtcp == NULL)
633     goto no_udp_rtcp_protocol;
634
635   /* set port */
636   tmp_rtcp = tmp_rtp + 1;
637   g_object_set (G_OBJECT (rtcp), "port", tmp_rtcp, NULL);
638
639   GST_DEBUG_OBJECT (src, "starting RTCP on port %d", tmp_rtcp);
640   ret = gst_element_set_state (rtcp, GST_STATE_PAUSED);
641   /* FIXME, this could fail if the next port is not free, we
642    * should retry with another port then */
643   if (ret == GST_STATE_CHANGE_FAILURE)
644     goto start_rtcp_failure;
645
646   /* all fine, do port check */
647   g_object_get (G_OBJECT (rtp), "port", rtpport, NULL);
648   g_object_get (G_OBJECT (rtcp), "port", rtcpport, NULL);
649
650   /* this should not happen */
651   if (*rtpport != tmp_rtp || *rtcpport != tmp_rtcp)
652     goto port_error;
653
654   /* we manage these elements */
655   stream->rtpsrc = rtp;
656   gst_rtspsrc_add_element (src, stream->rtpsrc);
657   stream->rtcpsrc = rtcp;
658   gst_rtspsrc_add_element (src, stream->rtcpsrc);
659
660   caps = gst_rtspsrc_media_to_caps (media);
661
662   /* set caps */
663   g_object_set (G_OBJECT (stream->rtpsrc), "caps", caps, NULL);
664
665   return TRUE;
666
667   /* ERRORS */
668 no_udp_rtp_protocol:
669   {
670     GST_DEBUG_OBJECT (src, "could not get UDP source for RTP");
671     goto cleanup;
672   }
673 start_rtp_failure:
674   {
675     GST_DEBUG_OBJECT (src, "could not start UDP source for RTP");
676     goto cleanup;
677   }
678 no_ports:
679   {
680     GST_DEBUG_OBJECT (src, "could not allocate UDP port pair after %d retries",
681         count);
682     goto cleanup;
683   }
684 no_udp_rtcp_protocol:
685   {
686     GST_DEBUG_OBJECT (src, "could not get UDP source for RTCP");
687     goto cleanup;
688   }
689 start_rtcp_failure:
690   {
691     GST_DEBUG_OBJECT (src, "could not start UDP source for RTCP");
692     goto cleanup;
693   }
694 port_error:
695   {
696     GST_DEBUG_OBJECT (src, "ports don't match rtp: %d<->%d, rtcp: %d<->%d",
697         tmp_rtp, *rtpport, tmp_rtcp, *rtcpport);
698     goto cleanup;
699   }
700 cleanup:
701   {
702     if (tmp) {
703       gst_element_set_state (tmp, GST_STATE_NULL);
704       gst_object_unref (tmp);
705     }
706     if (rtp) {
707       gst_element_set_state (rtp, GST_STATE_NULL);
708       gst_object_unref (rtp);
709     }
710     if (rtcp) {
711       gst_element_set_state (rtcp, GST_STATE_NULL);
712       gst_object_unref (rtcp);
713     }
714     return FALSE;
715   }
716 }
717
718 static gboolean
719 gst_rtspsrc_stream_configure_transport (GstRTSPStream * stream,
720     SDPMedia * media, RTSPTransport * transport)
721 {
722   GstRTSPSrc *src;
723   GstPad *pad;
724   GstStateChangeReturn ret;
725   gchar *name;
726
727   src = stream->parent;
728
729   GST_DEBUG ("configuring RTP transport for stream %p", stream);
730
731   if (!(stream->rtpdec = gst_element_factory_make ("rtpdec", NULL)))
732     goto no_element;
733
734   /* we manage this element */
735   gst_rtspsrc_add_element (src, stream->rtpdec);
736
737   if ((ret =
738           gst_element_set_state (stream->rtpdec,
739               GST_STATE_PAUSED)) != GST_STATE_CHANGE_SUCCESS)
740     goto start_rtpdec_failure;
741
742   stream->rtpdecrtp = gst_element_get_pad (stream->rtpdec, "sinkrtp");
743   stream->rtpdecrtcp = gst_element_get_pad (stream->rtpdec, "sinkrtcp");
744
745   if (transport->lower_transport == RTSP_LOWER_TRANS_TCP) {
746     /* configure for interleaved delivery, nothing needs to be done
747      * here, the loop function will call the chain functions of the
748      * rtp session manager. */
749     stream->rtpchannel = transport->interleaved.min;
750     stream->rtcpchannel = transport->interleaved.max;
751     GST_DEBUG ("stream %p on channels %d-%d", stream,
752         stream->rtpchannel, stream->rtcpchannel);
753
754     /* also store the caps in the stream */
755     stream->caps = gst_rtspsrc_media_to_caps (media);
756   } else {
757     /* configure for UDP delivery, we need to connect the udp pads to
758      * the rtp session plugin. */
759     pad = gst_element_get_pad (stream->rtpsrc, "src");
760     gst_pad_link (pad, stream->rtpdecrtp);
761     gst_object_unref (pad);
762
763     pad = gst_element_get_pad (stream->rtcpsrc, "src");
764     gst_pad_link (pad, stream->rtpdecrtcp);
765     gst_object_unref (pad);
766   }
767
768   pad = gst_element_get_pad (stream->rtpdec, "srcrtp");
769   if (stream->caps) {
770     gst_pad_use_fixed_caps (pad);
771     gst_pad_set_caps (pad, stream->caps);
772   }
773   name = g_strdup_printf ("rtp_stream%d", stream->id);
774   gst_element_add_pad (GST_ELEMENT_CAST (src), gst_ghost_pad_new (name, pad));
775   g_free (name);
776   gst_object_unref (pad);
777
778   return TRUE;
779
780   /* ERRORS */
781 no_element:
782   {
783     GST_DEBUG_OBJECT (src, "no rtpdec element found");
784     return FALSE;
785   }
786 start_rtpdec_failure:
787   {
788     GST_DEBUG_OBJECT (src, "could not start RTP session");
789     return FALSE;
790   }
791 }
792
793 static gint
794 find_stream (GstRTSPStream * stream, gconstpointer a)
795 {
796   gint channel = GPOINTER_TO_INT (a);
797
798   if (stream->rtpchannel == channel || stream->rtcpchannel == channel)
799     return 0;
800
801   return -1;
802 }
803
804 static GstFlowReturn
805 gst_rtspsrc_combine_flows (GstRTSPSrc * src, GstRTSPStream * stream,
806     GstFlowReturn ret)
807 {
808   GList *streams;
809
810   /* store the value */
811   stream->last_ret = ret;
812
813   /* if it's success we can return the value right away */
814   if (GST_FLOW_IS_SUCCESS (ret))
815     goto done;
816
817   /* any other error that is not-linked can be returned right
818    * away */
819   if (ret != GST_FLOW_NOT_LINKED)
820     goto done;
821
822   /* only return NOT_LINKED if all other pads returned NOT_LINKED */
823   for (streams = src->streams; streams; streams = g_list_next (streams)) {
824     GstRTSPStream *ostream = (GstRTSPStream *) streams->data;
825
826     ret = ostream->last_ret;
827     /* some other return value (must be SUCCESS but we can return
828      * other values as well) */
829     if (ret != GST_FLOW_NOT_LINKED)
830       goto done;
831   }
832   /* if we get here, all other pads were unlinked and we return
833    * NOT_LINKED then */
834 done:
835   return ret;
836 }
837
838 static void
839 gst_rtspsrc_loop (GstRTSPSrc * src)
840 {
841   RTSPMessage response = { 0 };
842   RTSPResult res;
843   gint channel;
844   GList *lstream;
845   GstRTSPStream *stream;
846   GstPad *outpad = NULL;
847   guint8 *data;
848   guint size;
849   GstFlowReturn ret = GST_FLOW_OK;
850   GstCaps *caps = NULL;
851
852   do {
853     GST_DEBUG_OBJECT (src, "doing receive");
854     if ((res = rtsp_connection_receive (src->connection, &response)) < 0)
855       goto receive_error;
856     GST_DEBUG_OBJECT (src, "got packet type %d", response.type);
857   }
858   while (response.type != RTSP_MESSAGE_DATA);
859
860   channel = response.type_data.data.channel;
861
862   lstream = g_list_find_custom (src->streams, GINT_TO_POINTER (channel),
863       (GCompareFunc) find_stream);
864   if (!lstream)
865     goto unknown_stream;
866
867   stream = (GstRTSPStream *) lstream->data;
868   if (channel == stream->rtpchannel) {
869     outpad = stream->rtpdecrtp;
870     caps = stream->caps;
871   } else if (channel == stream->rtcpchannel) {
872     outpad = stream->rtpdecrtcp;
873   }
874
875   rtsp_message_get_body (&response, &data, &size);
876
877   /* channels are not correct on some servers, do extra check */
878   if (data[1] >= 200 && data[1] <= 204) {
879     /* hmm RTCP message */
880     outpad = stream->rtpdecrtcp;
881   }
882
883   /* we have no clue what this is, just ignore then. */
884   if (outpad == NULL)
885     goto unknown_stream;
886
887   /* and chain buffer to internal element */
888   {
889     GstBuffer *buf;
890
891     /* strip the trailing \0 */
892     size -= 1;
893
894     buf = gst_buffer_new_and_alloc (size);
895     memcpy (GST_BUFFER_DATA (buf), data, size);
896
897     if (caps)
898       gst_buffer_set_caps (buf, caps);
899
900     GST_DEBUG_OBJECT (src, "pushing data of size %d on channel %d", size,
901         channel);
902
903     /* chain to the peer pad */
904     ret = gst_pad_chain (outpad, buf);
905
906     /* combine all streams */
907     ret = gst_rtspsrc_combine_flows (src, stream, ret);
908     if (ret != GST_FLOW_OK)
909       goto need_pause;
910   }
911   return;
912
913   /* ERRORS */
914 unknown_stream:
915   {
916     GST_DEBUG_OBJECT (src, "unknown stream on channel %d, ignored", channel);
917     return;
918   }
919 receive_error:
920   {
921     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
922         ("Could not receive message."), (NULL));
923     ret = GST_FLOW_UNEXPECTED;
924     /*
925        gst_pad_push_event (src->srcpad, gst_event_new (GST_EVENT_EOS));
926      */
927     goto need_pause;
928   }
929 need_pause:
930   {
931     GST_DEBUG_OBJECT (src, "pausing task, reason %d (%s)", ret,
932         gst_flow_get_name (ret));
933     gst_task_pause (src->task);
934     return;
935   }
936 }
937
938 static gboolean
939 gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
940     RTSPMessage * response, RTSPStatusCode * code)
941 {
942   RTSPResult res;
943
944   if (src->debug) {
945     rtsp_message_dump (request);
946   }
947   if ((res = rtsp_connection_send (src->connection, request)) < 0)
948     goto send_error;
949
950   if ((res = rtsp_connection_receive (src->connection, response)) < 0)
951     goto receive_error;
952
953   if (code) {
954     *code = response->type_data.response.code;
955   }
956
957   if (src->debug) {
958     rtsp_message_dump (response);
959   }
960   if (response->type_data.response.code != RTSP_STS_OK)
961     goto error_response;
962
963   return TRUE;
964
965 send_error:
966   {
967     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
968         ("Could not send message."), (NULL));
969     return FALSE;
970   }
971 receive_error:
972   {
973     GST_ELEMENT_ERROR (src, RESOURCE, READ,
974         ("Could not receive message."), (NULL));
975     return FALSE;
976   }
977 error_response:
978   {
979     GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Got error response: %d (%s).",
980             response->type_data.response.code,
981             response->type_data.response.reason), (NULL));
982     return FALSE;
983   }
984 }
985
986 static gboolean
987 gst_rtspsrc_open (GstRTSPSrc * src)
988 {
989   RTSPUrl *url;
990   RTSPResult res;
991   RTSPMessage request = { 0 };
992   RTSPMessage response = { 0 };
993   guint8 *data;
994   guint size;
995   SDPMessage sdp = { 0 };
996   GstRTSPProto protocols;
997
998   /* parse url */
999   GST_DEBUG_OBJECT (src, "parsing url...");
1000   if ((res = rtsp_url_parse (src->location, &url)) < 0)
1001     goto invalid_url;
1002
1003   /* open connection */
1004   GST_DEBUG_OBJECT (src, "opening connection...");
1005   if ((res = rtsp_connection_open (url, &src->connection)) < 0)
1006     goto could_not_open;
1007
1008   /* create OPTIONS */
1009   GST_DEBUG_OBJECT (src, "create options...");
1010   if ((res =
1011           rtsp_message_init_request (RTSP_OPTIONS, src->location,
1012               &request)) < 0)
1013     goto create_request_failed;
1014
1015   /* send OPTIONS */
1016   GST_DEBUG_OBJECT (src, "send options...");
1017   if (!gst_rtspsrc_send (src, &request, &response, NULL))
1018     goto send_error;
1019
1020   {
1021     gchar *respoptions = NULL;
1022     gchar **options;
1023     gint i;
1024
1025     /* Try Allow Header first */
1026     rtsp_message_get_header (&response, RTSP_HDR_ALLOW, &respoptions);
1027     if (!respoptions) {
1028       /* Then maybe Public Header... */
1029       rtsp_message_get_header (&response, RTSP_HDR_PUBLIC, &respoptions);
1030       if (!respoptions) {
1031         /* this field is not required, assume the server supports
1032          * DESCRIBE and SETUP*/
1033         GST_DEBUG_OBJECT (src, "could not get OPTIONS");
1034         src->options = RTSP_DESCRIBE | RTSP_SETUP;
1035         goto no_options;
1036       }
1037     }
1038
1039     /* parse options */
1040     options = g_strsplit (respoptions, ",", 0);
1041
1042     i = 0;
1043     while (options[i]) {
1044       gchar *stripped;
1045       gint method;
1046
1047       stripped = g_strdup (options[i]);
1048       stripped = g_strstrip (stripped);
1049       method = rtsp_find_method (stripped);
1050       g_free (stripped);
1051
1052       /* keep bitfield of supported methods */
1053       if (method != -1)
1054         src->options |= method;
1055       i++;
1056     }
1057     g_strfreev (options);
1058
1059   no_options:
1060     /* we need describe and setup */
1061     if (!(src->options & RTSP_DESCRIBE))
1062       goto no_describe;
1063     if (!(src->options & RTSP_SETUP))
1064       goto no_setup;
1065   }
1066
1067   /* create DESCRIBE */
1068   GST_DEBUG_OBJECT (src, "create describe...");
1069   if ((res =
1070           rtsp_message_init_request (RTSP_DESCRIBE, src->location,
1071               &request)) < 0)
1072     goto create_request_failed;
1073   /* we accept SDP for now */
1074   rtsp_message_add_header (&request, RTSP_HDR_ACCEPT, "application/sdp");
1075
1076   /* send DESCRIBE */
1077   GST_DEBUG_OBJECT (src, "send describe...");
1078   if (!gst_rtspsrc_send (src, &request, &response, NULL))
1079     goto send_error;
1080
1081   /* check if reply is SDP */
1082   {
1083     gchar *respcont = NULL;
1084
1085     rtsp_message_get_header (&response, RTSP_HDR_CONTENT_TYPE, &respcont);
1086     /* could not be set but since the request returned OK, we assume it
1087      * was SDP, else check it. */
1088     if (respcont) {
1089       if (!g_ascii_strcasecmp (respcont, "application/sdp") == 0)
1090         goto wrong_content_type;
1091     }
1092   }
1093
1094   /* parse SDP */
1095   rtsp_message_get_body (&response, &data, &size);
1096
1097   GST_DEBUG_OBJECT (src, "parse sdp...");
1098   sdp_message_init (&sdp);
1099   sdp_message_parse_buffer (data, size, &sdp);
1100
1101   if (src->debug)
1102     sdp_message_dump (&sdp);
1103
1104   /* we allow all configured protocols */
1105   protocols = src->protocols;
1106   /* setup streams */
1107   {
1108     gint i;
1109
1110     for (i = 0; i < sdp_message_medias_len (&sdp); i++) {
1111       SDPMedia *media;
1112       gchar *setup_url;
1113       gchar *control_url;
1114       gchar *transports;
1115       GstRTSPStream *stream;
1116
1117       media = sdp_message_get_media (&sdp, i);
1118
1119       stream = gst_rtspsrc_create_stream (src);
1120
1121       GST_DEBUG_OBJECT (src, "setup media %d", i);
1122       control_url = sdp_media_get_attribute_val (media, "control");
1123       if (control_url == NULL) {
1124         GST_DEBUG_OBJECT (src, "no control url found, skipping stream");
1125         continue;
1126       }
1127
1128       /* check absolute/relative URL */
1129       /* FIXME, what if the control_url starts with a '/' or a non rtsp: protocol? */
1130       if (g_str_has_prefix (control_url, "rtsp://")) {
1131         setup_url = g_strdup (control_url);
1132       } else {
1133         setup_url = g_strdup_printf ("%s/%s", src->location, control_url);
1134       }
1135
1136       GST_DEBUG_OBJECT (src, "setup %s", setup_url);
1137       /* create SETUP request */
1138       if ((res =
1139               rtsp_message_init_request (RTSP_SETUP, setup_url,
1140                   &request)) < 0) {
1141         g_free (setup_url);
1142         goto create_request_failed;
1143       }
1144       g_free (setup_url);
1145
1146       transports = g_strdup ("");
1147       if (protocols & GST_RTSP_PROTO_UDP_UNICAST) {
1148         gchar *new;
1149         gint rtpport, rtcpport;
1150         gchar *trxparams;
1151
1152         /* allocate two udp ports */
1153         if (!gst_rtspsrc_stream_setup_rtp (stream, media, &rtpport, &rtcpport))
1154           goto setup_rtp_failed;
1155
1156         GST_DEBUG_OBJECT (src, "setting up RTP ports %d-%d", rtpport, rtcpport);
1157
1158         trxparams = g_strdup_printf ("client_port=%d-%d", rtpport, rtcpport);
1159         new = g_strconcat (transports, "RTP/AVP/UDP;unicast;", trxparams, NULL);
1160         g_free (trxparams);
1161         g_free (transports);
1162         transports = new;
1163       }
1164       if (protocols & GST_RTSP_PROTO_UDP_MULTICAST) {
1165         gchar *new;
1166
1167         GST_DEBUG_OBJECT (src, "setting up MULTICAST");
1168
1169         new =
1170             g_strconcat (transports, transports[0] ? "," : "",
1171             "RTP/AVP/UDP;multicast", NULL);
1172         g_free (transports);
1173         transports = new;
1174       }
1175       if (protocols & GST_RTSP_PROTO_TCP) {
1176         gchar *new;
1177
1178         GST_DEBUG_OBJECT (src, "setting up TCP");
1179
1180         new =
1181             g_strconcat (transports, transports[0] ? "," : "", "RTP/AVP/TCP",
1182             NULL);
1183         g_free (transports);
1184         transports = new;
1185       }
1186
1187       /* select transport, copy is made when adding to header */
1188       rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT, transports);
1189       g_free (transports);
1190
1191       if (!gst_rtspsrc_send (src, &request, &response, NULL))
1192         goto send_error;
1193
1194       /* parse response transport */
1195       {
1196         gchar *resptrans = NULL;
1197         RTSPTransport transport = { 0 };
1198
1199         rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans);
1200         if (!resptrans)
1201           goto no_transport;
1202
1203         /* parse transport */
1204         rtsp_transport_parse (resptrans, &transport);
1205         /* update allowed transports for other streams */
1206         if (transport.lower_transport == RTSP_LOWER_TRANS_TCP) {
1207           GST_DEBUG_OBJECT (src, "stream %d as TCP", i);
1208           protocols = GST_RTSP_PROTO_TCP;
1209           src->interleaved = TRUE;
1210         } else {
1211           if (transport.multicast) {
1212             /* disable unicast */
1213             GST_DEBUG_OBJECT (src, "stream %d as MULTICAST", i);
1214             protocols = GST_RTSP_PROTO_UDP_MULTICAST;
1215           } else {
1216             /* disable multicast */
1217             GST_DEBUG_OBJECT (src, "stream %d as UNICAST", i);
1218             protocols = GST_RTSP_PROTO_UDP_UNICAST;
1219           }
1220         }
1221         /* now configure the stream with the transport */
1222         if (!gst_rtspsrc_stream_configure_transport (stream, media, &transport)) {
1223           GST_DEBUG_OBJECT (src,
1224               "could not configure stream transport, skipping stream");
1225         }
1226         /* clean up our transport struct */
1227         rtsp_transport_init (&transport);
1228       }
1229     }
1230   }
1231   return TRUE;
1232
1233   /* ERRORS */
1234 invalid_url:
1235   {
1236     GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
1237         ("Not a valid RTSP url."), (NULL));
1238     return FALSE;
1239   }
1240 could_not_open:
1241   {
1242     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE,
1243         ("Could not open connection."), (NULL));
1244     return FALSE;
1245   }
1246 create_request_failed:
1247   {
1248     GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1249         ("Could not create request."), (NULL));
1250     return FALSE;
1251   }
1252 send_error:
1253   {
1254     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1255         ("Could not send message."), (NULL));
1256     return FALSE;
1257   }
1258 no_describe:
1259   {
1260     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1261         ("Server does not support DESCRIBE."), (NULL));
1262     return FALSE;
1263   }
1264 no_setup:
1265   {
1266     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1267         ("Server does not support SETUP."), (NULL));
1268     return FALSE;
1269   }
1270 wrong_content_type:
1271   {
1272     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1273         ("Server does not support SDP."), (NULL));
1274     return FALSE;
1275   }
1276 setup_rtp_failed:
1277   {
1278     GST_ELEMENT_ERROR (src, RESOURCE, WRITE, ("Could not setup rtp."), (NULL));
1279     return FALSE;
1280   }
1281 no_transport:
1282   {
1283     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1284         ("Server did not select transport."), (NULL));
1285     return FALSE;
1286   }
1287 }
1288
1289 static gboolean
1290 gst_rtspsrc_close (GstRTSPSrc * src)
1291 {
1292   RTSPMessage request = { 0 };
1293   RTSPMessage response = { 0 };
1294   RTSPResult res;
1295
1296   GST_DEBUG_OBJECT (src, "TEARDOWN...");
1297
1298   /* stop task if any */
1299   if (src->task) {
1300     gst_task_stop (src->task);
1301
1302     /* make sure it is not running */
1303     g_static_rec_mutex_lock (src->stream_rec_lock);
1304     g_static_rec_mutex_unlock (src->stream_rec_lock);
1305
1306     /* no wait for the task to finish */
1307     gst_task_join (src->task);
1308
1309     /* and free the task */
1310     gst_object_unref (GST_OBJECT (src->task));
1311     src->task = NULL;
1312   }
1313
1314   if (src->options & RTSP_PLAY) {
1315     /* do TEARDOWN */
1316     if ((res =
1317             rtsp_message_init_request (RTSP_TEARDOWN, src->location,
1318                 &request)) < 0)
1319       goto create_request_failed;
1320
1321     if (!gst_rtspsrc_send (src, &request, &response, NULL))
1322       goto send_error;
1323   }
1324
1325   /* close connection */
1326   GST_DEBUG_OBJECT (src, "closing connection...");
1327   if ((res = rtsp_connection_close (src->connection)) < 0)
1328     goto close_failed;
1329
1330   return TRUE;
1331
1332 create_request_failed:
1333   {
1334     GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1335         ("Could not create request."), (NULL));
1336     return FALSE;
1337   }
1338 send_error:
1339   {
1340     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1341         ("Could not send message."), (NULL));
1342     return FALSE;
1343   }
1344 close_failed:
1345   {
1346     GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, ("Close failed."), (NULL));
1347     return FALSE;
1348   }
1349 }
1350
1351 static gboolean
1352 gst_rtspsrc_play (GstRTSPSrc * src)
1353 {
1354   RTSPMessage request = { 0 };
1355   RTSPMessage response = { 0 };
1356   RTSPResult res;
1357
1358   if (!(src->options & RTSP_PLAY))
1359     return TRUE;
1360
1361   GST_DEBUG_OBJECT (src, "PLAY...");
1362
1363   /* do play */
1364   if ((res =
1365           rtsp_message_init_request (RTSP_PLAY, src->location, &request)) < 0)
1366     goto create_request_failed;
1367
1368   if (!gst_rtspsrc_send (src, &request, &response, NULL))
1369     goto send_error;
1370
1371   if (src->interleaved) {
1372     src->task = gst_task_create ((GstTaskFunction) gst_rtspsrc_loop, src);
1373
1374     gst_task_set_lock (src->task, src->stream_rec_lock);
1375     gst_task_start (src->task);
1376   }
1377
1378   return TRUE;
1379
1380 create_request_failed:
1381   {
1382     GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1383         ("Could not create request."), (NULL));
1384     return FALSE;
1385   }
1386 send_error:
1387   {
1388     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1389         ("Could not send message."), (NULL));
1390     return FALSE;
1391   }
1392 }
1393
1394 static gboolean
1395 gst_rtspsrc_pause (GstRTSPSrc * src)
1396 {
1397   RTSPMessage request = { 0 };
1398   RTSPMessage response = { 0 };
1399   RTSPResult res;
1400
1401   if (!(src->options & RTSP_PAUSE))
1402     return TRUE;
1403
1404   GST_DEBUG_OBJECT (src, "PAUSE...");
1405   /* do pause */
1406   if ((res =
1407           rtsp_message_init_request (RTSP_PAUSE, src->location, &request)) < 0)
1408     goto create_request_failed;
1409
1410   if (!gst_rtspsrc_send (src, &request, &response, NULL))
1411     goto send_error;
1412
1413   return TRUE;
1414
1415 create_request_failed:
1416   {
1417     GST_ELEMENT_ERROR (src, LIBRARY, INIT,
1418         ("Could not create request."), (NULL));
1419     return FALSE;
1420   }
1421 send_error:
1422   {
1423     GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
1424         ("Could not send message."), (NULL));
1425     return FALSE;
1426   }
1427 }
1428
1429 static GstStateChangeReturn
1430 gst_rtspsrc_change_state (GstElement * element, GstStateChange transition)
1431 {
1432   GstRTSPSrc *rtspsrc;
1433   GstStateChangeReturn ret;
1434
1435   rtspsrc = GST_RTSPSRC (element);
1436
1437
1438   switch (transition) {
1439     case GST_STATE_CHANGE_NULL_TO_READY:
1440       break;
1441     case GST_STATE_CHANGE_READY_TO_PAUSED:
1442       rtspsrc->interleaved = FALSE;
1443       rtspsrc->options = 0;
1444       if (!gst_rtspsrc_open (rtspsrc))
1445         goto open_failed;
1446       break;
1447     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1448       gst_rtspsrc_play (rtspsrc);
1449       break;
1450     default:
1451       break;
1452   }
1453
1454   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1455   if (ret == GST_STATE_CHANGE_FAILURE)
1456     goto done;
1457
1458   ret = gst_rtspsrc_set_state (rtspsrc, GST_STATE_PENDING (rtspsrc));
1459   if (ret == GST_STATE_CHANGE_FAILURE)
1460     goto done;
1461
1462   switch (transition) {
1463     case GST_STATE_CHANGE_READY_TO_PAUSED:
1464       ret = GST_STATE_CHANGE_NO_PREROLL;
1465       break;
1466     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1467       gst_rtspsrc_pause (rtspsrc);
1468       break;
1469     case GST_STATE_CHANGE_PAUSED_TO_READY:
1470       gst_rtspsrc_close (rtspsrc);
1471       break;
1472     case GST_STATE_CHANGE_READY_TO_NULL:
1473       break;
1474     default:
1475       break;
1476   }
1477
1478 done:
1479   return ret;
1480
1481 open_failed:
1482   {
1483     return GST_STATE_CHANGE_FAILURE;
1484   }
1485 }
1486
1487 /*** GSTURIHANDLER INTERFACE *************************************************/
1488
1489 static guint
1490 gst_rtspsrc_uri_get_type (void)
1491 {
1492   return GST_URI_SRC;
1493 }
1494 static gchar **
1495 gst_rtspsrc_uri_get_protocols (void)
1496 {
1497   static gchar *protocols[] = { "rtsp", NULL };
1498
1499   return protocols;
1500 }
1501
1502 static const gchar *
1503 gst_rtspsrc_uri_get_uri (GstURIHandler * handler)
1504 {
1505   GstRTSPSrc *src = GST_RTSPSRC (handler);
1506
1507   return g_strdup (src->location);
1508 }
1509
1510 static gboolean
1511 gst_rtspsrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
1512 {
1513   GstRTSPSrc *src = GST_RTSPSRC (handler);
1514
1515   g_free (src->location);
1516   src->location = g_strdup (uri);
1517
1518   return TRUE;
1519 }
1520
1521 static void
1522 gst_rtspsrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
1523 {
1524   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
1525
1526   iface->get_type = gst_rtspsrc_uri_get_type;
1527   iface->get_protocols = gst_rtspsrc_uri_get_protocols;
1528   iface->get_uri = gst_rtspsrc_uri_get_uri;
1529   iface->set_uri = gst_rtspsrc_uri_set_uri;
1530 }