~oah-dev/oah/gst-plugins-bad

« back to all changes in this revision

Viewing changes to gst/rtpmanager/gstrtpssrcdemux.c

  • Committer: Haakon Sporsheim
  • Date: 2009-03-12 13:52:03 UTC
  • Revision ID: haakon.sporsheim@tandberg.com-20090312135203-i5k294hgkushb0mt
Initial import of git repository: git://anongit.freedesktop.org/gstreamer/gst-plugins-bad (tag: RELEASE-0_10_10)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
static GstElementDetails gst_rtp_ssrc_demux_details = {
 
87
  "RTP SSRC Demux",
 
88
  "Demux/Network/RTP",
 
89
  "Splits RTP streams based on the SSRC",
 
90
  "Wim Taymans <wim.taymans@gmail.com>"
 
91
};
 
92
 
 
93
#define GST_PAD_LOCK(obj)   (g_mutex_lock ((obj)->padlock))
 
94
#define GST_PAD_UNLOCK(obj) (g_mutex_unlock ((obj)->padlock))
 
95
 
 
96
/* signals */
 
97
enum
 
98
{
 
99
  SIGNAL_NEW_SSRC_PAD,
 
100
  LAST_SIGNAL
 
101
};
 
102
 
 
103
GST_BOILERPLATE (GstRtpSsrcDemux, gst_rtp_ssrc_demux, GstElement,
 
104
    GST_TYPE_ELEMENT);
 
105
 
 
106
 
 
107
/* GObject vmethods */
 
108
static void gst_rtp_ssrc_demux_dispose (GObject * object);
 
109
static void gst_rtp_ssrc_demux_finalize (GObject * object);
 
110
 
 
111
/* GstElement vmethods */
 
112
static GstStateChangeReturn gst_rtp_ssrc_demux_change_state (GstElement *
 
113
    element, GstStateChange transition);
 
114
 
 
115
/* sinkpad stuff */
 
116
static GstFlowReturn gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf);
 
117
static gboolean gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstEvent * event);
 
118
 
 
119
static GstFlowReturn gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad,
 
120
    GstBuffer * buf);
 
121
static gboolean gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad,
 
122
    GstEvent * event);
 
123
 
 
124
/* srcpad stuff */
 
125
static gboolean gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event);
 
126
static GList *gst_rtp_ssrc_demux_internal_links (GstPad * pad);
 
127
static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query);
 
128
 
 
129
static guint gst_rtp_ssrc_demux_signals[LAST_SIGNAL] = { 0 };
 
130
 
 
131
/*
 
132
 * Item for storing GstPad <-> SSRC pairs.
 
133
 */
 
134
struct _GstRtpSsrcDemuxPad
 
135
{
 
136
  guint32 ssrc;
 
137
  GstPad *rtp_pad;
 
138
  GstCaps *caps;
 
139
  GstPad *rtcp_pad;
 
140
};
 
141
 
 
142
/* find a src pad for a given SSRC, returns NULL if the SSRC was not found
 
143
 */
 
144
static GstRtpSsrcDemuxPad *
 
145
find_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc)
 
146
{
 
147
  GSList *walk;
 
148
 
 
149
  for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
 
150
    GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
 
151
 
 
152
    if (pad->ssrc == ssrc)
 
153
      return pad;
 
154
  }
 
155
  return NULL;
 
156
}
 
157
 
 
158
/* with PAD_LOCK */
 
159
static GstRtpSsrcDemuxPad *
 
160
create_demux_pad_for_ssrc (GstRtpSsrcDemux * demux, guint32 ssrc,
 
161
    GstClockTime timestamp)
 
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
  klass = GST_ELEMENT_GET_CLASS (demux);
 
172
  templ = gst_element_class_get_pad_template (klass, "src_%d");
 
173
  padname = g_strdup_printf ("src_%d", ssrc);
 
174
  rtp_pad = gst_pad_new_from_template (templ, padname);
 
175
  g_free (padname);
 
