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