1 /* GStreamer
2  * Copyright (C) <2007> Wim Taymans <wim dot taymans at gmail dot 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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 /**
20  * SECTION:element-sdpdemux
21  * @title: sdpdemux
22  *
23  * sdpdemux currently understands SDP as the input format of the session description.
24  * For each stream listed in the SDP a new stream_\%u pad will be created
25  * with caps derived from the SDP media description. This is a caps of mime type
26  * "application/x-rtp" that can be connected to any available RTP depayloader
27  * element.
28  *
29  * sdpdemux will internally instantiate an RTP session manager element
30  * that will handle the RTCP messages to and from the server, jitter removal,
31  * packet reordering along with providing a clock for the pipeline.
32  *
33  * sdpdemux acts like a live element and will therefore only generate data in the
34  * PLAYING state.
35  *
36  * ## Example launch line
37  * |[
38  * gst-launch-1.0 souphttpsrc location=http://some.server/session.sdp ! sdpdemux ! fakesink
39  * ]| Establish a connection to an HTTP server that contains an SDP session description
40  * that gets parsed by sdpdemux and send the raw RTP packets to a fakesink.
41  *
42  */
43 
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47 
48 #include "gstsdpdemux.h"
49 
50 #include <gst/rtp/gstrtppayloads.h>
51 #include <gst/sdp/gstsdpmessage.h>
52 
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include <string.h>
56 
57 GST_DEBUG_CATEGORY_STATIC (sdpdemux_debug);
58 #define GST_CAT_DEFAULT (sdpdemux_debug)
59 
60 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
61     GST_PAD_SINK,
62     GST_PAD_ALWAYS,
63     GST_STATIC_CAPS ("application/sdp"));
64 
65 static GstStaticPadTemplate rtptemplate = GST_STATIC_PAD_TEMPLATE ("stream_%u",
66     GST_PAD_SRC,
67     GST_PAD_SOMETIMES,
68     GST_STATIC_CAPS ("application/x-rtp"));
69 
70 enum
71 {
72   /* FILL ME */
73   LAST_SIGNAL
74 };
75 
76 #define DEFAULT_DEBUG            FALSE
77 #define DEFAULT_TIMEOUT          10000000
78 #define DEFAULT_LATENCY_MS       200
79 #define DEFAULT_REDIRECT         TRUE
80 
81 enum
82 {
83   PROP_0,
84   PROP_DEBUG,
85   PROP_TIMEOUT,
86   PROP_LATENCY,
87   PROP_REDIRECT
88 };
89 
90 static void gst_sdp_demux_finalize (GObject * object);
91 
92 static void gst_sdp_demux_set_property (GObject * object, guint prop_id,
93     const GValue * value, GParamSpec * pspec);
94 static void gst_sdp_demux_get_property (GObject * object, guint prop_id,
95     GValue * value, GParamSpec * pspec);
96 
97 static GstStateChangeReturn gst_sdp_demux_change_state (GstElement * element,
98     GstStateChange transition);
99 static void gst_sdp_demux_handle_message (GstBin * bin, GstMessage * message);
100 
101 static void gst_sdp_demux_stream_push_event (GstSDPDemux * demux,
102     GstSDPStream * stream, GstEvent * event);
103 
104 static gboolean gst_sdp_demux_sink_event (GstPad * pad, GstObject * parent,
105     GstEvent * event);
106 static GstFlowReturn gst_sdp_demux_sink_chain (GstPad * pad, GstObject * parent,
107     GstBuffer * buffer);
108 
109 /*static guint gst_sdp_demux_signals[LAST_SIGNAL] = { 0 }; */
110 
111 #define gst_sdp_demux_parent_class parent_class
112 G_DEFINE_TYPE (GstSDPDemux, gst_sdp_demux, GST_TYPE_BIN);
113 
114 static void
gst_sdp_demux_class_init(GstSDPDemuxClass * klass)115 gst_sdp_demux_class_init (GstSDPDemuxClass * klass)
116 {
117   GObjectClass *gobject_class;
118   GstElementClass *gstelement_class;
119   GstBinClass *gstbin_class;
120 
121   gobject_class = (GObjectClass *) klass;
122   gstelement_class = (GstElementClass *) klass;
123   gstbin_class = (GstBinClass *) klass;
124 
125   gobject_class->set_property = gst_sdp_demux_set_property;
126   gobject_class->get_property = gst_sdp_demux_get_property;
127 
128   gobject_class->finalize = gst_sdp_demux_finalize;
129 
130   g_object_class_install_property (gobject_class, PROP_DEBUG,
131       g_param_spec_boolean ("debug", "Debug",
132           "Dump request and response messages to stdout",
133           DEFAULT_DEBUG,
134           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
135 
136   g_object_class_install_property (gobject_class, PROP_TIMEOUT,
137       g_param_spec_uint64 ("timeout", "Timeout",
138           "Fail transport after UDP timeout microseconds (0 = disabled)",
139           0, G_MAXUINT64, DEFAULT_TIMEOUT,
140           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
141 
142   g_object_class_install_property (gobject_class, PROP_LATENCY,
143       g_param_spec_uint ("latency", "Buffer latency in ms",
144           "Amount of ms to buffer", 0, G_MAXUINT, DEFAULT_LATENCY_MS,
145           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
146 
147   g_object_class_install_property (gobject_class, PROP_REDIRECT,
148       g_param_spec_boolean ("redirect", "Redirect",
149           "Sends a redirection message instead of using a custom session element",
150           DEFAULT_REDIRECT,
151           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
152 
153   gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
154   gst_element_class_add_static_pad_template (gstelement_class, &rtptemplate);
155 
156   gst_element_class_set_static_metadata (gstelement_class, "SDP session setup",
157       "Codec/Demuxer/Network/RTP",
158       "Receive data over the network via SDP",
159       "Wim Taymans <wim.taymans@gmail.com>");
160 
161   gstelement_class->change_state = gst_sdp_demux_change_state;
162 
163   gstbin_class->handle_message = gst_sdp_demux_handle_message;
164 
165   GST_DEBUG_CATEGORY_INIT (sdpdemux_debug, "sdpdemux", 0, "SDP demux");
166 }
167 
168 static void
gst_sdp_demux_init(GstSDPDemux * demux)169 gst_sdp_demux_init (GstSDPDemux * demux)
170 {
171   demux->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
172   gst_pad_set_event_function (demux->sinkpad,
173       GST_DEBUG_FUNCPTR (gst_sdp_demux_sink_event));
174   gst_pad_set_chain_function (demux->sinkpad,
175       GST_DEBUG_FUNCPTR (gst_sdp_demux_sink_chain));
176   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
177 
178   /* protects the streaming thread in interleaved mode or the polling
179    * thread in UDP mode. */
180   g_rec_mutex_init (&demux->stream_rec_lock);
181 
182   demux->adapter = gst_adapter_new ();
183 }
184 
185 static void
gst_sdp_demux_finalize(GObject * object)186 gst_sdp_demux_finalize (GObject * object)
187 {
188   GstSDPDemux *demux;
189 
190   demux = GST_SDP_DEMUX (object);
191 
192   /* free locks */
193   g_rec_mutex_clear (&demux->stream_rec_lock);
194 
195   g_object_unref (demux->adapter);
196 
197   G_OBJECT_CLASS (parent_class)->finalize (object);
198 }
199 
200 static void
gst_sdp_demux_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)201 gst_sdp_demux_set_property (GObject * object, guint prop_id,
202     const GValue * value, GParamSpec * pspec)
203 {
204   GstSDPDemux *demux;
205 
206   demux = GST_SDP_DEMUX (object);
207 
208   switch (prop_id) {
209     case PROP_DEBUG:
210       demux->debug = g_value_get_boolean (value);
211       break;
212     case PROP_TIMEOUT:
213       demux->udp_timeout = g_value_get_uint64 (value);
214       break;
215     case PROP_LATENCY:
216       demux->latency = g_value_get_uint (value);
217       break;
218     case PROP_REDIRECT:
219       demux->redirect = g_value_get_boolean (value);
220       break;
221     default:
222       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
223       break;
224   }
225 }
226 
227 static void
gst_sdp_demux_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)228 gst_sdp_demux_get_property (GObject * object, guint prop_id, GValue * value,
229     GParamSpec * pspec)
230 {
231   GstSDPDemux *demux;
232 
233   demux = GST_SDP_DEMUX (object);
234 
235   switch (prop_id) {
236     case PROP_DEBUG:
237       g_value_set_boolean (value, demux->debug);
238       break;
239     case PROP_TIMEOUT:
240       g_value_set_uint64 (value, demux->udp_timeout);
241       break;
242     case PROP_LATENCY:
243       g_value_set_uint (value, demux->latency);
244       break;
245     case PROP_REDIRECT:
246       g_value_set_boolean (value, demux->redirect);
247       break;
248     default:
249       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
250       break;
251   }
252 }
253 
254 static gint
find_stream_by_id(GstSDPStream * stream,gconstpointer a)255 find_stream_by_id (GstSDPStream * stream, gconstpointer a)
256 {
257   gint id = GPOINTER_TO_INT (a);
258 
259   if (stream->id == id)
260     return 0;
261 
262   return -1;
263 }
264 
265 static gint
find_stream_by_pt(GstSDPStream * stream,gconstpointer a)266 find_stream_by_pt (GstSDPStream * stream, gconstpointer a)
267 {
268   gint pt = GPOINTER_TO_INT (a);
269 
270   if (stream->pt == pt)
271     return 0;
272 
273   return -1;
274 }
275 
276 static gint
find_stream_by_udpsrc(GstSDPStream * stream,gconstpointer a)277 find_stream_by_udpsrc (GstSDPStream * stream, gconstpointer a)
278 {
279   GstElement *src = (GstElement *) a;
280 
281   if (stream->udpsrc[0] == src)
282     return 0;
283   if (stream->udpsrc[1] == src)
284     return 0;
285 
286   return -1;
287 }
288 
289 static GstSDPStream *
find_stream(GstSDPDemux * demux,gconstpointer data,gconstpointer func)290 find_stream (GstSDPDemux * demux, gconstpointer data, gconstpointer func)
291 {
292   GList *lstream;
293 
294   /* find and get stream */
295   if ((lstream =
296           g_list_find_custom (demux->streams, data, (GCompareFunc) func)))
297     return (GstSDPStream *) lstream->data;
298 
299   return NULL;
300 }
301 
302 static void
gst_sdp_demux_stream_free(GstSDPDemux * demux,GstSDPStream * stream)303 gst_sdp_demux_stream_free (GstSDPDemux * demux, GstSDPStream * stream)
304 {
305   gint i;
306 
307   GST_DEBUG_OBJECT (demux, "free stream %p", stream);
308 
309   if (stream->caps)
310     gst_caps_unref (stream->caps);
311 
312   for (i = 0; i < 2; i++) {
313     GstElement *udpsrc = stream->udpsrc[i];
314 
315     if (udpsrc) {
316       gst_element_set_state (udpsrc, GST_STATE_NULL);
317       gst_bin_remove (GST_BIN_CAST (demux), udpsrc);
318       stream->udpsrc[i] = NULL;
319     }
320   }
321   if (stream->udpsink) {
322     gst_element_set_state (stream->udpsink, GST_STATE_NULL);
323     gst_bin_remove (GST_BIN_CAST (demux), stream->udpsink);
324     stream->udpsink = NULL;
325   }
326   if (stream->srcpad) {
327     gst_pad_set_active (stream->srcpad, FALSE);
328     if (stream->added) {
329       gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->srcpad);
330       stream->added = FALSE;
331     }
332     stream->srcpad = NULL;
333   }
334   g_free (stream);
335 }
336 
337 static gboolean
is_multicast_address(const gchar * host_name)338 is_multicast_address (const gchar * host_name)
339 {
340   GInetAddress *addr;
341   GResolver *resolver = NULL;
342   gboolean ret = FALSE;
343 
344   addr = g_inet_address_new_from_string (host_name);
345   if (!addr) {
346     GList *results;
347 
348     resolver = g_resolver_get_default ();
349     results = g_resolver_lookup_by_name (resolver, host_name, NULL, NULL);
350     if (!results)
351       goto out;
352     addr = G_INET_ADDRESS (g_object_ref (results->data));
353 
354     g_resolver_free_addresses (results);
355   }
356   g_assert (addr != NULL);
357 
358   ret = g_inet_address_get_is_multicast (addr);
359 
360 out:
361   if (resolver)
362     g_object_unref (resolver);
363   if (addr)
364     g_object_unref (addr);
365   return ret;
366 }
367 
368 static GstSDPStream *
gst_sdp_demux_create_stream(GstSDPDemux * demux,GstSDPMessage * sdp,gint idx)369 gst_sdp_demux_create_stream (GstSDPDemux * demux, GstSDPMessage * sdp, gint idx)
370 {
371   GstSDPStream *stream;
372   const gchar *payload;
373   const GstSDPMedia *media;
374   const GstSDPConnection *conn;
375 
376   /* get media, should not return NULL */
377   media = gst_sdp_message_get_media (sdp, idx);
378   if (media == NULL)
379     return NULL;
380 
381   stream = g_new0 (GstSDPStream, 1);
382   stream->parent = demux;
383   /* we mark the pad as not linked, we will mark it as OK when we add the pad to
384    * the element. */
385   stream->last_ret = GST_FLOW_OK;
386   stream->added = FALSE;
387   stream->disabled = FALSE;
388   stream->id = demux->numstreams++;
389   stream->eos = FALSE;
390 
391   /* we must have a payload. No payload means we cannot create caps */
392   /* FIXME, handle multiple formats. */
393   if ((payload = gst_sdp_media_get_format (media, 0))) {
394     GstStructure *s;
395 
396     stream->pt = atoi (payload);
397     /* convert caps */
398     stream->caps = gst_sdp_media_get_caps_from_media (media, stream->pt);
399 
400     s = gst_caps_get_structure (stream->caps, 0);
401     gst_structure_set_name (s, "application/x-rtp");
402 
403     if (stream->pt >= 96) {
404       /* If we have a dynamic payload type, see if we have a stream with the
405        * same payload number. If there is one, they are part of the same
406        * container and we only need to add one pad. */
407       if (find_stream (demux, GINT_TO_POINTER (stream->pt),
408               (gpointer) find_stream_by_pt)) {
409         stream->container = TRUE;
410       }
411     }
412   }
413   if (!(conn = gst_sdp_media_get_connection (media, 0))) {
414     if (!(conn = gst_sdp_message_get_connection (sdp)))
415       goto no_connection;
416   }
417 
418   if (!conn->address)
419     goto no_connection;
420 
421   stream->destination = conn->address;
422   stream->ttl = conn->ttl;
423   stream->multicast = is_multicast_address (stream->destination);
424 
425   stream->rtp_port = gst_sdp_media_get_port (media);
426   if (gst_sdp_media_get_attribute_val (media, "rtcp")) {
427     /* FIXME, RFC 3605 */
428     stream->rtcp_port = stream->rtp_port + 1;
429   } else {
430     stream->rtcp_port = stream->rtp_port + 1;
431   }
432 
433   GST_DEBUG_OBJECT (demux, "stream %d, (%p)", stream->id, stream);
434   GST_DEBUG_OBJECT (demux, " pt: %d", stream->pt);
435   GST_DEBUG_OBJECT (demux, " container: %d", stream->container);
436   GST_DEBUG_OBJECT (demux, " caps: %" GST_PTR_FORMAT, stream->caps);
437 
438   /* we keep track of all streams */
439   demux->streams = g_list_append (demux->streams, stream);
440 
441   return stream;
442 
443   /* ERRORS */
444 no_connection:
445   {
446     gst_sdp_demux_stream_free (demux, stream);
447     return NULL;
448   }
449 }
450 
451 static void
gst_sdp_demux_cleanup(GstSDPDemux * demux)452 gst_sdp_demux_cleanup (GstSDPDemux * demux)
453 {
454   GList *walk;
455 
456   GST_DEBUG_OBJECT (demux, "cleanup");
457 
458   for (walk = demux->streams; walk; walk = g_list_next (walk)) {
459     GstSDPStream *stream = (GstSDPStream *) walk->data;
460 
461     gst_sdp_demux_stream_free (demux, stream);
462   }
463   g_list_free (demux->streams);
464   demux->streams = NULL;
465   if (demux->session) {
466     if (demux->session_sig_id) {
467       g_signal_handler_disconnect (demux->session, demux->session_sig_id);
468       demux->session_sig_id = 0;
469     }
470     if (demux->session_nmp_id) {
471       g_signal_handler_disconnect (demux->session, demux->session_nmp_id);
472       demux->session_nmp_id = 0;
473     }
474     if (demux->session_ptmap_id) {
475       g_signal_handler_disconnect (demux->session, demux->session_ptmap_id);
476       demux->session_ptmap_id = 0;
477     }
478     gst_element_set_state (demux->session, GST_STATE_NULL);
479     gst_bin_remove (GST_BIN_CAST (demux), demux->session);
480     demux->session = NULL;
481   }
482   demux->numstreams = 0;
483 }
484 
485 /* this callback is called when the session manager generated a new src pad with
486  * payloaded RTP packets. We simply ghost the pad here. */
487 static void
new_session_pad(GstElement * session,GstPad * pad,GstSDPDemux * demux)488 new_session_pad (GstElement * session, GstPad * pad, GstSDPDemux * demux)
489 {
490   gchar *name, *pad_name;
491   GstPadTemplate *template;
492   gint id, ssrc, pt;
493   GList *lstream;
494   GstSDPStream *stream;
495   gboolean all_added;
496 
497   GST_DEBUG_OBJECT (demux, "got new session pad %" GST_PTR_FORMAT, pad);
498 
499   GST_SDP_STREAM_LOCK (demux);
500   /* find stream */
501   name = gst_object_get_name (GST_OBJECT_CAST (pad));
502   if (sscanf (name, "recv_rtp_src_%u_%u_%u", &id, &ssrc, &pt) != 3)
503     goto unknown_stream;
504 
505   GST_DEBUG_OBJECT (demux, "stream: %u, SSRC %d, PT %d", id, ssrc, pt);
506 
507   stream =
508       find_stream (demux, GINT_TO_POINTER (id), (gpointer) find_stream_by_id);
509   if (stream == NULL)
510     goto unknown_stream;
511 
512   /* no need for a timeout anymore now */
513   g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout", (guint64) 0, NULL);
514 
515   pad_name = g_strdup_printf ("stream_%u", stream->id);
516   /* create a new pad we will use to stream to */
517   template = gst_static_pad_template_get (&rtptemplate);
518   stream->srcpad = gst_ghost_pad_new_from_template (pad_name, pad, template);
519   gst_object_unref (template);
520   g_free (name);
521   g_free (pad_name);
522 
523   stream->added = TRUE;
524   gst_pad_set_active (stream->srcpad, TRUE);
525   gst_element_add_pad (GST_ELEMENT_CAST (demux), stream->srcpad);
526 
527   /* check if we added all streams */
528   all_added = TRUE;
529   for (lstream = demux->streams; lstream; lstream = g_list_next (lstream)) {
530     stream = (GstSDPStream *) lstream->data;
531     /* a container stream only needs one pad added. Also disabled streams don't
532      * count */
533     if (!stream->container && !stream->disabled && !stream->added) {
534       all_added = FALSE;
535       break;
536     }
537   }
538   GST_SDP_STREAM_UNLOCK (demux);
539 
540   if (all_added) {
541     GST_DEBUG_OBJECT (demux, "We added all streams");
542     /* when we get here, all stream are added and we can fire the no-more-pads
543      * signal. */
544     gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
545   }
546 
547   return;
548 
549   /* ERRORS */
550 unknown_stream:
551   {
552     GST_DEBUG_OBJECT (demux, "ignoring unknown stream");
553     GST_SDP_STREAM_UNLOCK (demux);
554     g_free (name);
555     return;
556   }
557 }
558 
559 static void
rtsp_session_pad_added(GstElement * session,GstPad * pad,GstSDPDemux * demux)560 rtsp_session_pad_added (GstElement * session, GstPad * pad, GstSDPDemux * demux)
561 {
562   GstPad *srcpad = NULL;
563   gchar *name;
564 
565   GST_DEBUG_OBJECT (demux, "got new session pad %" GST_PTR_FORMAT, pad);
566 
567   name = gst_pad_get_name (pad);
568   srcpad = gst_ghost_pad_new (name, pad);
569   g_free (name);
570 
571   gst_pad_set_active (srcpad, TRUE);
572   gst_element_add_pad (GST_ELEMENT_CAST (demux), srcpad);
573 }
574 
575 static void
rtsp_session_no_more_pads(GstElement * session,GstSDPDemux * demux)576 rtsp_session_no_more_pads (GstElement * session, GstSDPDemux * demux)
577 {
578   GST_DEBUG_OBJECT (demux, "got no-more-pads");
579   gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
580 }
581 
582 static GstCaps *
request_pt_map(GstElement * sess,guint session,guint pt,GstSDPDemux * demux)583 request_pt_map (GstElement * sess, guint session, guint pt, GstSDPDemux * demux)
584 {
585   GstSDPStream *stream;
586   GstCaps *caps;
587 
588   GST_DEBUG_OBJECT (demux, "getting pt map for pt %d in session %d", pt,
589       session);
590 
591   GST_SDP_STREAM_LOCK (demux);
592   stream =
593       find_stream (demux, GINT_TO_POINTER (session),
594       (gpointer) find_stream_by_id);
595   if (!stream)
596     goto unknown_stream;
597 
598   caps = stream->caps;
599   if (caps)
600     gst_caps_ref (caps);
601   GST_SDP_STREAM_UNLOCK (demux);
602 
603   return caps;
604 
605 unknown_stream:
606   {
607     GST_DEBUG_OBJECT (demux, "unknown stream %d", session);
608     GST_SDP_STREAM_UNLOCK (demux);
609     return NULL;
610   }
611 }
612 
613 static void
gst_sdp_demux_do_stream_eos(GstSDPDemux * demux,guint session)614 gst_sdp_demux_do_stream_eos (GstSDPDemux * demux, guint session)
615 {
616   GstSDPStream *stream;
617 
618   GST_DEBUG_OBJECT (demux, "setting stream for session %u to EOS", session);
619 
620   /* get stream for session */
621   stream =
622       find_stream (demux, GINT_TO_POINTER (session),
623       (gpointer) find_stream_by_id);
624   if (!stream)
625     goto unknown_stream;
626 
627   if (stream->eos)
628     goto was_eos;
629 
630   stream->eos = TRUE;
631   gst_sdp_demux_stream_push_event (demux, stream, gst_event_new_eos ());
632   return;
633 
634   /* ERRORS */
635 unknown_stream:
636   {
637     GST_DEBUG_OBJECT (demux, "unknown stream for session %u", session);
638     return;
639   }
640 was_eos:
641   {
642     GST_DEBUG_OBJECT (demux, "stream for session %u was already EOS", session);
643     return;
644   }
645 }
646 
647 static void
on_bye_ssrc(GstElement * manager,guint session,guint32 ssrc,GstSDPDemux * demux)648 on_bye_ssrc (GstElement * manager, guint session, guint32 ssrc,
649     GstSDPDemux * demux)
650 {
651   GST_DEBUG_OBJECT (demux, "SSRC %08x in session %u received BYE", ssrc,
652       session);
653 
654   gst_sdp_demux_do_stream_eos (demux, session);
655 }
656 
657 static void
on_timeout(GstElement * manager,guint session,guint32 ssrc,GstSDPDemux * demux)658 on_timeout (GstElement * manager, guint session, guint32 ssrc,
659     GstSDPDemux * demux)
660 {
661   GST_DEBUG_OBJECT (demux, "SSRC %08x in session %u timed out", ssrc, session);
662 
663   gst_sdp_demux_do_stream_eos (demux, session);
664 }
665 
666 /* try to get and configure a manager */
667 static gboolean
gst_sdp_demux_configure_manager(GstSDPDemux * demux,char * rtsp_sdp)668 gst_sdp_demux_configure_manager (GstSDPDemux * demux, char *rtsp_sdp)
669 {
670   /* configure the session manager */
671   if (rtsp_sdp != NULL) {
672     if (!(demux->session = gst_element_factory_make ("rtspsrc", NULL)))
673       goto rtspsrc_failed;
674 
675     g_object_set (demux->session, "location", rtsp_sdp, NULL);
676 
677     GST_DEBUG_OBJECT (demux, "connect to signals on rtspsrc");
678     demux->session_sig_id =
679         g_signal_connect (demux->session, "pad-added",
680         (GCallback) rtsp_session_pad_added, demux);
681     demux->session_nmp_id =
682         g_signal_connect (demux->session, "no-more-pads",
683         (GCallback) rtsp_session_no_more_pads, demux);
684   } else {
685     if (!(demux->session = gst_element_factory_make ("rtpbin", NULL)))
686       goto manager_failed;
687 
688     /* connect to signals if we did not already do so */
689     GST_DEBUG_OBJECT (demux, "connect to signals on session manager");
690     demux->session_sig_id =
691         g_signal_connect (demux->session, "pad-added",
692         (GCallback) new_session_pad, demux);
693     demux->session_ptmap_id =
694         g_signal_connect (demux->session, "request-pt-map",
695         (GCallback) request_pt_map, demux);
696     g_signal_connect (demux->session, "on-bye-ssrc", (GCallback) on_bye_ssrc,
697         demux);
698     g_signal_connect (demux->session, "on-bye-timeout", (GCallback) on_timeout,
699         demux);
700     g_signal_connect (demux->session, "on-timeout", (GCallback) on_timeout,
701         demux);
702   }
703 
704   g_object_set (demux->session, "latency", demux->latency, NULL);
705 
706   /* we manage this element */
707   gst_bin_add (GST_BIN_CAST (demux), demux->session);
708 
709   return TRUE;
710 
711   /* ERRORS */
712 manager_failed:
713   {
714     GST_DEBUG_OBJECT (demux, "no session manager element gstrtpbin found");
715     return FALSE;
716   }
717 rtspsrc_failed:
718   {
719     GST_DEBUG_OBJECT (demux, "no manager element rtspsrc found");
720     return FALSE;
721   }
722 }
723 
724 static gboolean
gst_sdp_demux_stream_configure_udp(GstSDPDemux * demux,GstSDPStream * stream)725 gst_sdp_demux_stream_configure_udp (GstSDPDemux * demux, GstSDPStream * stream)
726 {
727   gchar *uri, *name;
728   const gchar *destination;
729   GstPad *pad;
730 
731   GST_DEBUG_OBJECT (demux, "creating UDP sources for multicast");
732 
733   /* if the destination is not a multicast address, we just want to listen on
734    * our local ports */
735   if (!stream->multicast)
736     destination = "0.0.0.0";
737   else
738     destination = stream->destination;
739 
740   /* creating UDP source */
741   if (stream->rtp_port != -1) {
742     GST_DEBUG_OBJECT (demux, "receiving RTP from %s:%d", destination,
743         stream->rtp_port);
744 
745     uri = g_strdup_printf ("udp://%s:%d", destination, stream->rtp_port);
746     stream->udpsrc[0] =
747         gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
748     g_free (uri);
749     if (stream->udpsrc[0] == NULL)
750       goto no_element;
751 
752     /* take ownership */
753     gst_bin_add (GST_BIN_CAST (demux), stream->udpsrc[0]);
754 
755     GST_DEBUG_OBJECT (demux,
756         "setting up UDP source with timeout %" G_GINT64_FORMAT,
757         demux->udp_timeout);
758 
759     /* configure a timeout on the UDP port. When the timeout message is
760      * posted, we assume UDP transport is not possible. */
761     g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout",
762         demux->udp_timeout * 1000, NULL);
763 
764     /* get output pad of the UDP source. */
765     pad = gst_element_get_static_pad (stream->udpsrc[0], "src");
766 
767     name = g_strdup_printf ("recv_rtp_sink_%u", stream->id);
768     stream->channelpad[0] = gst_element_get_request_pad (demux->session, name);
769     g_free (name);
770 
771     GST_DEBUG_OBJECT (demux, "connecting RTP source 0 to manager");
772     /* configure for UDP delivery, we need to connect the UDP pads to
773      * the session plugin. */
774     gst_pad_link (pad, stream->channelpad[0]);
775     gst_object_unref (pad);
776 
777     /* change state */
778     gst_element_set_state (stream->udpsrc[0], GST_STATE_PAUSED);
779   }
780 
781   /* creating another UDP source */
782   if (stream->rtcp_port != -1) {
783     GST_DEBUG_OBJECT (demux, "receiving RTCP from %s:%d", destination,
784         stream->rtcp_port);
785     uri = g_strdup_printf ("udp://%s:%d", destination, stream->rtcp_port);
786     stream->udpsrc[1] =
787         gst_element_make_from_uri (GST_URI_SRC, uri, NULL, NULL);
788     g_free (uri);
789     if (stream->udpsrc[1] == NULL)
790       goto no_element;
791 
792     /* take ownership */
793     gst_bin_add (GST_BIN_CAST (demux), stream->udpsrc[1]);
794 
795     GST_DEBUG_OBJECT (demux, "connecting RTCP source to manager");
796 
797     name = g_strdup_printf ("recv_rtcp_sink_%u", stream->id);
798     stream->channelpad[1] = gst_element_get_request_pad (demux->session, name);
799     g_free (name);
800 
801     pad = gst_element_get_static_pad (stream->udpsrc[1], "src");
802     gst_pad_link (pad, stream->channelpad[1]);
803     gst_object_unref (pad);
804 
805     gst_element_set_state (stream->udpsrc[1], GST_STATE_PAUSED);
806   }
807   return TRUE;
808 
809   /* ERRORS */
810 no_element:
811   {
812     GST_DEBUG_OBJECT (demux, "no UDP source element found");
813     return FALSE;
814   }
815 }
816 
817 /* configure the UDP sink back to the server for status reports */
818 static gboolean
gst_sdp_demux_stream_configure_udp_sink(GstSDPDemux * demux,GstSDPStream * stream)819 gst_sdp_demux_stream_configure_udp_sink (GstSDPDemux * demux,
820     GstSDPStream * stream)
821 {
822   GstPad *pad, *sinkpad;
823   gint port;
824   GSocket *socket;
825   gchar *destination, *uri, *name;
826 
827   /* get destination and port */
828   port = stream->rtcp_port;
829   destination = stream->destination;
830 
831   GST_DEBUG_OBJECT (demux, "configure UDP sink for %s:%d", destination, port);
832 
833   uri = g_strdup_printf ("udp://%s:%d", destination, port);
834   stream->udpsink = gst_element_make_from_uri (GST_URI_SINK, uri, NULL, NULL);
835   g_free (uri);
836   if (stream->udpsink == NULL)
837     goto no_sink_element;
838 
839   /* we clear all destinations because we don't really know where to send the
840    * RTCP to and we want to avoid sending it to our own ports.
841    * FIXME when we get an RTCP packet from the sender, we could look at its
842    * source port and address and try to send RTCP there. */
843   if (!stream->multicast)
844     g_signal_emit_by_name (stream->udpsink, "clear");
845 
846   g_object_set (G_OBJECT (stream->udpsink), "auto-multicast", FALSE, NULL);
847   g_object_set (G_OBJECT (stream->udpsink), "loop", FALSE, NULL);
848   /* no sync needed */
849   g_object_set (G_OBJECT (stream->udpsink), "sync", FALSE, NULL);
850   /* no async state changes needed */
851   g_object_set (G_OBJECT (stream->udpsink), "async", FALSE, NULL);
852 
853   if (stream->udpsrc[1]) {
854     /* configure socket, we give it the same UDP socket as the udpsrc for RTCP
855      * because some servers check the port number of where it sends RTCP to identify
856      * the RTCP packets it receives */
857     g_object_get (G_OBJECT (stream->udpsrc[1]), "used_socket", &socket, NULL);
858     GST_DEBUG_OBJECT (demux, "UDP src has socket %p", socket);
859     /* configure socket and make sure udpsink does not close it when shutting
860      * down, it belongs to udpsrc after all. */
861     g_object_set (G_OBJECT (stream->udpsink), "socket", socket, NULL);
862     g_object_set (G_OBJECT (stream->udpsink), "close-socket", FALSE, NULL);
863     g_object_unref (socket);
864   }
865 
866   /* we keep this playing always */
867   gst_element_set_locked_state (stream->udpsink, TRUE);
868   gst_element_set_state (stream->udpsink, GST_STATE_PLAYING);
869 
870   gst_bin_add (GST_BIN_CAST (demux), stream->udpsink);
871 
872   /* get session RTCP pad */
873   name = g_strdup_printf ("send_rtcp_src_%u", stream->id);
874   pad = gst_element_get_request_pad (demux->session, name);
875   g_free (name);
876 
877   /* and link */
878   if (pad) {
879     sinkpad = gst_element_get_static_pad (stream->udpsink, "sink");
880     gst_pad_link (pad, sinkpad);
881     gst_object_unref (pad);
882     gst_object_unref (sinkpad);
883   } else {
884     /* not very fatal, we just won't be able to send RTCP */
885     GST_WARNING_OBJECT (demux, "could not get session RTCP pad");
886   }
887 
888 
889   return TRUE;
890 
891   /* ERRORS */
892 no_sink_element:
893   {
894     GST_DEBUG_OBJECT (demux, "no UDP sink element found");
895     return FALSE;
896   }
897 }
898 
899 static GstFlowReturn
gst_sdp_demux_combine_flows(GstSDPDemux * demux,GstSDPStream * stream,GstFlowReturn ret)900 gst_sdp_demux_combine_flows (GstSDPDemux * demux, GstSDPStream * stream,
901     GstFlowReturn ret)
902 {
903   GList *streams;
904 
905   /* store the value */
906   stream->last_ret = ret;
907 
908   /* if it's success we can return the value right away */
909   if (ret == GST_FLOW_OK)
910     goto done;
911 
912   /* any other error that is not-linked can be returned right
913    * away */
914   if (ret != GST_FLOW_NOT_LINKED)
915     goto done;
916 
917   /* only return NOT_LINKED if all other pads returned NOT_LINKED */
918   for (streams = demux->streams; streams; streams = g_list_next (streams)) {
919     GstSDPStream *ostream = (GstSDPStream *) streams->data;
920 
921     ret = ostream->last_ret;
922     /* some other return value (must be SUCCESS but we can return
923      * other values as well) */
924     if (ret != GST_FLOW_NOT_LINKED)
925       goto done;
926   }
927   /* if we get here, all other pads were unlinked and we return
928    * NOT_LINKED then */
929 done:
930   return ret;
931 }
932 
933 static void
gst_sdp_demux_stream_push_event(GstSDPDemux * demux,GstSDPStream * stream,GstEvent * event)934 gst_sdp_demux_stream_push_event (GstSDPDemux * demux, GstSDPStream * stream,
935     GstEvent * event)
936 {
937   /* only streams that have a connection to the outside world */
938   if (stream->srcpad == NULL)
939     goto done;
940 
941   if (stream->channelpad[0]) {
942     gst_event_ref (event);
943     gst_pad_send_event (stream->channelpad[0], event);
944   }
945 
946   if (stream->channelpad[1]) {
947     gst_event_ref (event);
948     gst_pad_send_event (stream->channelpad[1], event);
949   }
950 
951 done:
952   gst_event_unref (event);
953 }
954 
955 static void
gst_sdp_demux_handle_message(GstBin * bin,GstMessage * message)956 gst_sdp_demux_handle_message (GstBin * bin, GstMessage * message)
957 {
958   GstSDPDemux *demux;
959 
960   demux = GST_SDP_DEMUX (bin);
961 
962   switch (GST_MESSAGE_TYPE (message)) {
963     case GST_MESSAGE_ELEMENT:
964     {
965       const GstStructure *s = gst_message_get_structure (message);
966 
967       if (gst_structure_has_name (s, "GstUDPSrcTimeout")) {
968         gboolean ignore_timeout;
969 
970         GST_DEBUG_OBJECT (bin, "timeout on UDP port");
971 
972         GST_OBJECT_LOCK (demux);
973         ignore_timeout = demux->ignore_timeout;
974         demux->ignore_timeout = TRUE;
975         GST_OBJECT_UNLOCK (demux);
976 
977         /* we only act on the first udp timeout message, others are irrelevant
978          * and can be ignored. */
979         if (ignore_timeout)
980           gst_message_unref (message);
981         else {
982           GST_ELEMENT_ERROR (demux, RESOURCE, READ, (NULL),
983               ("Could not receive any UDP packets for %.4f seconds, maybe your "
984                   "firewall is blocking it.",
985                   gst_guint64_to_gdouble (demux->udp_timeout / 1000000.0)));
986         }
987         return;
988       }
989       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
990       break;
991     }
992     case GST_MESSAGE_ERROR:
993     {
994       GstObject *udpsrc;
995       GstSDPStream *stream;
996       GstFlowReturn ret;
997 
998       udpsrc = GST_MESSAGE_SRC (message);
999 
1000       GST_DEBUG_OBJECT (demux, "got error from %s", GST_ELEMENT_NAME (udpsrc));
1001 
1002       stream = find_stream (demux, udpsrc, (gpointer) find_stream_by_udpsrc);
1003       /* fatal but not our message, forward */
1004       if (!stream)
1005         goto forward;
1006 
1007       /* we ignore the RTCP udpsrc */
1008       if (stream->udpsrc[1] == GST_ELEMENT_CAST (udpsrc))
1009         goto done;
1010 
1011       /* if we get error messages from the udp sources, that's not a problem as
1012        * long as not all of them error out. We also don't really know what the
1013        * problem is, the message does not give enough detail... */
1014       ret = gst_sdp_demux_combine_flows (demux, stream, GST_FLOW_NOT_LINKED);
1015       GST_DEBUG_OBJECT (demux, "combined flows: %s", gst_flow_get_name (ret));
1016       if (ret != GST_FLOW_OK)
1017         goto forward;
1018 
1019     done:
1020       gst_message_unref (message);
1021       break;
1022 
1023     forward:
1024       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
1025       break;
1026     }
1027     default:
1028     {
1029       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
1030       break;
1031     }
1032   }
1033 }
1034 
1035 static gboolean
gst_sdp_demux_start(GstSDPDemux * demux)1036 gst_sdp_demux_start (GstSDPDemux * demux)
1037 {
1038   guint8 *data = NULL;
1039   guint size;
1040   gint i, n_streams;
1041   GstSDPMessage sdp = { 0 };
1042   GstSDPStream *stream = NULL;
1043   GList *walk;
1044   gchar *uri = NULL;
1045   GstStateChangeReturn ret;
1046 
1047   /* grab the lock so that no state change can interfere */
1048   GST_SDP_STREAM_LOCK (demux);
1049 
1050   GST_DEBUG_OBJECT (demux, "parse SDP...");
1051 
1052   size = gst_adapter_available (demux->adapter);
1053   if (size == 0)
1054     goto no_data;
1055 
1056   data = gst_adapter_take (demux->adapter, size);
1057 
1058   gst_sdp_message_init (&sdp);
1059   if (gst_sdp_message_parse_buffer (data, size, &sdp) != GST_SDP_OK)
1060     goto could_not_parse;
1061 
1062   if (demux->debug)
1063     gst_sdp_message_dump (&sdp);
1064 
1065   /* maybe this is plain RTSP DESCRIBE rtsp and we should redirect */
1066   /* look for rtsp control url */
1067   {
1068     const gchar *control;
1069 
1070     for (i = 0;; i++) {
1071       control = gst_sdp_message_get_attribute_val_n (&sdp, "control", i);
1072       if (control == NULL)
1073         break;
1074 
1075       /* only take fully qualified urls */
1076       if (g_str_has_prefix (control, "rtsp://"))
1077         break;
1078     }
1079     if (!control) {
1080       gint idx;
1081 
1082       /* try to find non-aggragate control */
1083       n_streams = gst_sdp_message_medias_len (&sdp);
1084 
1085       for (idx = 0; idx < n_streams; idx++) {
1086         const GstSDPMedia *media;
1087 
1088         /* get media, should not return NULL */
1089         media = gst_sdp_message_get_media (&sdp, idx);
1090         if (media == NULL)
1091           break;
1092 
1093         for (i = 0;; i++) {
1094           control = gst_sdp_media_get_attribute_val_n (media, "control", i);
1095           if (control == NULL)
1096             break;
1097 
1098           /* only take fully qualified urls */
1099           if (g_str_has_prefix (control, "rtsp://"))
1100             break;
1101         }
1102         /* this media has no control, exit */
1103         if (!control)
1104           break;
1105       }
1106     }
1107 
1108     if (control) {
1109       /* we have RTSP now */
1110       uri = gst_sdp_message_as_uri ("rtsp-sdp", &sdp);
1111 
1112       if (demux->redirect) {
1113         GST_INFO_OBJECT (demux, "redirect to %s", uri);
1114 
1115         gst_element_post_message (GST_ELEMENT_CAST (demux),
1116             gst_message_new_element (GST_OBJECT_CAST (demux),
1117                 gst_structure_new ("redirect",
1118                     "new-location", G_TYPE_STRING, uri, NULL)));
1119         goto sent_redirect;
1120       }
1121     }
1122   }
1123 
1124   /* we get here when we didn't do a redirect */
1125 
1126   /* try to get and configure a manager */
1127   if (!gst_sdp_demux_configure_manager (demux, uri))
1128     goto no_manager;
1129   if (!uri) {
1130     /* create streams with UDP sources and sinks */
1131     n_streams = gst_sdp_message_medias_len (&sdp);
1132     for (i = 0; i < n_streams; i++) {
1133       stream = gst_sdp_demux_create_stream (demux, &sdp, i);
1134 
1135       if (!stream)
1136         continue;
1137 
1138       GST_DEBUG_OBJECT (demux, "configuring transport for stream %p", stream);
1139 
1140       if (!gst_sdp_demux_stream_configure_udp (demux, stream))
1141         goto transport_failed;
1142       if (!gst_sdp_demux_stream_configure_udp_sink (demux, stream))
1143         goto transport_failed;
1144     }
1145 
1146     if (!demux->streams)
1147       goto no_streams;
1148   }
1149 
1150   /* set target state on session manager */
1151   /* setting rtspsrc to PLAYING may cause it to loose it that target state
1152    * along the way due to no-preroll udpsrc elements, so ...
1153    * do it in two stages here (similar to other elements) */
1154   if (demux->target > GST_STATE_PAUSED) {
1155     ret = gst_element_set_state (demux->session, GST_STATE_PAUSED);
1156     if (ret == GST_STATE_CHANGE_FAILURE)
1157       goto start_session_failure;
1158   }
1159   ret = gst_element_set_state (demux->session, demux->target);
1160   if (ret == GST_STATE_CHANGE_FAILURE)
1161     goto start_session_failure;
1162 
1163   if (!uri) {
1164     /* activate all streams */
1165     for (walk = demux->streams; walk; walk = g_list_next (walk)) {
1166       stream = (GstSDPStream *) walk->data;
1167 
1168       /* configure target state on udp sources */
1169       gst_element_set_state (stream->udpsrc[0], demux->target);
1170       gst_element_set_state (stream->udpsrc[1], demux->target);
1171     }
1172   }
1173   GST_SDP_STREAM_UNLOCK (demux);
1174   gst_sdp_message_uninit (&sdp);
1175   g_free (data);
1176 
1177   return TRUE;
1178 
1179   /* ERRORS */
1180 done:
1181   {
1182     GST_SDP_STREAM_UNLOCK (demux);
1183     gst_sdp_message_uninit (&sdp);
1184     g_free (data);
1185     return FALSE;
1186   }
1187 transport_failed:
1188   {
1189     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
1190         ("Could not create RTP stream transport."));
1191     goto done;
1192   }
1193 no_manager:
1194   {
1195     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
1196         ("Could not create RTP session manager."));
1197     goto done;
1198   }
1199 no_data:
1200   {
1201     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
1202         ("Empty SDP message."));
1203     goto done;
1204   }
1205 could_not_parse:
1206   {
1207     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
1208         ("Could not parse SDP message."));
1209     goto done;
1210   }
1211 no_streams:
1212   {
1213     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
1214         ("No streams in SDP message."));
1215     goto done;
1216   }
1217 sent_redirect:
1218   {
1219     /* avoid hanging if redirect not handled */
1220     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
1221         ("Sent RTSP redirect."));
1222     goto done;
1223   }
1224 start_session_failure:
1225   {
1226     GST_ELEMENT_ERROR (demux, STREAM, TYPE_NOT_FOUND, (NULL),
1227         ("Could not start RTP session manager."));
1228     gst_element_set_state (demux->session, GST_STATE_NULL);
1229     gst_bin_remove (GST_BIN_CAST (demux), demux->session);
1230     demux->session = NULL;
1231     goto done;
1232   }
1233 }
1234 
1235 static gboolean
gst_sdp_demux_sink_event(GstPad * pad,GstObject * parent,GstEvent * event)1236 gst_sdp_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
1237 {
1238   GstSDPDemux *demux;
1239   gboolean res = TRUE;
1240 
1241   demux = GST_SDP_DEMUX (parent);
1242 
1243   switch (GST_EVENT_TYPE (event)) {
1244     case GST_EVENT_EOS:
1245       /* when we get EOS, start parsing the SDP */
1246       res = gst_sdp_demux_start (demux);
1247       gst_event_unref (event);
1248       break;
1249     default:
1250       gst_event_unref (event);
1251       break;
1252   }
1253 
1254   return res;
1255 }
1256 
1257 static GstFlowReturn
gst_sdp_demux_sink_chain(GstPad * pad,GstObject * parent,GstBuffer * buffer)1258 gst_sdp_demux_sink_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
1259 {
1260   GstSDPDemux *demux;
1261 
1262   demux = GST_SDP_DEMUX (parent);
1263 
1264   /* push the SDP message in an adapter, we start doing something with it when
1265    * we receive EOS */
1266   gst_adapter_push (demux->adapter, buffer);
1267 
1268   return GST_FLOW_OK;
1269 }
1270 
1271 static GstStateChangeReturn
gst_sdp_demux_change_state(GstElement * element,GstStateChange transition)1272 gst_sdp_demux_change_state (GstElement * element, GstStateChange transition)
1273 {
1274   GstSDPDemux *demux;
1275   GstStateChangeReturn ret;
1276 
1277   demux = GST_SDP_DEMUX (element);
1278 
1279   GST_SDP_STREAM_LOCK (demux);
1280 
1281   switch (transition) {
1282     case GST_STATE_CHANGE_NULL_TO_READY:
1283       break;
1284     case GST_STATE_CHANGE_READY_TO_PAUSED:
1285       /* first attempt, don't ignore timeouts */
1286       gst_adapter_clear (demux->adapter);
1287       demux->ignore_timeout = FALSE;
1288       demux->target = GST_STATE_PAUSED;
1289       break;
1290     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1291       demux->target = GST_STATE_PLAYING;
1292       break;
1293     default:
1294       break;
1295   }
1296 
1297   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1298   if (ret == GST_STATE_CHANGE_FAILURE)
1299     goto done;
1300 
1301   switch (transition) {
1302     case GST_STATE_CHANGE_READY_TO_PAUSED:
1303       ret = GST_STATE_CHANGE_NO_PREROLL;
1304       break;
1305     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1306       ret = GST_STATE_CHANGE_NO_PREROLL;
1307       demux->target = GST_STATE_PAUSED;
1308       break;
1309     case GST_STATE_CHANGE_PAUSED_TO_READY:
1310       gst_sdp_demux_cleanup (demux);
1311       break;
1312     case GST_STATE_CHANGE_READY_TO_NULL:
1313       break;
1314     default:
1315       break;
1316   }
1317 
1318 done:
1319   GST_SDP_STREAM_UNLOCK (demux);
1320 
1321   return ret;
1322 }
1323