176
 
 
177
  templ = gst_element_class_get_pad_template (klass, "rtcp_src_%d");
 
178
  padname = g_strdup_printf ("rtcp_src_%d", ssrc);
 
179
  rtcp_pad = gst_pad_new_from_template (templ, padname);
 
180
  g_free (padname);
 
181
 
 
182
  /* we use the first timestamp received to calculate the difference between
 
183
   * timestamps on all streams */
 
184
  GST_DEBUG_OBJECT (demux, "SSRC %08x, first timestamp %" GST_TIME_FORMAT,
 
185
      ssrc, GST_TIME_ARGS (timestamp));
 
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_DEBUG_OBJECT (demux, "first timestamp %" GST_TIME_FORMAT,
 
194
      GST_TIME_ARGS (timestamp));
 
195
 
 
196
  gst_pad_set_element_private (rtp_pad, demuxpad);
 
197
  gst_pad_set_element_private (rtcp_pad, demuxpad);
 
198
 
 
199
  demux->srcpads = g_slist_prepend (demux->srcpads, demuxpad);
 
200
 
 
201
  /* copy caps from input */
 
202
  gst_pad_set_caps (rtp_pad, GST_PAD_CAPS (demux->rtp_sink));
 
203
  gst_pad_use_fixed_caps (rtp_pad);
 
204
  gst_pad_set_caps (rtcp_pad, GST_PAD_CAPS (demux->rtcp_sink));
 
205
  gst_pad_use_fixed_caps (rtcp_pad);
 
206
 
 
207
  gst_pad_set_event_function (rtp_pad, gst_rtp_ssrc_demux_src_event);
 
208
  gst_pad_set_query_function (rtp_pad, gst_rtp_ssrc_demux_src_query);
 
209
  gst_pad_set_internal_link_function (rtp_pad,
 
210
      gst_rtp_ssrc_demux_internal_links);
 
211
  gst_pad_set_active (rtp_pad, TRUE);
 
212
 
 
213
  gst_pad_set_internal_link_function (rtcp_pad,
 
214
      gst_rtp_ssrc_demux_internal_links);
 
215
  gst_pad_set_active (rtcp_pad, TRUE);
 
216
 
 
217
  gst_element_add_pad (GST_ELEMENT_CAST (demux), rtp_pad);
 
218
  gst_element_add_pad (GST_ELEMENT_CAST (demux), rtcp_pad);
 
219
 
 
220
  g_signal_emit (G_OBJECT (demux),
 
221
      gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD], 0, ssrc, rtp_pad);
 
222
 
 
223
  return demuxpad;
 
224
}
 
225
 
 
226
static void
 
227
gst_rtp_ssrc_demux_base_init (gpointer g_class)
 
228
{
 
229
  GstElementClass *gstelement_klass = GST_ELEMENT_CLASS (g_class);
 
230
 
 
231
  gst_element_class_add_pad_template (gstelement_klass,
 
232
      gst_static_pad_template_get (&rtp_ssrc_demux_sink_template));
 
233
  gst_element_class_add_pad_template (gstelement_klass,
 
234
      gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_sink_template));
 
235
  gst_element_class_add_pad_template (gstelement_klass,
 
236
      gst_static_pad_template_get (&rtp_ssrc_demux_src_template));
 
237
  gst_element_class_add_pad_template (gstelement_klass,
 
238
      gst_static_pad_template_get (&rtp_ssrc_demux_rtcp_src_template));
 
239
 
 
240
  gst_element_class_set_details (gstelement_klass, &gst_rtp_ssrc_demux_details);
 
241
}
 
242
 
 
243
static void
 
244
gst_rtp_ssrc_demux_class_init (GstRtpSsrcDemuxClass * klass)
 
245
{
 
246
  GObjectClass *gobject_klass;
 
247
  GstElementClass *gstelement_klass;
 
248
 
 
249
  gobject_klass = (GObjectClass *) klass;
 
250
  gstelement_klass = (GstElementClass *) klass;
 
251
 
 
252
  gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_dispose);
 
