various: fix pad template leaks
[platform/upstream/gstreamer.git] / gst / rtpmanager / gstrtpssrcdemux.c
1 /* GStreamer
2  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * RTP SSRC demuxer
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 /**
23  * SECTION:element-gstrtpssrcdemux
24  *
25  * gstrtpssrcdemux acts as a demuxer for RTP packets based on the SSRC of the
26  * packets. Its main purpose is to allow an application to easily receive and
27  * decode an RTP stream with multiple SSRCs.
28  * 
29  * For each SSRC that is detected, a new pad will be created and the
30  * #GstRtpSsrcDemux::new-ssrc-pad signal will be emitted. 
31  * 
32  * <refsect2>
33  * <title>Example pipelines</title>
34  * |[
35  * gst-launch udpsrc caps="application/x-rtp" ! gstrtpssrcdemux ! fakesink
36  * ]| Takes an RTP stream and send the RTP packets with the first detected SSRC
37  * to fakesink, discarding the other SSRCs.
38  * </refsect2>
39  *
40  * Last reviewed on 2007-05-28 (0.10.5)
41  */
42
43 #ifdef HAVE_CONFIG_H
44 #include "config.h"
45 #endif
46
47 #include <string.h>
48 #include <gst/rtp/gstrtpbuffer.h>
49 #include <gst/rtp/gstrtcpbuffer.h>
50
51 #include "gstrtpbin-marshal.h"
52 #include "gstrtpssrcdemux.h"
53
54 GST_DEBUG_CATEGORY_STATIC (gst_rtp_ssrc_demux_debug);
55 #define GST_CAT_DEFAULT gst_rtp_ssrc_demux_debug
56
57 /* generic templates */
58 static GstStaticPadTemplate rtp_ssrc_demux_sink_template =
59 GST_STATIC_PAD_TEMPLATE ("sink",
60     GST_PAD_SINK,
61     GST_PAD_ALWAYS,
62     GST_STATIC_CAPS ("application/x-rtp")
63     );
64
65 static GstStaticPadTemplate rtp_ssrc_demux_rtcp_sink_template =
66 GST_STATIC_PAD_TEMPLATE ("rtcp_sink",
67     GST_PAD_SINK,
68     GST_PAD_ALWAYS,
69     GST_STATIC_CAPS ("application/x-rtcp")
70     );
71
72 static GstStaticPadTemplate rtp_ssrc_demux_src_template =
73 GST_STATIC_PAD_TEMPLATE ("src_%d",
74     GST_PAD_SRC,
75     GST_PAD_SOMETIMES,
76     GST_STATIC_CAPS ("application/x-rtp")
77     );
78
79 static GstStaticPadTemplate rtp_ssrc_demux_rtcp_src_template =
80 GST_STATIC_PAD_TEMPLATE ("rtcp_src_%d",
81     GST_PAD_SRC,
82     GST_PAD_SOMETIMES,
83     GST_STATIC_CAPS ("application/x-rtcp")
84     );
85
86 #define GST_PAD_LOCK(obj)   (g_static_rec_mutex_lock (&(obj)->padlock))
87 #define GST_PAD_UNLOCK(obj) (g_static_rec_mutex_unlock (&(obj)->padlock))
88
89 /* signals */
90 enum
91 {
92   SIGNAL_NEW_SSRC_PAD,
93   SIGNAL_REMOVED_SSRC_PAD,
94   SIGNAL_CLEAR_SSRC,
95   LAST_SIGNAL
96 };
97
98 GST_BOILERPLATE (GstRtpSsrcDemux, gst_rtp_ssrc_demux, GstElement,
99     GST_TYPE_ELEMENT);
100
101
102 /* GObject vmethods */
103 static void gst_rtp_ssrc_demux_dispose (GObject * object);
104 static void gst_rtp_ssrc_demux_finalize (GObject * object);
105
106 /* GstElement vmethods */
107 static GstStateChangeReturn gst_rtp_ssrc_demux_change_state (GstElement *
108     element, GstStateChange transition);
109
110 static void gst_rtp_ssrc_demux_clear_ssrc (GstRtpSsrcDemux * demux,
111     guint32 ssrc);
112
113 /* sinkpad stuff */
114 static GstFlowReturn gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf);
115 static gboolean gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstEvent * event);
116
117 static GstFlowReturn gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad,
118     GstBuffer * buf);
119 static gboolean gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad,
120     GstEvent * event);
121 static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links_sink (GstPad *
122     pad);
123
124 /* srcpad stuff */
125 static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event);
126 static GstIterator *gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad *
127     pad);
128 static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query);
129
130 static guint gst_rtp_ssrc_demux_signals[LAST_SIGNAL] = { 0 };
131
132 /*
133  * Item for storing GstPad <-> SSRC pairs.
134  */
135 struct _GstRtpSsrcDemuxPad
136 {
137   guint32 ssrc;
138   GstPad *rtp_pad;
139   GstCaps *caps;
140   GstPad *rtcp_pad;
141 };
142
143 /* find a src pad for a given SSRC, returns NULL if the SSRC was not found
144  */
145 static GstRtpSsrcDemuxPad *
146 find_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
147 {
148   GSList *walk;
149
150   for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
151     GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
152
153     if (pad->ssrc == ssrc)
154       return pad;
155   }
156   return NULL;
157 }
158
159 /* with PAD_LOCK */
160 static GstRtpSsrcDemuxPad *
161 find_or_create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
162 {
163   GstPad *rtp_pad, *rtcp_pad;
164   GstElementClass *klass;
165   GstPadTemplate *templ;
166   gchar *padname;
167   GstRtpSsrcDemuxPad *demuxpad;
168
169   GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc);
170
171   demuxpad = find_demux_pad_for_ssrc (demux, ssrc);
172   if (demuxpad != NULL) {
173     return demuxpad;
174   }
175
176   klass = GST_ELEMENT_GET_CLASS (demux);
177   templ = gst_element_class_get_pad_template (klass, "src_%d");
178   padname = g_strdup_printf ("src_%d", ssrc);
179   rtp_pad = gst_pad_new_from_template (templ, padname);
180   g_free (padname);
181
182   templ = gst_element_class_get_pad_template (klass, "rtcp_src_%d");
183   padname = g_strdup_printf ("rtcp_src_%d", ssrc);
184   rtcp_pad = gst_pad_new_from_template (templ, padname);
185   g_free (padname);
186
187   /* wrap in structure and add to list */
188   demuxpad = g_new0 (GstRtpSsrcDemuxPad, 1);
189   demuxpad->ssrc = ssrc;
190   demuxpad->rtp_pad = rtp_pad;
191   demuxpad->rtcp_pad = rtcp_pad;
192
193   gst_pad_set_element_private (rtp_pad, demuxpad);
194   gst_pad_set_element_private (rtcp_pad, demuxpad);
195
196   demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad);
197
198   /* copy caps from input */
199   gst_pad_set_caps (rtp_pad, GST_PAD_CAPS (demux->rtp_sink));
200   gst_pad_use_fixed_caps (rtp_pad);
201   gst_pad_set_caps (rtcp_pad, GST_PAD_CAPS (demux->rtcp_sink));
202   gst_pad_use_fixed_caps (rtcp_pad);
203
204   gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event);
205   gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query);
206   gst_pad_set_iterate_internal_links_function (rtp_pad,
207       gst_rtp_ssrc_demux_iterate_internal_links_src);
208   gst_pad_set_active (rtp_pad, TRUE);
209
210   gst_pad_set_event_function (rtcp_pad, gst_rtp_ssrc_demux_src_event);
211   gst_pad_set_iterate_internal_links_function (rtcp_pad,
212       gst_rtp_ssrc_demux_iterate_internal_links_src);
213   gst_pad_set_active (rtcp_pad, TRUE);
214
215   gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad);
216   gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad);
217
218   g_signal_emit (G_OBJECT (demux),
219       gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad);
220
221   return demuxpad;
222 }
223
224 static void
225 gst_rtp_ssrc_demux_base_init (gpointer g_class)
226 {
227   GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class);
228
229   gst_element_class_add_static_pad_template (gstelement_klass,
230       &rtp_ssrc_demux_sink_template);
231   gst_element_class_add_static_pad_template (gstelement_klass,
232       &rtp_ssrc_demux_rtcp_sink_template);
233   gst_element_class_add_static_pad_template (gstelement_klass,
234       &rtp_ssrc_demux_src_template);
235   gst_element_class_add_static_pad_template (gstelement_klass,
236       &rtp_ssrc_demux_rtcp_src_template);
237
238   gst_element_class_set_details_simple (gstelement_klass, "RTP SSRC Demux",
239       "Demux/Network/RTP",
240       "Splits RTP streams based on the SSRC",
241       "Wim Taymans <wim.taymans@gmail.com>");
242 }
243
244 static void
245 gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass)
246 {
247   GObjectClass *gobject_klass;
248   GstElementClass *gstelement_klass;
249   GstRtpSsrcDemuxClass *gstrtpssrcdemux_klass;
250
251   gobject_klass = (GObjectClass *) klass;
252   gstelement_klass = (GstElementClass *) klass;
253   gstrtpssrcdemux_klass = (GstRtpSsrcDemuxClass *) klass;
254
255   gobject_klass->dispose = gst_rtp_ssrc_demux_dispose;
256   gobject_klass->finalize = gst_rtp_ssrc_demux_finalize;
257
258   /**
259    * GstRtpSsrcDemux::new-ssrc-pad:
260    * @demux: the object which received the signal
261    * @ssrc: the SSRC of the pad
262    * @pad: the new pad.
263    *
264    * Emited when a new SSRC pad has been created.
265    */
266   gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD] =
267       g_signal_new ("new-ssrc-pad",
268       G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
269       G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, new_ssrc_pad),
270       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT,
271       G_TYPE_NONE, 2, G_TYPE_UINT, GST_TYPE_PAD);
272
273   /**
274    * GstRtpSsrcDemux::removed-ssrc-pad:
275    * @demux: the object which received the signal
276    * @ssrc: the SSRC of the pad
277    * @pad: the removed pad.
278    *
279    * Emited when a SSRC pad has been removed.
280    */
281   gst_rtp_ssrc_demux_signals[SIGNAL_REMOVED_SSRC_PAD] =
282       g_signal_new ("removed-ssrc-pad",
283       G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
284       G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, removed_ssrc_pad),
285       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT,
286       G_TYPE_NONE, 2, G_TYPE_UINT, GST_TYPE_PAD);
287
288   /**
289    * GstRtpSsrcDemux::clear-ssrc:
290    * @demux: the object which received the signal
291    * @ssrc: the SSRC of the pad
292    *
293    * Action signal to remove the pad for SSRC.
294    */
295   gst_rtp_ssrc_demux_signals[SIGNAL_CLEAR_SSRC] =
296       g_signal_new ("clear-ssrc",
297       G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
298       G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, clear_ssrc),
299       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
300
301   gstelement_klass->change_state =
302       GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_change_state);
303   gstrtpssrcdemux_klass->clear_ssrc =
304       GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_clear_ssrc);
305
306   GST_DEBUG_CATEGORY_INIT (gst_rtp_ssrc_demux_debug,
307       "rtpssrcdemux", 0, "RTP SSRC demuxer");
308 }
309
310 static void
311 gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux,
312     GstRtpSsrcDemuxClass * g_class)
313 {
314   GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
315
316   demux->rtp_sink =
317       gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
318           "sink"), "sink");
319   gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain);
320   gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event);
321   gst_pad_set_iterate_internal_links_function (demux->rtp_sink,
322       gst_rtp_ssrc_demux_iterate_internal_links_sink);
323   gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink);
324
325   demux->rtcp_sink =
326       gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
327           "rtcp_sink"), "rtcp_sink");
328   gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain);
329   gst_pad_set_event_function (demux->rtcp_sink,
330       gst_rtp_ssrc_demux_rtcp_sink_event);
331   gst_pad_set_iterate_internal_links_function (demux->rtcp_sink,
332       gst_rtp_ssrc_demux_iterate_internal_links_sink);
333   gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink);
334
335   g_static_rec_mutex_init (&demux->padlock);
336
337   gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
338 }
339
340 static void
341 gst_rtp_ssrc_demux_reset (GstRtpSsrcDemux * demux)
342 {
343   GSList *walk;
344
345   for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
346     GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data;
347
348     gst_pad_set_active (dpad->rtp_pad, FALSE);
349     gst_pad_set_active (dpad->rtcp_pad, FALSE);
350
351     gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtp_pad);
352     gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtcp_pad);
353     g_free (dpad);
354   }
355   g_slist_free (demux->srcpads);
356   demux->srcpads = NULL;
357 }
358
359 static void
360 gst_rtp_ssrc_demux_dispose (GObject * object)
361 {
362   GstRtpSsrcDemux *demux;
363
364   demux = GST_RTP_SSRC_DEMUX (object);
365
366   gst_rtp_ssrc_demux_reset (demux);
367
368   G_OBJECT_CLASS (parent_class)->dispose (object);
369 }
370
371 static void
372 gst_rtp_ssrc_demux_finalize (GObject * object)
373 {
374   GstRtpSsrcDemux *demux;
375
376   demux = GST_RTP_SSRC_DEMUX (object);
377   g_static_rec_mutex_free (&demux->padlock);
378
379   G_OBJECT_CLASS (parent_class)->finalize (object);
380 }
381
382 static void
383 gst_rtp_ssrc_demux_clear_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
384 {
385   GstRtpSsrcDemuxPad *dpad;
386
387   GST_PAD_LOCK (demux);
388   dpad = find_demux_pad_for_ssrc (demux, ssrc);
389   if (dpad == NULL) {
390     GST_PAD_UNLOCK (demux);
391     goto unknown_pad;
392   }
393
394   GST_DEBUG_OBJECT (demux, "clearing pad for SSRC %08x", ssrc);
395
396   demux->srcpads = g_slist_remove (demux->srcpads, dpad);
397   GST_PAD_UNLOCK (demux);
398
399   gst_pad_set_active (dpad->rtp_pad, FALSE);
400   gst_pad_set_active (dpad->rtcp_pad, FALSE);
401
402   g_signal_emit (G_OBJECT (demux),
403       gst_rtp_ssrc_demux_signals[SIGNAL_REMOVED_SSRC_PAD], 0, ssrc,
404       dpad->rtp_pad);
405
406   gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtp_pad);
407   gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtcp_pad);
408
409   g_free (dpad);
410
411   return;
412
413   /* ERRORS */
414 unknown_pad:
415   {
416     GST_WARNING_OBJECT (demux, "unknown SSRC %08x", ssrc);
417     return;
418   }
419 }
420
421 static gboolean
422 gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstEvent * event)
423 {
424   GstRtpSsrcDemux *demux;
425   gboolean res = FALSE;
426
427   demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
428   if (G_UNLIKELY (demux == NULL)) {
429     gst_event_unref (event);
430     return FALSE;
431   }
432
433   switch (GST_EVENT_TYPE (event)) {
434     case GST_EVENT_FLUSH_STOP:
435       gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
436     case GST_EVENT_NEWSEGMENT:
437     default:
438     {
439       GSList *walk;
440       GSList *pads = NULL;
441
442       res = TRUE;
443       /* need local snapshot of pads;
444        * should not push downstream while holding lock as that might deadlock
445        * with stuff traveling upstream tyring to get this lock while holding
446        * other (stream)lock */
447       GST_PAD_LOCK (demux);
448       for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
449         GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
450
451         pads = g_slist_prepend (pads, gst_object_ref (pad->rtp_pad));
452       }
453       GST_PAD_UNLOCK (demux);
454       for (walk = pads; walk; walk = g_slist_next (walk)) {
455         GstPad *pad = (GstPad *) walk->data;
456
457         gst_event_ref (event);
458         res &= gst_pad_push_event (pad, event);
459         gst_object_unref (pad);
460       }
461       g_slist_free (pads);
462       gst_event_unref (event);
463       break;
464     }
465   }
466
467   gst_object_unref (demux);
468   return res;
469 }
470
471 static gboolean
472 gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, GstEvent * event)
473 {
474   GstRtpSsrcDemux *demux;
475   gboolean res = FALSE;
476
477   demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
478
479   switch (GST_EVENT_TYPE (event)) {
480     case GST_EVENT_NEWSEGMENT:
481     default:
482     {
483       GSList *walk;
484       GSList *pads = NULL;
485
486       res = TRUE;
487       GST_PAD_LOCK (demux);
488       for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
489         GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
490
491         pads = g_slist_prepend (pads, gst_object_ref (pad->rtcp_pad));
492       }
493       GST_PAD_UNLOCK (demux);
494       for (walk = pads; walk; walk = g_slist_next (walk)) {
495         GstPad *pad = (GstPad *) walk->data;
496
497         gst_event_ref (event);
498         res &= gst_pad_push_event (pad, event);
499         gst_object_unref (pad);
500       }
501       g_slist_free (pads);
502       gst_event_unref (event);
503       break;
504     }
505   }
506   gst_object_unref (demux);
507   return res;
508 }
509
510 static GstFlowReturn
511 gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf)
512 {
513   GstFlowReturn ret;
514   GstRtpSsrcDemux *demux;
515   guint32 ssrc;
516   GstRtpSsrcDemuxPad *dpad;
517   GstPad *srcpad;
518
519   demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad));
520
521   if (!gst_rtp_buffer_validate (buf))
522     goto invalid_payload;
523
524   ssrc = gst_rtp_buffer_get_ssrc (buf);
525
526   GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc);
527
528   GST_PAD_LOCK (demux);
529   dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc);
530   if (dpad == NULL) {
531     GST_PAD_UNLOCK (demux);
532     goto create_failed;
533   }
534   srcpad = gst_object_ref (dpad->rtp_pad);
535   GST_PAD_UNLOCK (demux);
536
537   /* push to srcpad */
538   ret = gst_pad_push (srcpad, buf);
539
540   gst_object_unref (srcpad);
541
542   return ret;
543
544   /* ERRORS */
545 invalid_payload:
546   {
547     /* this is fatal and should be filtered earlier */
548     GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
549         ("Dropping invalid RTP payload"));
550     gst_buffer_unref (buf);
551     return GST_FLOW_ERROR;
552   }
553 create_failed:
554   {
555     GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
556         ("Could not create new pad"));
557     gst_buffer_unref (buf);
558     return GST_FLOW_ERROR;
559   }
560 }
561
562 static GstFlowReturn
563 gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf)
564 {
565   GstFlowReturn ret;
566   GstRtpSsrcDemux *demux;
567   guint32 ssrc;
568   GstRtpSsrcDemuxPad *dpad;
569   GstRTCPPacket packet;
570   GstPad *srcpad;
571
572   demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad));
573
574   if (!gst_rtcp_buffer_validate (buf))
575     goto invalid_rtcp;
576
577   if (!gst_rtcp_buffer_get_first_packet (buf, &packet))
578     goto invalid_rtcp;
579
580   /* first packet must be SR or RR or else the validate would have failed */
581   switch (gst_rtcp_packet_get_type (&packet)) {
582     case GST_RTCP_TYPE_SR:
583       /* get the ssrc so that we can route it to the right source pad */
584       gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, NULL, NULL, NULL,
585           NULL);
586       break;
587     default:
588       goto unexpected_rtcp;
589   }
590
591   GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc);
592
593   GST_PAD_LOCK (demux);
594   dpad = find_or_create_demux_pad_for_ssrc (demux, ssrc);
595   if (dpad == NULL) {
596     GST_PAD_UNLOCK (demux);
597     goto create_failed;
598   }
599   srcpad = gst_object_ref (dpad->rtcp_pad);
600   GST_PAD_UNLOCK (demux);
601
602   /* push to srcpad */
603   ret = gst_pad_push (srcpad, buf);
604
605   gst_object_unref (srcpad);
606
607   return ret;
608
609   /* ERRORS */
610 invalid_rtcp:
611   {
612     /* this is fatal and should be filtered earlier */
613     GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
614         ("Dropping invalid RTCP packet"));
615     gst_buffer_unref (buf);
616     return GST_FLOW_ERROR;
617   }
618 unexpected_rtcp:
619   {
620     GST_DEBUG_OBJECT (demux, "dropping unexpected RTCP packet");
621     gst_buffer_unref (buf);
622     return GST_FLOW_OK;
623   }
624 create_failed:
625   {
626     GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
627         ("Could not create new pad"));
628     gst_buffer_unref (buf);
629     return GST_FLOW_ERROR;
630   }
631 }
632
633 static gboolean
634 gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event)
635 {
636   GstRtpSsrcDemux *demux;
637   const GstStructure *s;
638
639   demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
640
641   switch (GST_EVENT_TYPE (event)) {
642     case GST_EVENT_CUSTOM_UPSTREAM:
643     case GST_EVENT_CUSTOM_BOTH:
644     case GST_EVENT_CUSTOM_BOTH_OOB:
645       s = gst_event_get_structure (event);
646       if (s && !gst_structure_has_field (s, "ssrc")) {
647         GSList *walk;
648
649         for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
650           GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data;
651
652           if (dpad->rtp_pad == pad || dpad->rtcp_pad == pad) {
653             event =
654                 GST_EVENT_CAST (gst_mini_object_make_writable
655                 (GST_MINI_OBJECT_CAST (event)));
656             gst_structure_set (event->structure, "ssrc", G_TYPE_UINT,
657                 dpad->ssrc, NULL);
658             break;
659           }
660         }
661       }
662       break;
663     default:
664       break;
665   }
666
667   gst_object_unref (demux);
668
669   return gst_pad_event_default (pad, event);
670 }
671
672 static GstIterator *
673 gst_rtp_ssrc_demux_iterate_internal_links_src (GstPad * pad)
674 {
675   GstRtpSsrcDemux *demux;
676   GstPad *otherpad = NULL;
677   GstIterator *it = NULL;
678   GSList *current;
679
680   demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
681
682   if (!demux)
683     return NULL;
684
685   GST_PAD_LOCK (demux);
686   for (current = demux->srcpads; current; current = g_slist_next (current)) {
687     GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) current->data;
688
689     if (pad == dpad->rtp_pad) {
690       otherpad = demux->rtp_sink;
691       break;
692     } else if (pad == dpad->rtcp_pad) {
693       otherpad = demux->rtcp_sink;
694       break;
695     }
696   }
697   it = gst_iterator_new_single (GST_TYPE_PAD, otherpad,
698       (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
699   GST_PAD_UNLOCK (demux);
700
701   gst_object_unref (demux);
702   return it;
703 }
704
705 /* Should return 0 for elements to be included */
706 static gint
707 src_pad_compare_func (gconstpointer a, gconstpointer b)
708 {
709   GstPad *pad = GST_PAD (a);
710   const gchar *prefix = b;
711   gint res = 1;
712
713   GST_OBJECT_LOCK (pad);
714   res = !GST_PAD_NAME (pad) || g_str_has_prefix (GST_PAD_NAME (pad), prefix);
715   GST_OBJECT_UNLOCK (pad);
716
717   return res;
718 }
719
720 static GstIterator *
721 gst_rtp_ssrc_demux_iterate_internal_links_sink (GstPad * pad)
722 {
723   GstRtpSsrcDemux *demux;
724   GstIterator *it = NULL;
725   const gchar *prefix = NULL;
726
727   demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
728
729   if (!demux)
730     return NULL;
731
732   if (pad == demux->rtp_sink)
733     prefix = "src_";
734   else if (pad == demux->rtcp_sink)
735     prefix = "rtcp_src_";
736   else
737     g_assert_not_reached ();
738
739   it = gst_element_iterate_src_pads (GST_ELEMENT (demux));
740
741   return gst_iterator_filter (it, src_pad_compare_func, (gpointer) prefix);
742 }
743
744
745 static gboolean
746 gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query)
747 {
748   GstRtpSsrcDemux *demux;
749   gboolean res = FALSE;
750
751   demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
752   if (G_UNLIKELY (demux == NULL))
753     return FALSE;
754
755   switch (GST_QUERY_TYPE (query)) {
756     case GST_QUERY_LATENCY:
757     {
758
759       if ((res = gst_pad_peer_query (demux->rtp_sink, query))) {
760         gboolean live;
761         GstClockTime min_latency, max_latency;
762         GstRtpSsrcDemuxPad *demuxpad;
763
764         demuxpad = gst_pad_get_element_private (pad);
765
766         gst_query_parse_latency (query, &live, &min_latency, &max_latency);
767
768         GST_DEBUG_OBJECT (demux, "peer min latency %" GST_TIME_FORMAT,
769             GST_TIME_ARGS (min_latency));
770
771         GST_DEBUG_OBJECT (demux, "latency for SSRC %08x", demuxpad->ssrc);
772
773         gst_query_set_latency (query, live, min_latency, max_latency);
774       }
775       break;
776     }
777     default:
778       res = gst_pad_query_default (pad, query);
779       break;
780   }
781   gst_object_unref (demux);
782
783   return res;
784 }
785
786 static GstStateChangeReturn
787 gst_rtp_ssrc_demux_change_state (GstElement * element,
788     GstStateChange transition)
789 {
790   GstStateChangeReturn ret;
791   GstRtpSsrcDemux *demux;
792
793   demux = GST_RTP_SSRC_DEMUX (element);
794
795   switch (transition) {
796     case GST_STATE_CHANGE_NULL_TO_READY:
797     case GST_STATE_CHANGE_READY_TO_PAUSED:
798     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
799     default:
800       break;
801   }
802
803   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
804
805   switch (transition) {
806     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
807       break;
808     case GST_STATE_CHANGE_PAUSED_TO_READY:
809       gst_rtp_ssrc_demux_reset (demux);
810       break;
811     case GST_STATE_CHANGE_READY_TO_NULL:
812     default:
813       break;
814   }
815   return ret;
816 }