253
  gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_finalize);
 
254
 
 
255
  /**
 
256
   * GstRtpSsrcDemux::new-ssrc-pad:
 
257
   * @demux: the object which received the signal
 
258
   * @ssrc: the SSRC of the pad
 
259
   * @pad: the new pad.
 
260
   *
 
261
   * Emited when a new SSRC pad has been created.
 
262
   */
 
263
  gst_rtp_ssrc_demux_signals[SIGNAL_NEW_SSRC_PAD] =
 
264
      g_signal_new ("new-ssrc-pad",
 
265
      G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
 
266
      G_STRUCT_OFFSET (GstRtpSsrcDemuxClass, new_ssrc_pad),
 
267
      NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_OBJECT,
 
268
      G_TYPE_NONE, 2, G_TYPE_UINT, GST_TYPE_PAD);
 
269
 
 
270
  gstelement_klass->change_state =
 
271
      GST_DEBUG_FUNCPTR (gst_rtp_ssrc_demux_change_state);
 
272
 
 
273
  GST_DEBUG_CATEGORY_INIT (gst_rtp_ssrc_demux_debug,
 
274
      "rtpssrcdemux", 0, "RTP SSRC demuxer");
 
275
}
 
276
 
 
277
static void
 
278
gst_rtp_ssrc_demux_init (GstRtpSsrcDemux * demux,
 
279
    GstRtpSsrcDemuxClass * g_class)
 
280
{
 
281
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (demux);
 
282
 
 
283
  demux->rtp_sink =
 
284
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
 
285
          "sink"), "sink");
 
286
  gst_pad_set_chain_function (demux->rtp_sink, gst_rtp_ssrc_demux_chain);
 
287
  gst_pad_set_event_function (demux->rtp_sink, gst_rtp_ssrc_demux_sink_event);
 
288
  gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtp_sink);
 
289
 
 
290
  demux->rtcp_sink =
 
291
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
 
292
          "rtcp_sink"), "rtcp_sink");
 
293
  gst_pad_set_chain_function (demux->rtcp_sink, gst_rtp_ssrc_demux_rtcp_chain);
 
294
  gst_pad_set_event_function (demux->rtcp_sink,
 
295
      gst_rtp_ssrc_demux_rtcp_sink_event);
 
296
  gst_element_add_pad (GST_ELEMENT_CAST (demux), demux->rtcp_sink);
 
297
 
 
298
  demux->padlock = g_mutex_new ();
 
299
 
 
300
  gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
 
301
}
 
302
 
 
303
static void
 
304
gst_rtp_ssrc_demux_reset (GstRtpSsrcDemux * demux)
 
305
{
 
306
  GSList *walk;
 
307
 
 
308
  for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
 
309
    GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data;
 
310
 
 
311
    gst_pad_set_active (dpad->rtp_pad, FALSE);
 
312
    gst_pad_set_active (dpad->rtcp_pad, FALSE);
 
313
 
 
314
    gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtp_pad);
 
315
    gst_element_remove_pad (GST_ELEMENT_CAST (demux), dpad->rtcp_pad);
 
316
    g_free (dpad);
 
317
  }
 
318
  g_slist_free (demux->srcpads);
 
319
  demux->srcpads = NULL;
 
320
}
 
321
 
 
322
static void
 
323
gst_rtp_ssrc_demux_dispose (GObject * object)
 
324
{
 
325
  GstRtpSsrcDemux *demux;
 
326
 
 
327
  demux = GST_RTP_SSRC_DEMUX (object);
 
328
 
 
329
  gst_rtp_ssrc_demux_reset (demux);
 
330
 
 
331
  G_OBJECT_CLASS (parent_class)->dispose (object);
 
332
}
 
333
 
 
334
static void
 
335
gst_rtp_ssrc_demux_finalize (GObject * object)
 
336
{
 
337
  GstRtpSsrcDemux *demux;
 
338
 
 
339
  demux = GST_RTP_SSRC_DEMUX (object);
 
340
  g_mutex_free (demux->padlock);
 
341
 
 
342
  G_OBJECT_CLASS (parent_class)->finalize (object);
 
343
}
 
344
 
 
345
static gboolean
 
346
gst_rtp_ssrc_demux_sink_event (GstPad * pad, GstEvent * event)
 
347
{
 
348
  GstRtpSsrcDemux *demux;
 
349
  gboolean res = FALSE;
 
350
 
 
351
  demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
 
352
 
 
353
  switch (GST_EVENT_TYPE (event)) {
 
354
    case GST_EVENT_FLUSH_STOP:
 
355
      gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
 
356
    case GST_EVENT_NEWSEGMENT:
 
357
    default:
 
358
    {
 
359
      GSList *walk;
 
360
 
 
361
      res = TRUE;
 
362
      GST_PAD_LOCK (demux);
 
363
      for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
 
364
        GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
 
365
 
 
366
        gst_event_ref (event);
 
367
        res &= gst_pad_push_event (pad->rtp_pad, event);
 
368
      }
 
369
      GST_PAD_UNLOCK (demux);
 
370
      gst_event_unref (event);
 
371
      break;
 
372
    }
 
373
  }
 
374
 
 
375
  gst_object_unref (demux);
 
376
  return res;
 
377
}
 
378
 
 
379
static gboolean
 
380
gst_rtp_ssrc_demux_rtcp_sink_event (GstPad * pad, GstEvent * event)
 
381
{
 
382
  GstRtpSsrcDemux *demux;
 
383
  gboolean res = FALSE;
 
384
 
 
385
  demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
 
386
 
 
387
  switch (GST_EVENT_TYPE (event)) {
 
388
    case GST_EVENT_NEWSEGMENT:
 
389
    default:
 
390
    {
 
391
      GSList *walk;
 
392
 
 
393
      res = TRUE;
 
394
      GST_PAD_LOCK (demux);
 
395
      for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
 
396
        GstRtpSsrcDemuxPad *pad = (GstRtpSsrcDemuxPad *) walk->data;
 
397
 
 
398
        gst_event_ref (event);
 
399
        res &= gst_pad_push_event (pad->rtcp_pad, event);
 
400
      }
 
401
      GST_PAD_UNLOCK (demux);
 
402
      gst_event_unref (event);
 
403
      break;
 
404
    }
 
405
  }
 
406
  gst_object_unref (demux);
 
407
  return res;
 
408
}
 
409
 
 
410
static GstFlowReturn
 
411
gst_rtp_ssrc_demux_chain (GstPad * pad, GstBuffer * buf)
 
412
{
 
413
  GstFlowReturn ret;
 
414
  GstRtpSsrcDemux *demux;
 
415
  guint32 ssrc;
 
416
  GstRtpSsrcDemuxPad *dpad;
 
417
 
 
418
  demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad));
 
419
 
 
420
  if (!gst_rtp_buffer_validate (buf))
 
421
    goto invalid_payload;
 
422
 
 
423
  ssrc = gst_rtp_buffer_get_ssrc (buf);
 
424
 
 
425
  GST_DEBUG_OBJECT (demux, "received buffer of SSRC %08x", ssrc);
 
426
 
 
427
  GST_PAD_LOCK (demux);
 
428
  dpad = find_demux_pad_for_ssrc (demux, ssrc);
 
429
  if (dpad == NULL) {
 
430
    if (!(dpad =
 
431
            create_demux_pad_for_ssrc (demux, ssrc,
 
432
                GST_BUFFER_TIMESTAMP (buf))))
 
433
      goto create_failed;
 
434
  }
 
435
  GST_PAD_UNLOCK (demux);
 
436
 
 
437
  /* push to srcpad */
 
438
  ret = gst_pad_push (dpad->rtp_pad, buf);
 
439
 
 
440
  return ret;
 
441
 
 
442
  /* ERRORS */
 
443
invalid_payload:
 
444
  {
 
445
    /* this is fatal and should be filtered earlier */
 
446
    GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
 
447
        ("Dropping invalid RTP payload"));
 
448
    gst_buffer_unref (buf);
 
449
    return GST_FLOW_ERROR;
 
450
  }
 
451
create_failed:
 
452
  {
 
453
    GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
 
454
        ("Could not create new pad"));
 
455
    GST_PAD_UNLOCK (demux);
 
456
    gst_buffer_unref (buf);
 
457
    return GST_FLOW_ERROR;
 
458
  }
 
459
}
 
460
 
 
461
static GstFlowReturn
 
462
gst_rtp_ssrc_demux_rtcp_chain (GstPad * pad, GstBuffer * buf)
 
463
{
 
464
  GstFlowReturn ret;
 
465
  GstRtpSsrcDemux *demux;
 
466
  guint32 ssrc;
 
467
  GstRtpSsrcDemuxPad *dpad;
 
468
  GstRTCPPacket packet;
 
469
 
 
470
  demux = GST_RTP_SSRC_DEMUX (GST_OBJECT_PARENT (pad));
 
471
 
 
472
  if (!gst_rtcp_buffer_validate (buf))
 
473
    goto invalid_rtcp;
 
474
 
 
475
  if (!gst_rtcp_buffer_get_first_packet (buf, &packet))
 
476
    goto invalid_rtcp;
 
477
 
 
478
  /* first packet must be SR or RR or else the validate would have failed */
 
479
  switch (gst_rtcp_packet_get_type (&packet)) {
 
480
    case GST_RTCP_TYPE_SR:
 
481
      /* get the ssrc so that we can route it to the right source pad */
 
482
      gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, NULL, NULL, NULL,
 
483
          NULL);
 
484
      break;
 
485
    default:
 
486
      goto invalid_rtcp;
 
487
  }
 
488
 
 
489
  GST_DEBUG_OBJECT (demux, "received RTCP of SSRC %08x", ssrc);
 
490
 
 
491
  GST_PAD_LOCK (demux);
 
492
  dpad = find_demux_pad_for_ssrc (demux, ssrc);
 
493
  if (dpad == NULL) {
 
494
    GST_DEBUG_OBJECT (demux, "creating pad for SSRC %08x", ssrc);
 
495
    if (!(dpad = create_demux_pad_for_ssrc (demux, ssrc, -1)))
 
496
      goto create_failed;
 
497
  }
 
498
  GST_PAD_UNLOCK (demux);
 
499
 
 
500
  /* push to srcpad */
 
501
  ret = gst_pad_push (dpad->rtcp_pad, buf);
 
502
 
 
503
  return ret;
 
504
 
 
505
  /* ERRORS */
 
506
invalid_rtcp:
 
507
  {
 
508
    /* this is fatal and should be filtered earlier */
 
509
    GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
 
510
        ("Dropping invalid RTCP packet"));
 
511
    gst_buffer_unref (buf);
 
512
    return GST_FLOW_ERROR;
 
513
  }
 
514
create_failed:
 
515
  {
 
516
    GST_ELEMENT_ERROR (demux, STREAM, DECODE, (NULL),
 
517
        ("Could not create new pad"));
 
518
    GST_PAD_UNLOCK (demux);
 
519
    gst_buffer_unref (buf);
 
520
    return GST_FLOW_ERROR;
 
521
  }
 
522
}
 
523
 
 
524
static gboolean
 
525
gst_rtp_ssrc_demux_src_event (GstPad * pad, GstEvent * event)
 
526
{
 
527
  GstRtpSsrcDemux *demux;
 
528
  gboolean res = FALSE;
 
529
 
 
530
  demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
 
531
 
 
532
  switch (GST_EVENT_TYPE (event)) {
 
533
    case GST_EVENT_SEEK:
 
534
    default:
 
535
      res = gst_pad_event_default (pad, event);
 
536
      break;
 
537
  }
 
538
  gst_object_unref (demux);
 
539
  return res;
 
540
}
 
541
 
 
542
static GList *
 
543
gst_rtp_ssrc_demux_internal_links (GstPad * pad)
 
544
{
 
545
  GstRtpSsrcDemux *demux;
 
546
  GList *res = NULL;
 
547
  GSList *walk;
 
548
 
 
549
  demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
 
550
 
 
551
  GST_PAD_LOCK (demux);
 
552
  for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
 
553
    GstRtpSsrcDemuxPad *dpad = (GstRtpSsrcDemuxPad *) walk->data;
 
554
 
 
555
    if (pad == demux->rtp_sink) {
 
556
      res = g_list_prepend (res, dpad->rtp_pad);
 
557
    } else if (pad == demux->rtcp_sink) {
 
558
      res = g_list_prepend (res, dpad->rtcp_pad);
 
559
    } else if (pad == dpad->rtp_pad) {
 
560
      res = g_list_prepend (res, demux->rtp_sink);
 
561
      break;
 
562
    } else if (pad == dpad->rtcp_pad) {
 
563
      res = g_list_prepend (res, demux->rtcp_sink);
 
564
      break;
 
565
    }
 
566
  }
 
567
  GST_PAD_UNLOCK (demux);
 
568
 
 
569
  gst_object_unref (demux);
 
570
  return res;
 
571
}
 
572
 
 
573
static gboolean
 
574
gst_rtp_ssrc_demux_src_query (GstPad * pad, GstQuery * query)
 
575
{
 
576
  GstRtpSsrcDemux *demux;
 
577
  gboolean res = FALSE;
 
578
 
 
579
  demux = GST_RTP_SSRC_DEMUX (gst_pad_get_parent (pad));
 
580
 
 
581
  switch (GST_QUERY_TYPE (query)) {
 
582
    case GST_QUERY_LATENCY:
 
583
    {
 
584
 
 
585
      if ((res = gst_pad_peer_query (demux->rtp_sink, query))) {
 
586
        gboolean live;
 
587
        GstClockTime min_latency, max_latency;
 
588
        GstRtpSsrcDemuxPad *demuxpad;
 
589
 
 
590
        demuxpad = gst_pad_get_element_private (pad);
 
591
 
 
592
        gst_query_parse_latency (query, &live, &min_latency, &max_latency);
 
593
 
 
594
        GST_DEBUG_OBJECT (demux, "peer min latency %" GST_TIME_FORMAT,
 
595
            GST_TIME_ARGS (min_latency));
 
596
 
 
597
        GST_DEBUG_OBJECT (demux, "latency for SSRC %08x", demuxpad->ssrc);
 
598
 
 
599
        gst_query_set_latency (query, live, min_latency, max_latency);
 
600
      }
 
601
      break;
 
602
    }
 
603
    default:
 
604
      res = gst_pad_query_default (pad, query);
 
605
      break;
 
606
  }
 
607
  gst_object_unref (demux);
 
608
 
 
609
  return res;
 
610
}
 
611
 
 
612
static GstStateChangeReturn
 
613
gst_rtp_ssrc_demux_change_state (GstElement * element,
 
614
    GstStateChange transition)
 
615
{
 
616
  GstStateChangeReturn ret;
 
617
  GstRtpSsrcDemux *demux;
 
618
 
 
619
  demux = GST_RTP_SSRC_DEMUX (element);
 
620
 
 
621
  switch (transition) {
 
622
    case GST_STATE_CHANGE_NULL_TO_READY:
 
623
    case GST_STATE_CHANGE_READY_TO_PAUSED:
 
624
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
 
625
    default:
 
626
      break;
 
627
  }
 
628
 
 
629
  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
630
 
 
631
  switch (transition) {
 
632
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
 
633
      break;
 
634
    case GST_STATE_CHANGE_PAUSED_TO_READY:
 
635
      gst_rtp_ssrc_demux_reset (demux);
 
636
      break;
 
637
    case GST_STATE_CHANGE_READY_TO_NULL:
 
638
    default:
 
639
      break;
 
640
  }
 
641
  return ret;
 
642
}