rtpbin: add ts-offset-smoothing-factor property
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / gst / rtpmanager / gstrtpbin.c
1 /* GStreamer
2  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.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 /**
21  * SECTION:element-rtpbin
22  * @title: rtpbin
23  * @see_also: rtpjitterbuffer, rtpsession, rtpptdemux, rtpssrcdemux
24  *
25  * RTP bin combines the functions of #GstRtpSession, #GstRtpSsrcDemux,
26  * #GstRtpJitterBuffer and #GstRtpPtDemux in one element. It allows for multiple
27  * RTP sessions that will be synchronized together using RTCP SR packets.
28  *
29  * #GstRtpBin is configured with a number of request pads that define the
30  * functionality that is activated, similar to the #GstRtpSession element.
31  *
32  * To use #GstRtpBin as an RTP receiver, request a recv_rtp_sink_\%u pad. The session
33  * number must be specified in the pad name.
34  * Data received on the recv_rtp_sink_\%u pad will be processed in the #GstRtpSession
35  * manager and after being validated forwarded on #GstRtpSsrcDemux element. Each
36  * RTP stream is demuxed based on the SSRC and send to a #GstRtpJitterBuffer. After
37  * the packets are released from the jitterbuffer, they will be forwarded to a
38  * #GstRtpPtDemux element. The #GstRtpPtDemux element will demux the packets based
39  * on the payload type and will create a unique pad recv_rtp_src_\%u_\%u_\%u on
40  * rtpbin with the session number, SSRC and payload type respectively as the pad
41  * name.
42  *
43  * To also use #GstRtpBin as an RTCP receiver, request a recv_rtcp_sink_\%u pad. The
44  * session number must be specified in the pad name.
45  *
46  * If you want the session manager to generate and send RTCP packets, request
47  * the send_rtcp_src_\%u pad with the session number in the pad name. Packet pushed
48  * on this pad contain SR/RR RTCP reports that should be sent to all participants
49  * in the session.
50  *
51  * To use #GstRtpBin as a sender, request a send_rtp_sink_\%u pad, which will
52  * automatically create a send_rtp_src_\%u pad. If the session number is not provided,
53  * the pad from the lowest available session will be returned. The session manager will modify the
54  * SSRC in the RTP packets to its own SSRC and will forward the packets on the
55  * send_rtp_src_\%u pad after updating its internal state.
56  *
57  * The session manager needs the clock-rate of the payload types it is handling
58  * and will signal the #GstRtpSession::request-pt-map signal when it needs such a
59  * mapping. One can clear the cached values with the #GstRtpSession::clear-pt-map
60  * signal.
61  *
62  * Access to the internal statistics of rtpbin is provided with the
63  * get-internal-session property. This action signal gives access to the
64  * RTPSession object which further provides action signals to retrieve the
65  * internal source and other sources.
66  *
67  * #GstRtpBin also has signals (#GstRtpBin::request-rtp-encoder,
68  * #GstRtpBin::request-rtp-decoder, #GstRtpBin::request-rtcp-encoder and
69  * #GstRtpBin::request-rtp-decoder) to dynamically request for RTP and RTCP encoders
70  * and decoders in order to support SRTP. The encoders must provide the pads
71  * rtp_sink_\%u and rtp_src_\%u for RTP and rtcp_sink_\%u and rtcp_src_\%u for
72  * RTCP. The session number will be used in the pad name. The decoders must provide
73  * rtp_sink and rtp_src for RTP and rtcp_sink and rtcp_src for RTCP. The decoders will
74  * be placed before the #GstRtpSession element, thus they must support SSRC demuxing
75  * internally.
76  *
77  * #GstRtpBin has signals (#GstRtpBin::request-aux-sender and
78  * #GstRtpBin::request-aux-receiver to dynamically request an element that can be
79  * used to create or merge additional RTP streams. AUX elements are needed to
80  * implement FEC or retransmission (such as RFC 4588). An AUX sender must have one
81  * sink_\%u pad that matches the sessionid in the signal and it should have 1 or
82  * more src_\%u pads. For each src_%\u pad, a session will be made (if needed)
83  * and the pad will be linked to the session send_rtp_sink pad. Each session will
84  * then expose its source pad as send_rtp_src_\%u on #GstRtpBin.
85  * An AUX receiver has 1 src_\%u pad that much match the sessionid in the signal
86  * and 1 or more sink_\%u pads. A session will be made for each sink_\%u pad
87  * when the corresponding recv_rtp_sink_\%u pad is requested on #GstRtpBin.
88  * The #GstRtpBin::request-jitterbuffer signal can be used to provide a custom
89  * element to perform arrival time smoothing, reordering and optionally packet
90  * loss detection and retransmission requests.
91  *
92  * ## Example pipelines
93  *
94  * |[
95  * gst-launch-1.0 udpsrc port=5000 caps="application/x-rtp, ..." ! .recv_rtp_sink_0 \
96  *     rtpbin ! rtptheoradepay ! theoradec ! xvimagesink
97  * ]| Receive RTP data from port 5000 and send to the session 0 in rtpbin.
98  * |[
99  * gst-launch-1.0 rtpbin name=rtpbin \
100  *         v4l2src ! videoconvert ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \
101  *                   rtpbin.send_rtp_src_0 ! udpsink port=5000                            \
102  *                   rtpbin.send_rtcp_src_0 ! udpsink port=5001 sync=false async=false    \
103  *                   udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
104  *         audiotestsrc ! amrnbenc ! rtpamrpay ! rtpbin.send_rtp_sink_1                   \
105  *                   rtpbin.send_rtp_src_1 ! udpsink port=5002                            \
106  *                   rtpbin.send_rtcp_src_1 ! udpsink port=5003 sync=false async=false    \
107  *                   udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1
108  * ]| Encode and payload H263 video captured from a v4l2src. Encode and payload AMR
109  * audio generated from audiotestsrc. The video is sent to session 0 in rtpbin
110  * and the audio is sent to session 1. Video packets are sent on UDP port 5000
111  * and audio packets on port 5002. The video RTCP packets for session 0 are sent
112  * on port 5001 and the audio RTCP packets for session 0 are sent on port 5003.
113  * RTCP packets for session 0 are received on port 5005 and RTCP for session 1
114  * is received on port 5007. Since RTCP packets from the sender should be sent
115  * as soon as possible and do not participate in preroll, sync=false and
116  * async=false is configured on udpsink
117  * |[
118  * gst-launch-1.0 -v rtpbin name=rtpbin                                          \
119  *     udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-1998" \
120  *             port=5000 ! rtpbin.recv_rtp_sink_0                                \
121  *         rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink                    \
122  *      udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
123  *      rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
124  *     udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1" \
125  *             port=5002 ! rtpbin.recv_rtp_sink_1                                \
126  *         rtpbin. ! rtpamrdepay ! amrnbdec ! alsasink                           \
127  *      udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
128  *      rtpbin.send_rtcp_src_1 ! udpsink port=5007 sync=false async=false
129  * ]| Receive H263 on port 5000, send it through rtpbin in session 0, depayload,
130  * decode and display the video.
131  * Receive AMR on port 5002, send it through rtpbin in session 1, depayload,
132  * decode and play the audio.
133  * Receive server RTCP packets for session 0 on port 5001 and RTCP packets for
134  * session 1 on port 5003. These packets will be used for session management and
135  * synchronisation.
136  * Send RTCP reports for session 0 on port 5005 and RTCP reports for session 1
137  * on port 5007.
138  *
139  */
140
141 #ifdef HAVE_CONFIG_H
142 #include "config.h"
143 #endif
144 #include <stdio.h>
145 #include <string.h>
146
147 #include <gst/rtp/gstrtpbuffer.h>
148 #include <gst/rtp/gstrtcpbuffer.h>
149
150 #include "gstrtpbin.h"
151 #include "rtpsession.h"
152 #include "gstrtpsession.h"
153 #include "gstrtpjitterbuffer.h"
154
155 #include <gst/glib-compat-private.h>
156
157 GST_DEBUG_CATEGORY_STATIC (gst_rtp_bin_debug);
158 #define GST_CAT_DEFAULT gst_rtp_bin_debug
159
160 /* sink pads */
161 static GstStaticPadTemplate rtpbin_recv_rtp_sink_template =
162     GST_STATIC_PAD_TEMPLATE ("recv_rtp_sink_%u",
163     GST_PAD_SINK,
164     GST_PAD_REQUEST,
165     GST_STATIC_CAPS ("application/x-rtp;application/x-srtp")
166     );
167
168 /**
169  * GstRtpBin!recv_fec_sink_%u_%u:
170  *
171  * Sink template for receiving Forward Error Correction packets,
172  * in the form recv_fec_sink_<session_idx>_<fec_stream_idx>
173  *
174  * See #GstRTPST_2022_1_FecDec for example usage
175  *
176  * Since: 1.20
177  */
178 static GstStaticPadTemplate rtpbin_recv_fec_sink_template =
179 GST_STATIC_PAD_TEMPLATE ("recv_fec_sink_%u_%u",
180     GST_PAD_SINK,
181     GST_PAD_REQUEST,
182     GST_STATIC_CAPS ("application/x-rtp")
183     );
184
185 /**
186  * GstRtpBin!send_fec_src_%u_%u:
187  *
188  * Src template for sending Forward Error Correction packets,
189  * in the form send_fec_src_<session_idx>_<fec_stream_idx>
190  *
191  * See #GstRTPST_2022_1_FecEnc for example usage
192  *
193  * Since: 1.20
194  */
195 static GstStaticPadTemplate rtpbin_send_fec_src_template =
196 GST_STATIC_PAD_TEMPLATE ("send_fec_src_%u_%u",
197     GST_PAD_SRC,
198     GST_PAD_SOMETIMES,
199     GST_STATIC_CAPS ("application/x-rtp")
200     );
201
202 static GstStaticPadTemplate rtpbin_recv_rtcp_sink_template =
203     GST_STATIC_PAD_TEMPLATE ("recv_rtcp_sink_%u",
204     GST_PAD_SINK,
205     GST_PAD_REQUEST,
206     GST_STATIC_CAPS ("application/x-rtcp;application/x-srtcp")
207     );
208
209 static GstStaticPadTemplate rtpbin_send_rtp_sink_template =
210 GST_STATIC_PAD_TEMPLATE ("send_rtp_sink_%u",
211     GST_PAD_SINK,
212     GST_PAD_REQUEST,
213     GST_STATIC_CAPS ("application/x-rtp")
214     );
215
216 /* src pads */
217 static GstStaticPadTemplate rtpbin_recv_rtp_src_template =
218 GST_STATIC_PAD_TEMPLATE ("recv_rtp_src_%u_%u_%u",
219     GST_PAD_SRC,
220     GST_PAD_SOMETIMES,
221     GST_STATIC_CAPS ("application/x-rtp")
222     );
223
224 static GstStaticPadTemplate rtpbin_send_rtcp_src_template =
225     GST_STATIC_PAD_TEMPLATE ("send_rtcp_src_%u",
226     GST_PAD_SRC,
227     GST_PAD_REQUEST,
228     GST_STATIC_CAPS ("application/x-rtcp;application/x-srtcp")
229     );
230
231 static GstStaticPadTemplate rtpbin_send_rtp_src_template =
232     GST_STATIC_PAD_TEMPLATE ("send_rtp_src_%u",
233     GST_PAD_SRC,
234     GST_PAD_SOMETIMES,
235     GST_STATIC_CAPS ("application/x-rtp;application/x-srtp")
236     );
237
238 #define GST_RTP_BIN_LOCK(bin)   g_mutex_lock (&(bin)->priv->bin_lock)
239 #define GST_RTP_BIN_UNLOCK(bin) g_mutex_unlock (&(bin)->priv->bin_lock)
240
241 /* lock to protect dynamic callbacks, like pad-added and new ssrc. */
242 #define GST_RTP_BIN_DYN_LOCK(bin)    g_mutex_lock (&(bin)->priv->dyn_lock)
243 #define GST_RTP_BIN_DYN_UNLOCK(bin)  g_mutex_unlock (&(bin)->priv->dyn_lock)
244
245 /* lock for shutdown */
246 #define GST_RTP_BIN_SHUTDOWN_LOCK(bin,label)     \
247 G_STMT_START {                                   \
248   if (g_atomic_int_get (&bin->priv->shutdown))   \
249     goto label;                                  \
250   GST_RTP_BIN_DYN_LOCK (bin);                    \
251   if (g_atomic_int_get (&bin->priv->shutdown)) { \
252     GST_RTP_BIN_DYN_UNLOCK (bin);                \
253     goto label;                                  \
254   }                                              \
255 } G_STMT_END
256
257 /* unlock for shutdown */
258 #define GST_RTP_BIN_SHUTDOWN_UNLOCK(bin)         \
259   GST_RTP_BIN_DYN_UNLOCK (bin);                  \
260
261 /* Minimum time offset to apply. This compensates for rounding errors in NTP to
262  * RTP timestamp conversions */
263 #define MIN_TS_OFFSET_ROUND_OFF_COMP (4 * GST_MSECOND)
264
265 struct _GstRtpBinPrivate
266 {
267   GMutex bin_lock;
268
269   /* lock protecting dynamic adding/removing */
270   GMutex dyn_lock;
271
272   /* if we are shutting down or not */
273   gint shutdown;
274
275   gboolean autoremove;
276
277   /* NTP time in ns of last SR sync used */
278   guint64 last_ntpnstime;
279
280   /* list of extra elements */
281   GList *elements;
282 };
283
284 /* signals and args */
285 enum
286 {
287   SIGNAL_REQUEST_PT_MAP,
288   SIGNAL_PAYLOAD_TYPE_CHANGE,
289   SIGNAL_CLEAR_PT_MAP,
290   SIGNAL_RESET_SYNC,
291   SIGNAL_GET_SESSION,
292   SIGNAL_GET_INTERNAL_SESSION,
293   SIGNAL_GET_STORAGE,
294   SIGNAL_GET_INTERNAL_STORAGE,
295   SIGNAL_CLEAR_SSRC,
296
297   SIGNAL_ON_NEW_SSRC,
298   SIGNAL_ON_SSRC_COLLISION,
299   SIGNAL_ON_SSRC_VALIDATED,
300   SIGNAL_ON_SSRC_ACTIVE,
301   SIGNAL_ON_SSRC_SDES,
302   SIGNAL_ON_BYE_SSRC,
303   SIGNAL_ON_BYE_TIMEOUT,
304   SIGNAL_ON_TIMEOUT,
305   SIGNAL_ON_SENDER_TIMEOUT,
306   SIGNAL_ON_NPT_STOP,
307
308   SIGNAL_REQUEST_RTP_ENCODER,
309   SIGNAL_REQUEST_RTP_DECODER,
310   SIGNAL_REQUEST_RTCP_ENCODER,
311   SIGNAL_REQUEST_RTCP_DECODER,
312
313   SIGNAL_REQUEST_FEC_DECODER,
314   SIGNAL_REQUEST_FEC_DECODER_FULL,
315   SIGNAL_REQUEST_FEC_ENCODER,
316
317   SIGNAL_REQUEST_JITTERBUFFER,
318
319   SIGNAL_NEW_JITTERBUFFER,
320   SIGNAL_NEW_STORAGE,
321
322   SIGNAL_REQUEST_AUX_SENDER,
323   SIGNAL_REQUEST_AUX_RECEIVER,
324
325   SIGNAL_ON_NEW_SENDER_SSRC,
326   SIGNAL_ON_SENDER_SSRC_ACTIVE,
327
328   SIGNAL_ON_BUNDLED_SSRC,
329
330   LAST_SIGNAL
331 };
332
333 #define DEFAULT_LATENCY_MS           200
334 #define DEFAULT_DROP_ON_LATENCY      FALSE
335 #define DEFAULT_SDES                 NULL
336 #define DEFAULT_DO_LOST              FALSE
337 #define DEFAULT_IGNORE_PT            FALSE
338 #define DEFAULT_NTP_SYNC             FALSE
339 #define DEFAULT_AUTOREMOVE           FALSE
340 #define DEFAULT_BUFFER_MODE          RTP_JITTER_BUFFER_MODE_SLAVE
341 #define DEFAULT_USE_PIPELINE_CLOCK   FALSE
342 #define DEFAULT_RTCP_SYNC            GST_RTP_BIN_RTCP_SYNC_ALWAYS
343 #define DEFAULT_RTCP_SYNC_INTERVAL   0
344 #define DEFAULT_DO_SYNC_EVENT        FALSE
345 #define DEFAULT_DO_RETRANSMISSION    FALSE
346 #define DEFAULT_RTP_PROFILE          GST_RTP_PROFILE_AVP
347 #define DEFAULT_NTP_TIME_SOURCE      GST_RTP_NTP_TIME_SOURCE_NTP
348 #define DEFAULT_RTCP_SYNC_SEND_TIME  TRUE
349 #define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
350 #define DEFAULT_MAX_DROPOUT_TIME     60000
351 #define DEFAULT_MAX_MISORDER_TIME    2000
352 #define DEFAULT_RFC7273_SYNC         FALSE
353 #define DEFAULT_MAX_STREAMS          G_MAXUINT
354 #define DEFAULT_MAX_TS_OFFSET_ADJUSTMENT G_GUINT64_CONSTANT(0)
355 #define DEFAULT_MAX_TS_OFFSET        G_GINT64_CONSTANT(3000000000)
356 #define DEFAULT_MIN_TS_OFFSET        MIN_TS_OFFSET_ROUND_OFF_COMP
357 #define DEFAULT_TS_OFFSET_SMOOTHING_FACTOR  0
358
359 enum
360 {
361   PROP_0,
362   PROP_LATENCY,
363   PROP_DROP_ON_LATENCY,
364   PROP_SDES,
365   PROP_DO_LOST,
366   PROP_IGNORE_PT,
367   PROP_NTP_SYNC,
368   PROP_RTCP_SYNC,
369   PROP_RTCP_SYNC_INTERVAL,
370   PROP_AUTOREMOVE,
371   PROP_BUFFER_MODE,
372   PROP_USE_PIPELINE_CLOCK,
373   PROP_DO_SYNC_EVENT,
374   PROP_DO_RETRANSMISSION,
375   PROP_RTP_PROFILE,
376   PROP_NTP_TIME_SOURCE,
377   PROP_RTCP_SYNC_SEND_TIME,
378   PROP_MAX_RTCP_RTP_TIME_DIFF,
379   PROP_MAX_DROPOUT_TIME,
380   PROP_MAX_MISORDER_TIME,
381   PROP_RFC7273_SYNC,
382   PROP_MAX_STREAMS,
383   PROP_MAX_TS_OFFSET_ADJUSTMENT,
384   PROP_MAX_TS_OFFSET,
385   PROP_MIN_TS_OFFSET,
386   PROP_TS_OFFSET_SMOOTHING_FACTOR,
387   PROP_FEC_DECODERS,
388   PROP_FEC_ENCODERS,
389 };
390
391 #define GST_RTP_BIN_RTCP_SYNC_TYPE (gst_rtp_bin_rtcp_sync_get_type())
392 static GType
393 gst_rtp_bin_rtcp_sync_get_type (void)
394 {
395   static GType rtcp_sync_type = 0;
396   static const GEnumValue rtcp_sync_types[] = {
397     {GST_RTP_BIN_RTCP_SYNC_ALWAYS, "always", "always"},
398     {GST_RTP_BIN_RTCP_SYNC_INITIAL, "initial", "initial"},
399     {GST_RTP_BIN_RTCP_SYNC_RTP, "rtp-info", "rtp-info"},
400     {0, NULL, NULL},
401   };
402
403   if (!rtcp_sync_type) {
404     rtcp_sync_type = g_enum_register_static ("GstRTCPSync", rtcp_sync_types);
405   }
406   return rtcp_sync_type;
407 }
408
409 /* helper objects */
410 typedef struct _GstRtpBinSession GstRtpBinSession;
411 typedef struct _GstRtpBinStream GstRtpBinStream;
412 typedef struct _GstRtpBinClient GstRtpBinClient;
413
414 static guint gst_rtp_bin_signals[LAST_SIGNAL] = { 0 };
415
416 static GstCaps *pt_map_requested (GstElement * element, guint pt,
417     GstRtpBinSession * session);
418 static void payload_type_change (GstElement * element, guint pt,
419     GstRtpBinSession * session);
420 static void remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session);
421 static void remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session);
422 static void remove_recv_fec (GstRtpBin * rtpbin, GstRtpBinSession * session);
423 static void remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session);
424 static void remove_send_fec (GstRtpBin * rtpbin, GstRtpBinSession * session);
425 static void remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session);
426 static void free_client (GstRtpBinClient * client, GstRtpBin * bin);
427 static void free_stream (GstRtpBinStream * stream, GstRtpBin * bin);
428 static GstRtpBinSession *create_session (GstRtpBin * rtpbin, gint id);
429 static GstPad *complete_session_sink (GstRtpBin * rtpbin,
430     GstRtpBinSession * session);
431 static void
432 complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session,
433     guint sessid);
434 static GstPad *complete_session_rtcp (GstRtpBin * rtpbin,
435     GstRtpBinSession * session, guint sessid);
436 static GstElement *session_request_element (GstRtpBinSession * session,
437     guint signal);
438
439 /* Manages the RTP stream for one SSRC.
440  *
441  * We pipe the stream (coming from the SSRC demuxer) into a jitterbuffer.
442  * If we see an SDES RTCP packet that links multiple SSRCs together based on a
443  * common CNAME, we create a GstRtpBinClient structure to group the SSRCs
444  * together (see below).
445  */
446 struct _GstRtpBinStream
447 {
448   /* the SSRC of this stream */
449   guint32 ssrc;
450
451   /* parent bin */
452   GstRtpBin *bin;
453
454   /* the session this SSRC belongs to */
455   GstRtpBinSession *session;
456
457   /* the jitterbuffer of the SSRC */
458   GstElement *buffer;
459   gulong buffer_handlesync_sig;
460   gulong buffer_ptreq_sig;
461   gulong buffer_ntpstop_sig;
462   gint percent;
463
464   /* the PT demuxer of the SSRC */
465   GstElement *demux;
466   gulong demux_newpad_sig;
467   gulong demux_padremoved_sig;
468   gulong demux_ptreq_sig;
469   gulong demux_ptchange_sig;
470
471   /* if we have calculated a valid rt_delta for this stream */
472   gboolean have_sync;
473   /* mapping to local RTP and NTP time */
474   gint64 rt_delta;
475   gint64 rtp_delta;
476   gint64 avg_ts_offset;
477   gboolean is_initialized;
478   /* base rtptime in gst time */
479   gint64 clock_base;
480 };
481
482 #define GST_RTP_SESSION_LOCK(sess)   g_mutex_lock (&(sess)->lock)
483 #define GST_RTP_SESSION_UNLOCK(sess) g_mutex_unlock (&(sess)->lock)
484
485 /* Manages the receiving end of the packets.
486  *
487  * There is one such structure for each RTP session (audio/video/...).
488  * We get the RTP/RTCP packets and stuff them into the session manager. From
489  * there they are pushed into an SSRC demuxer that splits the stream based on
490  * SSRC. Each of the SSRC streams go into their own jitterbuffer (managed with
491  * the GstRtpBinStream above).
492  *
493  * Before the SSRC demuxer, a storage element may be inserted for the purpose
494  * of Forward Error Correction.
495  */
496 struct _GstRtpBinSession
497 {
498   /* session id */
499   gint id;
500   /* the parent bin */
501   GstRtpBin *bin;
502   /* the session element */
503   GstElement *session;
504   /* the SSRC demuxer */
505   GstElement *demux;
506   gulong demux_newpad_sig;
507   gulong demux_padremoved_sig;
508
509   /* Fec support */
510   GstElement *storage;
511
512   GMutex lock;
513
514   /* list of GstRtpBinStream */
515   GSList *streams;
516
517   /* list of elements */
518   GSList *elements;
519
520   /* mapping of payload type to caps */
521   GHashTable *ptmap;
522
523   /* the pads of the session */
524   GstPad *recv_rtp_sink;
525   GstPad *recv_rtp_sink_ghost;
526   GstPad *recv_rtp_src;
527   GstPad *recv_rtcp_sink;
528   GstPad *recv_rtcp_sink_ghost;
529   GstPad *sync_src;
530   GstPad *send_rtp_sink;
531   GstPad *send_rtp_sink_ghost;
532   GstPad *send_rtp_src_ghost;
533   GstPad *send_rtcp_src;
534   GstPad *send_rtcp_src_ghost;
535
536   GSList *recv_fec_sinks;
537   GSList *recv_fec_sink_ghosts;
538   /* fec decoder placed before the rtpjitterbuffer but after the rtpssrcdemux.
539    * XXX: This does not yet support multiple ssrc's in the same rtp session
540    */
541   GstElement *early_fec_decoder;
542
543   GSList *send_fec_src_ghosts;
544 };
545
546 /* Manages the RTP streams that come from one client and should therefore be
547  * synchronized.
548  */
549 struct _GstRtpBinClient
550 {
551   /* the common CNAME for the streams */
552   gchar *cname;
553   guint cname_len;
554
555   /* the streams */
556   guint nstreams;
557   GSList *streams;
558 };
559
560 /* find a session with the given id. Must be called with RTP_BIN_LOCK */
561 static GstRtpBinSession *
562 find_session_by_id (GstRtpBin * rtpbin, gint id)
563 {
564   GSList *walk;
565
566   for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) {
567     GstRtpBinSession *sess = (GstRtpBinSession *) walk->data;
568
569     if (sess->id == id)
570       return sess;
571   }
572   return NULL;
573 }
574
575 static gboolean
576 pad_is_recv_fec (GstRtpBinSession * session, GstPad * pad)
577 {
578   return g_slist_find (session->recv_fec_sink_ghosts, pad) != NULL;
579 }
580
581 /* find a session with the given request pad. Must be called with RTP_BIN_LOCK */
582 static GstRtpBinSession *
583 find_session_by_pad (GstRtpBin * rtpbin, GstPad * pad)
584 {
585   GSList *walk;
586
587   for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) {
588     GstRtpBinSession *sess = (GstRtpBinSession *) walk->data;
589
590     if ((sess->recv_rtp_sink_ghost == pad) ||
591         (sess->recv_rtcp_sink_ghost == pad) ||
592         (sess->send_rtp_sink_ghost == pad) ||
593         (sess->send_rtcp_src_ghost == pad) || pad_is_recv_fec (sess, pad))
594       return sess;
595   }
596   return NULL;
597 }
598
599 static void
600 on_new_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
601 {
602   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC], 0,
603       sess->id, ssrc);
604 }
605
606 static void
607 on_ssrc_collision (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
608 {
609   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION], 0,
610       sess->id, ssrc);
611 }
612
613 static void
614 on_ssrc_validated (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
615 {
616   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED], 0,
617       sess->id, ssrc);
618 }
619
620 static void
621 on_ssrc_active (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
622 {
623   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE], 0,
624       sess->id, ssrc);
625 }
626
627 static void
628 on_ssrc_sdes (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
629 {
630   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES], 0,
631       sess->id, ssrc);
632 }
633
634 static void
635 on_bye_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
636 {
637   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC], 0,
638       sess->id, ssrc);
639 }
640
641 static void
642 on_bye_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
643 {
644   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT], 0,
645       sess->id, ssrc);
646
647   if (sess->bin->priv->autoremove)
648     g_signal_emit_by_name (sess->demux, "clear-ssrc", ssrc, NULL);
649 }
650
651 static void
652 on_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
653 {
654   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT], 0,
655       sess->id, ssrc);
656
657   if (sess->bin->priv->autoremove)
658     g_signal_emit_by_name (sess->demux, "clear-ssrc", ssrc, NULL);
659 }
660
661 static void
662 on_sender_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
663 {
664   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT], 0,
665       sess->id, ssrc);
666 }
667
668 static void
669 on_npt_stop (GstElement * jbuf, GstRtpBinStream * stream)
670 {
671   g_signal_emit (stream->bin, gst_rtp_bin_signals[SIGNAL_ON_NPT_STOP], 0,
672       stream->session->id, stream->ssrc);
673 }
674
675 static void
676 on_new_sender_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
677 {
678   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_NEW_SENDER_SSRC], 0,
679       sess->id, ssrc);
680 }
681
682 static void
683 on_sender_ssrc_active (GstElement * session, guint32 ssrc,
684     GstRtpBinSession * sess)
685 {
686   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE],
687       0, sess->id, ssrc);
688 }
689
690 /* must be called with the SESSION lock */
691 static GstRtpBinStream *
692 find_stream_by_ssrc (GstRtpBinSession * session, guint32 ssrc)
693 {
694   GSList *walk;
695
696   for (walk = session->streams; walk; walk = g_slist_next (walk)) {
697     GstRtpBinStream *stream = (GstRtpBinStream *) walk->data;
698
699     if (stream->ssrc == ssrc)
700       return stream;
701   }
702   return NULL;
703 }
704
705 static void
706 ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad,
707     GstRtpBinSession * session)
708 {
709   GstRtpBinStream *stream = NULL;
710   GstRtpBin *rtpbin;
711
712   rtpbin = session->bin;
713
714   GST_RTP_BIN_LOCK (rtpbin);
715
716   GST_RTP_SESSION_LOCK (session);
717   if ((stream = find_stream_by_ssrc (session, ssrc)))
718     session->streams = g_slist_remove (session->streams, stream);
719   GST_RTP_SESSION_UNLOCK (session);
720
721   if (stream)
722     free_stream (stream, rtpbin);
723
724   GST_RTP_BIN_UNLOCK (rtpbin);
725 }
726
727 /* create a session with the given id.  Must be called with RTP_BIN_LOCK */
728 static GstRtpBinSession *
729 create_session (GstRtpBin * rtpbin, gint id)
730 {
731   GstRtpBinSession *sess;
732   GstElement *session, *demux;
733   GstElement *storage = NULL;
734   GstState target;
735
736   if (!(session = gst_element_factory_make ("rtpsession", NULL)))
737     goto no_session;
738
739   if (!(demux = gst_element_factory_make ("rtpssrcdemux", NULL)))
740     goto no_demux;
741
742   if (!(storage = gst_element_factory_make ("rtpstorage", NULL)))
743     goto no_storage;
744
745   /* need to sink the storage or otherwise signal handlers from bindings will
746    * take ownership of it and we don't own it anymore */
747   gst_object_ref_sink (storage);
748   g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_STORAGE], 0, storage,
749       id);
750
751   sess = g_new0 (GstRtpBinSession, 1);
752   g_mutex_init (&sess->lock);
753   sess->id = id;
754   sess->bin = rtpbin;
755   sess->session = session;
756   sess->demux = demux;
757   sess->storage = storage;
758
759   sess->ptmap = g_hash_table_new_full (NULL, NULL, NULL,
760       (GDestroyNotify) gst_caps_unref);
761   rtpbin->sessions = g_slist_prepend (rtpbin->sessions, sess);
762
763   /* configure SDES items */
764   GST_OBJECT_LOCK (rtpbin);
765   g_object_set (demux, "max-streams", rtpbin->max_streams, NULL);
766   g_object_set (session, "sdes", rtpbin->sdes, "rtp-profile",
767       rtpbin->rtp_profile, "rtcp-sync-send-time", rtpbin->rtcp_sync_send_time,
768       NULL);
769   if (rtpbin->use_pipeline_clock)
770     g_object_set (session, "use-pipeline-clock", rtpbin->use_pipeline_clock,
771         NULL);
772   else
773     g_object_set (session, "ntp-time-source", rtpbin->ntp_time_source, NULL);
774
775   g_object_set (session, "max-dropout-time", rtpbin->max_dropout_time,
776       "max-misorder-time", rtpbin->max_misorder_time, NULL);
777   GST_OBJECT_UNLOCK (rtpbin);
778
779   /* provide clock_rate to the session manager when needed */
780   g_signal_connect (session, "request-pt-map",
781       (GCallback) pt_map_requested, sess);
782
783   g_signal_connect (sess->session, "on-new-ssrc",
784       (GCallback) on_new_ssrc, sess);
785   g_signal_connect (sess->session, "on-ssrc-collision",
786       (GCallback) on_ssrc_collision, sess);
787   g_signal_connect (sess->session, "on-ssrc-validated",
788       (GCallback) on_ssrc_validated, sess);
789   g_signal_connect (sess->session, "on-ssrc-active",
790       (GCallback) on_ssrc_active, sess);
791   g_signal_connect (sess->session, "on-ssrc-sdes",
792       (GCallback) on_ssrc_sdes, sess);
793   g_signal_connect (sess->session, "on-bye-ssrc",
794       (GCallback) on_bye_ssrc, sess);
795   g_signal_connect (sess->session, "on-bye-timeout",
796       (GCallback) on_bye_timeout, sess);
797   g_signal_connect (sess->session, "on-timeout", (GCallback) on_timeout, sess);
798   g_signal_connect (sess->session, "on-sender-timeout",
799       (GCallback) on_sender_timeout, sess);
800   g_signal_connect (sess->session, "on-new-sender-ssrc",
801       (GCallback) on_new_sender_ssrc, sess);
802   g_signal_connect (sess->session, "on-sender-ssrc-active",
803       (GCallback) on_sender_ssrc_active, sess);
804
805   gst_bin_add (GST_BIN_CAST (rtpbin), session);
806   gst_bin_add (GST_BIN_CAST (rtpbin), demux);
807   gst_bin_add (GST_BIN_CAST (rtpbin), storage);
808
809   /* unref the storage again, the bin has a reference now and
810    * we don't need it anymore */
811   gst_object_unref (storage);
812
813   GST_OBJECT_LOCK (rtpbin);
814   target = GST_STATE_TARGET (rtpbin);
815   GST_OBJECT_UNLOCK (rtpbin);
816
817   /* change state only to what's needed */
818   gst_element_set_state (demux, target);
819   gst_element_set_state (session, target);
820   gst_element_set_state (storage, target);
821
822   return sess;
823
824   /* ERRORS */
825 no_session:
826   {
827     g_warning ("rtpbin: could not create rtpsession element");
828     return NULL;
829   }
830 no_demux:
831   {
832     gst_object_unref (session);
833     g_warning ("rtpbin: could not create rtpssrcdemux element");
834     return NULL;
835   }
836 no_storage:
837   {
838     gst_object_unref (session);
839     gst_object_unref (demux);
840     g_warning ("rtpbin: could not create rtpstorage element");
841     return NULL;
842   }
843 }
844
845 static gboolean
846 bin_manage_element (GstRtpBin * bin, GstElement * element)
847 {
848   GstRtpBinPrivate *priv = bin->priv;
849
850   if (g_list_find (priv->elements, element)) {
851     GST_DEBUG_OBJECT (bin, "requested element %p already in bin", element);
852   } else {
853     GST_DEBUG_OBJECT (bin, "adding requested element %p", element);
854
855     if (g_object_is_floating (element))
856       element = gst_object_ref_sink (element);
857
858     if (!gst_bin_add (GST_BIN_CAST (bin), element))
859       goto add_failed;
860     if (!gst_element_sync_state_with_parent (element))
861       GST_WARNING_OBJECT (bin, "unable to sync element state with rtpbin");
862   }
863   /* we add the element multiple times, each we need an equal number of
864    * removes to really remove the element from the bin */
865   priv->elements = g_list_prepend (priv->elements, element);
866
867   return TRUE;
868
869   /* ERRORS */
870 add_failed:
871   {
872     GST_WARNING_OBJECT (bin, "unable to add element");
873     gst_object_unref (element);
874     return FALSE;
875   }
876 }
877
878 static void
879 remove_bin_element (GstElement * element, GstRtpBin * bin)
880 {
881   GstRtpBinPrivate *priv = bin->priv;
882   GList *find;
883
884   find = g_list_find (priv->elements, element);
885   if (find) {
886     priv->elements = g_list_delete_link (priv->elements, find);
887
888     if (!g_list_find (priv->elements, element)) {
889       gst_element_set_locked_state (element, TRUE);
890       gst_bin_remove (GST_BIN_CAST (bin), element);
891       gst_element_set_state (element, GST_STATE_NULL);
892     }
893
894     gst_object_unref (element);
895   }
896 }
897
898 /* called with RTP_BIN_LOCK */
899 static void
900 free_session (GstRtpBinSession * sess, GstRtpBin * bin)
901 {
902   GST_DEBUG_OBJECT (bin, "freeing session %p", sess);
903
904   gst_element_set_locked_state (sess->demux, TRUE);
905   gst_element_set_locked_state (sess->session, TRUE);
906   gst_element_set_locked_state (sess->storage, TRUE);
907
908   gst_element_set_state (sess->demux, GST_STATE_NULL);
909   gst_element_set_state (sess->session, GST_STATE_NULL);
910   gst_element_set_state (sess->storage, GST_STATE_NULL);
911
912   remove_recv_rtp (bin, sess);
913   remove_recv_rtcp (bin, sess);
914   remove_recv_fec (bin, sess);
915   remove_send_rtp (bin, sess);
916   remove_send_fec (bin, sess);
917   remove_rtcp (bin, sess);
918
919   gst_bin_remove (GST_BIN_CAST (bin), sess->session);
920   gst_bin_remove (GST_BIN_CAST (bin), sess->demux);
921   gst_bin_remove (GST_BIN_CAST (bin), sess->storage);
922
923   g_slist_foreach (sess->elements, (GFunc) remove_bin_element, bin);
924   g_slist_free (sess->elements);
925   sess->elements = NULL;
926
927   g_slist_foreach (sess->streams, (GFunc) free_stream, bin);
928   g_slist_free (sess->streams);
929
930   g_mutex_clear (&sess->lock);
931   g_hash_table_destroy (sess->ptmap);
932
933   g_free (sess);
934 }
935
936 /* get the payload type caps for the specific payload @pt in @session */
937 static GstCaps *
938 get_pt_map (GstRtpBinSession * session, guint pt)
939 {
940   GstCaps *caps = NULL;
941   GstRtpBin *bin;
942   GValue ret = { 0 };
943   GValue args[3] = { {0}, {0}, {0} };
944
945   GST_DEBUG ("searching pt %u in cache", pt);
946
947   GST_RTP_SESSION_LOCK (session);
948
949   /* first look in the cache */
950   caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt));
951   if (caps) {
952     gst_caps_ref (caps);
953     goto done;
954   }
955
956   bin = session->bin;
957
958   GST_DEBUG ("emitting signal for pt %u in session %u", pt, session->id);
959
960   /* not in cache, send signal to request caps */
961   g_value_init (&args[0], GST_TYPE_ELEMENT);
962   g_value_set_object (&args[0], bin);
963   g_value_init (&args[1], G_TYPE_UINT);
964   g_value_set_uint (&args[1], session->id);
965   g_value_init (&args[2], G_TYPE_UINT);
966   g_value_set_uint (&args[2], pt);
967
968   g_value_init (&ret, GST_TYPE_CAPS);
969   g_value_set_boxed (&ret, NULL);
970
971   GST_RTP_SESSION_UNLOCK (session);
972
973   g_signal_emitv (args, gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP], 0, &ret);
974
975   GST_RTP_SESSION_LOCK (session);
976
977   g_value_unset (&args[0]);
978   g_value_unset (&args[1]);
979   g_value_unset (&args[2]);
980
981   /* look in the cache again because we let the lock go */
982   caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt));
983   if (caps) {
984     gst_caps_ref (caps);
985     g_value_unset (&ret);
986     goto done;
987   }
988
989   caps = (GstCaps *) g_value_dup_boxed (&ret);
990   g_value_unset (&ret);
991   if (!caps)
992     goto no_caps;
993
994   GST_DEBUG ("caching pt %u as %" GST_PTR_FORMAT, pt, caps);
995
996   /* store in cache, take additional ref */
997   g_hash_table_insert (session->ptmap, GINT_TO_POINTER (pt),
998       gst_caps_ref (caps));
999
1000 done:
1001   GST_RTP_SESSION_UNLOCK (session);
1002
1003   return caps;
1004
1005   /* ERRORS */
1006 no_caps:
1007   {
1008     GST_RTP_SESSION_UNLOCK (session);
1009     GST_DEBUG ("no pt map could be obtained");
1010     return NULL;
1011   }
1012 }
1013
1014 static gboolean
1015 return_true (gpointer key, gpointer value, gpointer user_data)
1016 {
1017   return TRUE;
1018 }
1019
1020 static void
1021 gst_rtp_bin_reset_sync (GstRtpBin * rtpbin)
1022 {
1023   GSList *clients, *streams;
1024
1025   GST_DEBUG_OBJECT (rtpbin, "Reset sync on all clients");
1026
1027   GST_RTP_BIN_LOCK (rtpbin);
1028   for (clients = rtpbin->clients; clients; clients = g_slist_next (clients)) {
1029     GstRtpBinClient *client = (GstRtpBinClient *) clients->data;
1030
1031     /* reset sync on all streams for this client */
1032     for (streams = client->streams; streams; streams = g_slist_next (streams)) {
1033       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
1034
1035       /* make use require a new SR packet for this stream before we attempt new
1036        * lip-sync */
1037       stream->have_sync = FALSE;
1038       stream->rt_delta = 0;
1039       stream->avg_ts_offset = 0;
1040       stream->is_initialized = FALSE;
1041       stream->rtp_delta = 0;
1042       stream->clock_base = -100 * GST_SECOND;
1043     }
1044   }
1045   GST_RTP_BIN_UNLOCK (rtpbin);
1046 }
1047
1048 static void
1049 gst_rtp_bin_clear_pt_map (GstRtpBin * bin)
1050 {
1051   GSList *sessions, *streams;
1052
1053   GST_RTP_BIN_LOCK (bin);
1054   GST_DEBUG_OBJECT (bin, "clearing pt map");
1055   for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
1056     GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
1057
1058     GST_DEBUG_OBJECT (bin, "clearing session %p", session);
1059     g_signal_emit_by_name (session->session, "clear-pt-map", NULL);
1060
1061     GST_RTP_SESSION_LOCK (session);
1062     g_hash_table_foreach_remove (session->ptmap, return_true, NULL);
1063
1064     for (streams = session->streams; streams; streams = g_slist_next (streams)) {
1065       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
1066
1067       GST_DEBUG_OBJECT (bin, "clearing stream %p", stream);
1068       if (g_signal_lookup ("clear-pt-map", G_OBJECT_TYPE (stream->buffer)) != 0)
1069         g_signal_emit_by_name (stream->buffer, "clear-pt-map", NULL);
1070       if (stream->demux)
1071         g_signal_emit_by_name (stream->demux, "clear-pt-map", NULL);
1072     }
1073     GST_RTP_SESSION_UNLOCK (session);
1074   }
1075   GST_RTP_BIN_UNLOCK (bin);
1076
1077   /* reset sync too */
1078   gst_rtp_bin_reset_sync (bin);
1079 }
1080
1081 static GstElement *
1082 gst_rtp_bin_get_session (GstRtpBin * bin, guint session_id)
1083 {
1084   GstRtpBinSession *session;
1085   GstElement *ret = NULL;
1086
1087   GST_RTP_BIN_LOCK (bin);
1088   GST_DEBUG_OBJECT (bin, "retrieving GstRtpSession, index: %u", session_id);
1089   session = find_session_by_id (bin, (gint) session_id);
1090   if (session) {
1091     ret = gst_object_ref (session->session);
1092   }
1093   GST_RTP_BIN_UNLOCK (bin);
1094
1095   return ret;
1096 }
1097
1098 static RTPSession *
1099 gst_rtp_bin_get_internal_session (GstRtpBin * bin, guint session_id)
1100 {
1101   RTPSession *internal_session = NULL;
1102   GstRtpBinSession *session;
1103
1104   GST_RTP_BIN_LOCK (bin);
1105   GST_DEBUG_OBJECT (bin, "retrieving internal RTPSession object, index: %u",
1106       session_id);
1107   session = find_session_by_id (bin, (gint) session_id);
1108   if (session) {
1109     g_object_get (session->session, "internal-session", &internal_session,
1110         NULL);
1111   }
1112   GST_RTP_BIN_UNLOCK (bin);
1113
1114   return internal_session;
1115 }
1116
1117 static GstElement *
1118 gst_rtp_bin_get_storage (GstRtpBin * bin, guint session_id)
1119 {
1120   GstRtpBinSession *session;
1121   GstElement *res = NULL;
1122
1123   GST_RTP_BIN_LOCK (bin);
1124   GST_DEBUG_OBJECT (bin, "retrieving internal storage object, index: %u",
1125       session_id);
1126   session = find_session_by_id (bin, (gint) session_id);
1127   if (session && session->storage) {
1128     res = gst_object_ref (session->storage);
1129   }
1130   GST_RTP_BIN_UNLOCK (bin);
1131
1132   return res;
1133 }
1134
1135 static GObject *
1136 gst_rtp_bin_get_internal_storage (GstRtpBin * bin, guint session_id)
1137 {
1138   GObject *internal_storage = NULL;
1139   GstRtpBinSession *session;
1140
1141   GST_RTP_BIN_LOCK (bin);
1142   GST_DEBUG_OBJECT (bin, "retrieving internal storage object, index: %u",
1143       session_id);
1144   session = find_session_by_id (bin, (gint) session_id);
1145   if (session && session->storage) {
1146     g_object_get (session->storage, "internal-storage", &internal_storage,
1147         NULL);
1148   }
1149   GST_RTP_BIN_UNLOCK (bin);
1150
1151   return internal_storage;
1152 }
1153
1154 static void
1155 gst_rtp_bin_clear_ssrc (GstRtpBin * bin, guint session_id, guint32 ssrc)
1156 {
1157   GstRtpBinSession *session;
1158   GstElement *demux = NULL;
1159
1160   GST_RTP_BIN_LOCK (bin);
1161   GST_DEBUG_OBJECT (bin, "clearing ssrc %u for session %u", ssrc, session_id);
1162   session = find_session_by_id (bin, (gint) session_id);
1163   if (session)
1164     demux = gst_object_ref (session->demux);
1165   GST_RTP_BIN_UNLOCK (bin);
1166
1167   if (demux) {
1168     g_signal_emit_by_name (demux, "clear-ssrc", ssrc, NULL);
1169     gst_object_unref (demux);
1170   }
1171 }
1172
1173 static GstElement *
1174 gst_rtp_bin_request_encoder (GstRtpBin * bin, guint session_id)
1175 {
1176   GST_DEBUG_OBJECT (bin, "return NULL encoder");
1177   return NULL;
1178 }
1179
1180 static GstElement *
1181 gst_rtp_bin_request_decoder (GstRtpBin * bin, guint session_id)
1182 {
1183   GST_DEBUG_OBJECT (bin, "return NULL decoder");
1184   return NULL;
1185 }
1186
1187 static GstElement *
1188 gst_rtp_bin_request_jitterbuffer (GstRtpBin * bin, guint session_id)
1189 {
1190   return gst_element_factory_make ("rtpjitterbuffer", NULL);
1191 }
1192
1193 static void
1194 gst_rtp_bin_propagate_property_to_jitterbuffer (GstRtpBin * bin,
1195     const gchar * name, const GValue * value)
1196 {
1197   GSList *sessions, *streams;
1198
1199   GST_RTP_BIN_LOCK (bin);
1200   for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
1201     GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
1202
1203     GST_RTP_SESSION_LOCK (session);
1204     for (streams = session->streams; streams; streams = g_slist_next (streams)) {
1205       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
1206       GObjectClass *jb_class;
1207
1208       jb_class = G_OBJECT_GET_CLASS (G_OBJECT (stream->buffer));
1209       if (g_object_class_find_property (jb_class, name))
1210         g_object_set_property (G_OBJECT (stream->buffer), name, value);
1211       else
1212         GST_WARNING_OBJECT (bin,
1213             "Stream jitterbuffer does not expose property %s", name);
1214     }
1215     GST_RTP_SESSION_UNLOCK (session);
1216   }
1217   GST_RTP_BIN_UNLOCK (bin);
1218 }
1219
1220 static void
1221 gst_rtp_bin_propagate_property_to_session (GstRtpBin * bin,
1222     const gchar * name, const GValue * value)
1223 {
1224   GSList *sessions;
1225
1226   GST_RTP_BIN_LOCK (bin);
1227   for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
1228     GstRtpBinSession *sess = (GstRtpBinSession *) sessions->data;
1229
1230     g_object_set_property (G_OBJECT (sess->session), name, value);
1231   }
1232   GST_RTP_BIN_UNLOCK (bin);
1233 }
1234
1235 /* get a client with the given SDES name. Must be called with RTP_BIN_LOCK */
1236 static GstRtpBinClient *
1237 get_client (GstRtpBin * bin, guint8 len, guint8 * data, gboolean * created)
1238 {
1239   GstRtpBinClient *result = NULL;
1240   GSList *walk;
1241
1242   for (walk = bin->clients; walk; walk = g_slist_next (walk)) {
1243     GstRtpBinClient *client = (GstRtpBinClient *) walk->data;
1244
1245     if (len != client->cname_len)
1246       continue;
1247
1248     if (!strncmp ((gchar *) data, client->cname, client->cname_len)) {
1249       GST_DEBUG_OBJECT (bin, "found existing client %p with CNAME %s", client,
1250           client->cname);
1251       result = client;
1252       break;
1253     }
1254   }
1255
1256   /* nothing found, create one */
1257   if (result == NULL) {
1258     result = g_new0 (GstRtpBinClient, 1);
1259     result->cname = g_strndup ((gchar *) data, len);
1260     result->cname_len = len;
1261     bin->clients = g_slist_prepend (bin->clients, result);
1262     GST_DEBUG_OBJECT (bin, "created new client %p with CNAME %s", result,
1263         result->cname);
1264   }
1265   return result;
1266 }
1267
1268 static void
1269 free_client (GstRtpBinClient * client, GstRtpBin * bin)
1270 {
1271   GST_DEBUG_OBJECT (bin, "freeing client %p", client);
1272   g_slist_free (client->streams);
1273   g_free (client->cname);
1274   g_free (client);
1275 }
1276
1277 static void
1278 get_current_times (GstRtpBin * bin, GstClockTime * running_time,
1279     guint64 * ntpnstime)
1280 {
1281   guint64 ntpns = -1;
1282   GstClock *clock;
1283   GstClockTime base_time, rt, clock_time;
1284
1285   GST_OBJECT_LOCK (bin);
1286   if ((clock = GST_ELEMENT_CLOCK (bin))) {
1287     base_time = GST_ELEMENT_CAST (bin)->base_time;
1288     gst_object_ref (clock);
1289     GST_OBJECT_UNLOCK (bin);
1290
1291     /* get current clock time and convert to running time */
1292     clock_time = gst_clock_get_time (clock);
1293     rt = clock_time - base_time;
1294
1295     if (bin->use_pipeline_clock) {
1296       ntpns = rt;
1297       /* add constant to convert from 1970 based time to 1900 based time */
1298       ntpns += (2208988800LL * GST_SECOND);
1299     } else {
1300       switch (bin->ntp_time_source) {
1301         case GST_RTP_NTP_TIME_SOURCE_NTP:
1302         case GST_RTP_NTP_TIME_SOURCE_UNIX:{
1303           /* get current NTP time */
1304           ntpns = g_get_real_time () * GST_USECOND;
1305
1306           /* add constant to convert from 1970 based time to 1900 based time */
1307           if (bin->ntp_time_source == GST_RTP_NTP_TIME_SOURCE_NTP)
1308             ntpns += (2208988800LL * GST_SECOND);
1309           break;
1310         }
1311         case GST_RTP_NTP_TIME_SOURCE_RUNNING_TIME:
1312           ntpns = rt;
1313           break;
1314         case GST_RTP_NTP_TIME_SOURCE_CLOCK_TIME:
1315           ntpns = clock_time;
1316           break;
1317         default:
1318           ntpns = -1;           /* Fix uninited compiler warning */
1319           g_assert_not_reached ();
1320           break;
1321       }
1322     }
1323
1324     gst_object_unref (clock);
1325   } else {
1326     GST_OBJECT_UNLOCK (bin);
1327     rt = -1;
1328     ntpns = -1;
1329   }
1330   if (running_time)
1331     *running_time = rt;
1332   if (ntpnstime)
1333     *ntpnstime = ntpns;
1334 }
1335
1336 static void
1337 stream_set_ts_offset (GstRtpBin * bin, GstRtpBinStream * stream,
1338     gint64 ts_offset, gint64 max_ts_offset, guint64 min_ts_offset,
1339     gboolean allow_positive_ts_offset)
1340 {
1341   gint64 prev_ts_offset;
1342   GObjectClass *jb_class;
1343
1344   jb_class = G_OBJECT_GET_CLASS (G_OBJECT (stream->buffer));
1345
1346   if (!g_object_class_find_property (jb_class, "ts-offset")) {
1347     GST_LOG_OBJECT (bin,
1348         "stream's jitterbuffer does not expose ts-offset property");
1349     return;
1350   }
1351
1352   if (bin->ts_offset_smoothing_factor > 0) {
1353     if (!stream->is_initialized) {
1354       stream->avg_ts_offset = ts_offset;
1355       stream->is_initialized = TRUE;
1356     } else {
1357       stream->avg_ts_offset =
1358           ((bin->ts_offset_smoothing_factor - 1) * stream->avg_ts_offset +
1359           ts_offset) / bin->ts_offset_smoothing_factor;
1360     }
1361   } else {
1362     stream->avg_ts_offset = ts_offset;
1363   }
1364
1365   g_object_get (stream->buffer, "ts-offset", &prev_ts_offset, NULL);
1366
1367   /* delta changed, see how much */
1368   if (prev_ts_offset != stream->avg_ts_offset) {
1369     gint64 diff;
1370
1371     diff = prev_ts_offset - stream->avg_ts_offset;
1372
1373     GST_DEBUG_OBJECT (bin,
1374         "ts-offset %" G_GINT64_FORMAT ", prev %" G_GINT64_FORMAT
1375         ", diff: %" G_GINT64_FORMAT, stream->avg_ts_offset, prev_ts_offset,
1376         diff);
1377
1378     /* ignore minor offsets */
1379     if (ABS (diff) < min_ts_offset) {
1380       GST_DEBUG_OBJECT (bin, "offset too small, ignoring");
1381       return;
1382     }
1383
1384     /* sanity check offset */
1385     if (max_ts_offset > 0) {
1386       if (stream->avg_ts_offset > 0 && !allow_positive_ts_offset) {
1387         GST_DEBUG_OBJECT (bin,
1388             "offset is positive (clocks are out of sync), ignoring");
1389         return;
1390       }
1391       if (ABS (stream->avg_ts_offset) > max_ts_offset) {
1392         GST_DEBUG_OBJECT (bin, "offset too large, ignoring");
1393         return;
1394       }
1395     }
1396
1397     g_object_set (stream->buffer, "ts-offset", stream->avg_ts_offset, NULL);
1398   }
1399   GST_DEBUG_OBJECT (bin, "stream SSRC %08x, delta %" G_GINT64_FORMAT,
1400       stream->ssrc, stream->avg_ts_offset);
1401 }
1402
1403 static void
1404 gst_rtp_bin_send_sync_event (GstRtpBinStream * stream)
1405 {
1406   if (stream->bin->send_sync_event) {
1407     GstEvent *event;
1408     GstPad *srcpad;
1409
1410     GST_DEBUG_OBJECT (stream->bin,
1411         "sending GstRTCPSRReceived event downstream");
1412
1413     event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM,
1414         gst_structure_new_empty ("GstRTCPSRReceived"));
1415
1416     srcpad = gst_element_get_static_pad (stream->buffer, "src");
1417     gst_pad_push_event (srcpad, event);
1418     gst_object_unref (srcpad);
1419   }
1420 }
1421
1422 /* associate a stream to the given CNAME. This will make sure all streams for
1423  * that CNAME are synchronized together.
1424  * Must be called with GST_RTP_BIN_LOCK */
1425 static void
1426 gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
1427     guint8 * data, guint64 ntptime, guint64 last_extrtptime,
1428     guint64 base_rtptime, guint64 base_time, guint clock_rate,
1429     gint64 rtp_clock_base)
1430 {
1431   GstRtpBinClient *client;
1432   gboolean created;
1433   GSList *walk;
1434   GstClockTime running_time, running_time_rtp;
1435   guint64 ntpnstime;
1436
1437   /* first find or create the CNAME */
1438   client = get_client (bin, len, data, &created);
1439
1440   /* find stream in the client */
1441   for (walk = client->streams; walk; walk = g_slist_next (walk)) {
1442     GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
1443
1444     if (ostream == stream)
1445       break;
1446   }
1447   /* not found, add it to the list */
1448   if (walk == NULL) {
1449     GST_DEBUG_OBJECT (bin,
1450         "new association of SSRC %08x with client %p with CNAME %s",
1451         stream->ssrc, client, client->cname);
1452     client->streams = g_slist_prepend (client->streams, stream);
1453     client->nstreams++;
1454   } else {
1455     GST_DEBUG_OBJECT (bin,
1456         "found association of SSRC %08x with client %p with CNAME %s",
1457         stream->ssrc, client, client->cname);
1458   }
1459
1460   if (!GST_CLOCK_TIME_IS_VALID (last_extrtptime)) {
1461     GST_DEBUG_OBJECT (bin, "invalidated sync data");
1462     if (bin->rtcp_sync == GST_RTP_BIN_RTCP_SYNC_RTP) {
1463       /* we don't need that data, so carry on,
1464        * but make some values look saner */
1465       last_extrtptime = base_rtptime;
1466     } else {
1467       /* nothing we can do with this data in this case */
1468       GST_DEBUG_OBJECT (bin, "bailing out");
1469       return;
1470     }
1471   }
1472
1473   /* Take the extended rtptime we found in the SR packet and map it to the
1474    * local rtptime. The local rtp time is used to construct timestamps on the
1475    * buffers so we will calculate what running_time corresponds to the RTP
1476    * timestamp in the SR packet. */
1477   running_time_rtp = last_extrtptime - base_rtptime;
1478
1479   GST_DEBUG_OBJECT (bin,
1480       "base %" G_GUINT64_FORMAT ", extrtptime %" G_GUINT64_FORMAT
1481       ", local RTP %" G_GUINT64_FORMAT ", clock-rate %d, "
1482       "clock-base %" G_GINT64_FORMAT, base_rtptime,
1483       last_extrtptime, running_time_rtp, clock_rate, rtp_clock_base);
1484
1485   /* calculate local RTP time in gstreamer timestamp, we essentially perform the
1486    * same conversion that a jitterbuffer would use to convert an rtp timestamp
1487    * into a corresponding gstreamer timestamp. Note that the base_time also
1488    * contains the drift between sender and receiver. */
1489   running_time =
1490       gst_util_uint64_scale_int (running_time_rtp, GST_SECOND, clock_rate);
1491   running_time += base_time;
1492
1493   /* convert ntptime to nanoseconds */
1494   ntpnstime = gst_util_uint64_scale (ntptime, GST_SECOND,
1495       (G_GINT64_CONSTANT (1) << 32));
1496
1497   stream->have_sync = TRUE;
1498
1499   GST_DEBUG_OBJECT (bin,
1500       "SR RTP running time %" G_GUINT64_FORMAT ", SR NTP %" G_GUINT64_FORMAT,
1501       running_time, ntpnstime);
1502
1503   /* recalc inter stream playout offset, but only if there is more than one
1504    * stream or we're doing NTP sync. */
1505   if (bin->ntp_sync) {
1506     gint64 ntpdiff, rtdiff;
1507     guint64 local_ntpnstime;
1508     GstClockTime local_running_time;
1509
1510     /* For NTP sync we need to first get a snapshot of running_time and NTP
1511      * time. We know at what running_time we play a certain RTP time, we also
1512      * calculated when we would play the RTP time in the SR packet. Now we need
1513      * to know how the running_time and the NTP time relate to each other. */
1514     get_current_times (bin, &local_running_time, &local_ntpnstime);
1515
1516     /* see how far away the NTP time is. This is the difference between the
1517      * current NTP time and the NTP time in the last SR packet. */
1518     ntpdiff = local_ntpnstime - ntpnstime;
1519     /* see how far away the running_time is. This is the difference between the
1520      * current running_time and the running_time of the RTP timestamp in the
1521      * last SR packet. */
1522     rtdiff = local_running_time - running_time;
1523
1524     GST_DEBUG_OBJECT (bin,
1525         "local NTP time %" G_GUINT64_FORMAT ", SR NTP time %" G_GUINT64_FORMAT,
1526         local_ntpnstime, ntpnstime);
1527     GST_DEBUG_OBJECT (bin,
1528         "local running time %" G_GUINT64_FORMAT ", SR RTP running time %"
1529         G_GUINT64_FORMAT, local_running_time, running_time);
1530     GST_DEBUG_OBJECT (bin,
1531         "NTP diff %" G_GINT64_FORMAT ", RT diff %" G_GINT64_FORMAT, ntpdiff,
1532         rtdiff);
1533
1534     /* combine to get the final diff to apply to the running_time */
1535     stream->rt_delta = rtdiff - ntpdiff;
1536
1537     stream_set_ts_offset (bin, stream, stream->rt_delta, bin->max_ts_offset,
1538         bin->min_ts_offset, FALSE);
1539   } else {
1540     gint64 min, rtp_min, clock_base = stream->clock_base;
1541     gboolean all_sync, use_rtp;
1542     gboolean rtcp_sync = g_atomic_int_get (&bin->rtcp_sync);
1543
1544     /* calculate delta between server and receiver. ntpnstime is created by
1545      * converting the ntptime in the last SR packet to a gstreamer timestamp. This
1546      * delta expresses the difference to our timeline and the server timeline. The
1547      * difference in itself doesn't mean much but we can combine the delta of
1548      * multiple streams to create a stream specific offset. */
1549     stream->rt_delta = ntpnstime - running_time;
1550
1551     /* calculate the min of all deltas, ignoring streams that did not yet have a
1552      * valid rt_delta because we did not yet receive an SR packet for those
1553      * streams.
1554      * We calculate the minimum because we would like to only apply positive
1555      * offsets to streams, delaying their playback instead of trying to speed up
1556      * other streams (which might be impossible when we have to create negative
1557      * latencies).
1558      * The stream that has the smallest diff is selected as the reference stream,
1559      * all other streams will have a positive offset to this difference. */
1560
1561     /* some alternative setting allow ignoring RTCP as much as possible,
1562      * for servers generating bogus ntp timeline */
1563     min = rtp_min = G_MAXINT64;
1564     use_rtp = FALSE;
1565     if (rtcp_sync == GST_RTP_BIN_RTCP_SYNC_RTP) {
1566       guint64 ext_base;
1567
1568       use_rtp = TRUE;
1569       /* signed version for convenience */
1570       clock_base = base_rtptime;
1571       /* deal with possible wrap-around */
1572       ext_base = base_rtptime;
1573       rtp_clock_base = gst_rtp_buffer_ext_timestamp (&ext_base, rtp_clock_base);
1574       /* sanity check; base rtp and provided clock_base should be close */
1575       if (rtp_clock_base >= clock_base) {
1576         if (rtp_clock_base - clock_base < 10 * clock_rate) {
1577           rtp_clock_base = base_time +
1578               gst_util_uint64_scale_int (rtp_clock_base - clock_base,
1579               GST_SECOND, clock_rate);
1580         } else {
1581           use_rtp = FALSE;
1582         }
1583       } else {
1584         if (clock_base - rtp_clock_base < 10 * clock_rate) {
1585           rtp_clock_base = base_time -
1586               gst_util_uint64_scale_int (clock_base - rtp_clock_base,
1587               GST_SECOND, clock_rate);
1588         } else {
1589           use_rtp = FALSE;
1590         }
1591       }
1592       /* warn and bail for clarity out if no sane values */
1593       if (!use_rtp) {
1594         GST_WARNING_OBJECT (bin, "unable to sync to provided rtptime");
1595         return;
1596       }
1597       /* store to track changes */
1598       clock_base = rtp_clock_base;
1599       /* generate a fake as before,
1600        * now equating rtptime obtained from RTP-Info,
1601        * where the large time represent the otherwise irrelevant npt/ntp time */
1602       stream->rtp_delta = (GST_SECOND << 28) - rtp_clock_base;
1603     } else {
1604       clock_base = rtp_clock_base;
1605     }
1606
1607     all_sync = TRUE;
1608     for (walk = client->streams; walk; walk = g_slist_next (walk)) {
1609       GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
1610
1611       if (!ostream->have_sync) {
1612         all_sync = FALSE;
1613         continue;
1614       }
1615
1616       /* change in current stream's base from previously init'ed value
1617        * leads to reset of all stream's base */
1618       if (stream != ostream && stream->clock_base >= 0 &&
1619           (stream->clock_base != clock_base)) {
1620         GST_DEBUG_OBJECT (bin, "reset upon clock base change");
1621         ostream->clock_base = -100 * GST_SECOND;
1622         ostream->rtp_delta = 0;
1623       }
1624
1625       if (ostream->rt_delta < min)
1626         min = ostream->rt_delta;
1627       if (ostream->rtp_delta < rtp_min)
1628         rtp_min = ostream->rtp_delta;
1629     }
1630
1631     /* arrange to re-sync for each stream upon significant change,
1632      * e.g. post-seek */
1633     all_sync = all_sync && (stream->clock_base == clock_base);
1634     stream->clock_base = clock_base;
1635
1636     /* may need init performed above later on, but nothing more to do now */
1637     if (client->nstreams <= 1)
1638       return;
1639
1640     GST_DEBUG_OBJECT (bin, "client %p min delta %" G_GINT64_FORMAT
1641         " all sync %d", client, min, all_sync);
1642     GST_DEBUG_OBJECT (bin, "rtcp sync mode %d, use_rtp %d", rtcp_sync, use_rtp);
1643
1644     switch (rtcp_sync) {
1645       case GST_RTP_BIN_RTCP_SYNC_RTP:
1646         if (!use_rtp)
1647           break;
1648         GST_DEBUG_OBJECT (bin, "using rtp generated reports; "
1649             "client %p min rtp delta %" G_GINT64_FORMAT, client, rtp_min);
1650         /* fall-through */
1651       case GST_RTP_BIN_RTCP_SYNC_INITIAL:
1652         /* if all have been synced already, do not bother further */
1653         if (all_sync) {
1654           GST_DEBUG_OBJECT (bin, "all streams already synced; done");
1655           return;
1656         }
1657         break;
1658       default:
1659         break;
1660     }
1661
1662     /* bail out if we adjusted recently enough */
1663     if (all_sync && (ntpnstime - bin->priv->last_ntpnstime) <
1664         bin->rtcp_sync_interval * GST_MSECOND) {
1665       GST_DEBUG_OBJECT (bin, "discarding RTCP sender packet for sync; "
1666           "previous sender info too recent "
1667           "(previous NTP %" G_GUINT64_FORMAT ")", bin->priv->last_ntpnstime);
1668       return;
1669     }
1670     bin->priv->last_ntpnstime = ntpnstime;
1671
1672     /* calculate offsets for each stream */
1673     for (walk = client->streams; walk; walk = g_slist_next (walk)) {
1674       GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
1675       gint64 ts_offset;
1676
1677       /* ignore streams for which we didn't receive an SR packet yet, we
1678        * can't synchronize them yet. We can however sync other streams just
1679        * fine. */
1680       if (!ostream->have_sync)
1681         continue;
1682
1683       /* calculate offset to our reference stream, this should always give a
1684        * positive number. */
1685       if (use_rtp)
1686         ts_offset = ostream->rtp_delta - rtp_min;
1687       else
1688         ts_offset = ostream->rt_delta - min;
1689
1690       stream_set_ts_offset (bin, ostream, ts_offset, bin->max_ts_offset,
1691           bin->min_ts_offset, TRUE);
1692     }
1693   }
1694   gst_rtp_bin_send_sync_event (stream);
1695
1696   return;
1697 }
1698
1699 #define GST_RTCP_BUFFER_FOR_PACKETS(b,buffer,packet) \
1700   for ((b) = gst_rtcp_buffer_get_first_packet ((buffer), (packet)); (b); \
1701           (b) = gst_rtcp_packet_move_to_next ((packet)))
1702
1703 #define GST_RTCP_SDES_FOR_ITEMS(b,packet) \
1704   for ((b) = gst_rtcp_packet_sdes_first_item ((packet)); (b); \
1705           (b) = gst_rtcp_packet_sdes_next_item ((packet)))
1706
1707 #define GST_RTCP_SDES_FOR_ENTRIES(b,packet) \
1708   for ((b) = gst_rtcp_packet_sdes_first_entry ((packet)); (b); \
1709           (b) = gst_rtcp_packet_sdes_next_entry ((packet)))
1710
1711 static void
1712 gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s,
1713     GstRtpBinStream * stream)
1714 {
1715   GstRtpBin *bin;
1716   GstRTCPPacket packet;
1717   guint32 ssrc;
1718   guint64 ntptime;
1719   gboolean have_sr, have_sdes;
1720   gboolean more;
1721   guint64 base_rtptime;
1722   guint64 base_time;
1723   guint clock_rate;
1724   guint64 clock_base;
1725   guint64 extrtptime;
1726   GstBuffer *buffer;
1727   GstRTCPBuffer rtcp = { NULL, };
1728
1729   bin = stream->bin;
1730
1731   GST_DEBUG_OBJECT (bin, "sync handler called");
1732
1733   /* get the last relation between the rtp timestamps and the gstreamer
1734    * timestamps. We get this info directly from the jitterbuffer which
1735    * constructs gstreamer timestamps from rtp timestamps and so it know exactly
1736    * what the current situation is. */
1737   base_rtptime =
1738       g_value_get_uint64 (gst_structure_get_value (s, "base-rtptime"));
1739   base_time = g_value_get_uint64 (gst_structure_get_value (s, "base-time"));
1740   clock_rate = g_value_get_uint (gst_structure_get_value (s, "clock-rate"));
1741   clock_base = g_value_get_uint64 (gst_structure_get_value (s, "clock-base"));
1742   extrtptime =
1743       g_value_get_uint64 (gst_structure_get_value (s, "sr-ext-rtptime"));
1744   buffer = gst_value_get_buffer (gst_structure_get_value (s, "sr-buffer"));
1745
1746   have_sr = FALSE;
1747   have_sdes = FALSE;
1748
1749   gst_rtcp_buffer_map (buffer, GST_MAP_READ, &rtcp);
1750
1751   GST_RTCP_BUFFER_FOR_PACKETS (more, &rtcp, &packet) {
1752     /* first packet must be SR or RR or else the validate would have failed */
1753     switch (gst_rtcp_packet_get_type (&packet)) {
1754       case GST_RTCP_TYPE_SR:
1755         /* only parse first. There is only supposed to be one SR in the packet
1756          * but we will deal with malformed packets gracefully */
1757         if (have_sr)
1758           break;
1759         /* get NTP and RTP times */
1760         gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, &ntptime, NULL,
1761             NULL, NULL);
1762
1763         GST_DEBUG_OBJECT (bin, "received sync packet from SSRC %08x", ssrc);
1764         /* ignore SR that is not ours */
1765         if (ssrc != stream->ssrc)
1766           continue;
1767
1768         have_sr = TRUE;
1769         break;
1770       case GST_RTCP_TYPE_SDES:
1771       {
1772         gboolean more_items, more_entries;
1773
1774         /* only deal with first SDES, there is only supposed to be one SDES in
1775          * the RTCP packet but we deal with bad packets gracefully. Also bail
1776          * out if we have not seen an SR item yet. */
1777         if (have_sdes || !have_sr)
1778           break;
1779
1780         GST_RTCP_SDES_FOR_ITEMS (more_items, &packet) {
1781           /* skip items that are not about the SSRC of the sender */
1782           if (gst_rtcp_packet_sdes_get_ssrc (&packet) != ssrc)
1783             continue;
1784
1785           /* find the CNAME entry */
1786           GST_RTCP_SDES_FOR_ENTRIES (more_entries, &packet) {
1787             GstRTCPSDESType type;
1788             guint8 len;
1789             guint8 *data;
1790
1791             gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data);
1792
1793             if (type == GST_RTCP_SDES_CNAME) {
1794               GST_RTP_BIN_LOCK (bin);
1795               /* associate the stream to CNAME */
1796               gst_rtp_bin_associate (bin, stream, len, data,
1797                   ntptime, extrtptime, base_rtptime, base_time, clock_rate,
1798                   clock_base);
1799               GST_RTP_BIN_UNLOCK (bin);
1800             }
1801           }
1802         }
1803         have_sdes = TRUE;
1804         break;
1805       }
1806       default:
1807         /* we can ignore these packets */
1808         break;
1809     }
1810   }
1811   gst_rtcp_buffer_unmap (&rtcp);
1812 }
1813
1814 /* create a new stream with @ssrc in @session. Must be called with
1815  * RTP_SESSION_LOCK. */
1816 static GstRtpBinStream *
1817 create_stream (GstRtpBinSession * session, guint32 ssrc)
1818 {
1819   GstElement *buffer, *demux = NULL;
1820   GstRtpBinStream *stream;
1821   GstRtpBin *rtpbin;
1822   GstState target;
1823   GObjectClass *jb_class;
1824
1825   rtpbin = session->bin;
1826
1827   if (g_slist_length (session->streams) >= rtpbin->max_streams)
1828     goto max_streams;
1829
1830   if (!(buffer =
1831           session_request_element (session, SIGNAL_REQUEST_JITTERBUFFER)))
1832     goto no_jitterbuffer;
1833
1834   if (!rtpbin->ignore_pt) {
1835     if (!(demux = gst_element_factory_make ("rtpptdemux", NULL)))
1836       goto no_demux;
1837   }
1838
1839   stream = g_new0 (GstRtpBinStream, 1);
1840   stream->ssrc = ssrc;
1841   stream->bin = rtpbin;
1842   stream->session = session;
1843   stream->buffer = gst_object_ref (buffer);
1844   stream->demux = demux;
1845
1846   stream->have_sync = FALSE;
1847   stream->rt_delta = 0;
1848   stream->avg_ts_offset = 0;
1849   stream->is_initialized = FALSE;
1850   stream->rtp_delta = 0;
1851   stream->percent = 100;
1852   stream->clock_base = -100 * GST_SECOND;
1853   session->streams = g_slist_prepend (session->streams, stream);
1854
1855   jb_class = G_OBJECT_GET_CLASS (G_OBJECT (buffer));
1856
1857   if (g_signal_lookup ("request-pt-map", G_OBJECT_TYPE (buffer)) != 0) {
1858     /* provide clock_rate to the jitterbuffer when needed */
1859     stream->buffer_ptreq_sig = g_signal_connect (buffer, "request-pt-map",
1860         (GCallback) pt_map_requested, session);
1861   }
1862   if (g_signal_lookup ("on-npt-stop", G_OBJECT_TYPE (buffer)) != 0) {
1863     stream->buffer_ntpstop_sig = g_signal_connect (buffer, "on-npt-stop",
1864         (GCallback) on_npt_stop, stream);
1865   }
1866
1867   g_object_set_data (G_OBJECT (buffer), "GstRTPBin.session", session);
1868   g_object_set_data (G_OBJECT (buffer), "GstRTPBin.stream", stream);
1869
1870   /* configure latency and packet lost */
1871   g_object_set (buffer, "latency", rtpbin->latency_ms, NULL);
1872
1873   if (g_object_class_find_property (jb_class, "drop-on-latency"))
1874     g_object_set (buffer, "drop-on-latency", rtpbin->drop_on_latency, NULL);
1875   if (g_object_class_find_property (jb_class, "do-lost"))
1876     g_object_set (buffer, "do-lost", rtpbin->do_lost, NULL);
1877   if (g_object_class_find_property (jb_class, "mode"))
1878     g_object_set (buffer, "mode", rtpbin->buffer_mode, NULL);
1879   if (g_object_class_find_property (jb_class, "do-retransmission"))
1880     g_object_set (buffer, "do-retransmission", rtpbin->do_retransmission, NULL);
1881   if (g_object_class_find_property (jb_class, "max-rtcp-rtp-time-diff"))
1882     g_object_set (buffer, "max-rtcp-rtp-time-diff",
1883         rtpbin->max_rtcp_rtp_time_diff, NULL);
1884   if (g_object_class_find_property (jb_class, "max-dropout-time"))
1885     g_object_set (buffer, "max-dropout-time", rtpbin->max_dropout_time, NULL);
1886   if (g_object_class_find_property (jb_class, "max-misorder-time"))
1887     g_object_set (buffer, "max-misorder-time", rtpbin->max_misorder_time, NULL);
1888   if (g_object_class_find_property (jb_class, "rfc7273-sync"))
1889     g_object_set (buffer, "rfc7273-sync", rtpbin->rfc7273_sync, NULL);
1890   if (g_object_class_find_property (jb_class, "max-ts-offset-adjustment"))
1891     g_object_set (buffer, "max-ts-offset-adjustment",
1892         rtpbin->max_ts_offset_adjustment, NULL);
1893
1894   g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_JITTERBUFFER], 0,
1895       buffer, session->id, ssrc);
1896
1897   if (!rtpbin->ignore_pt)
1898     gst_bin_add (GST_BIN_CAST (rtpbin), demux);
1899
1900   /* link stuff */
1901   if (demux)
1902     gst_element_link_pads_full (buffer, "src", demux, "sink",
1903         GST_PAD_LINK_CHECK_NOTHING);
1904
1905   if (rtpbin->buffering) {
1906     guint64 last_out;
1907
1908     if (g_signal_lookup ("set-active", G_OBJECT_TYPE (buffer)) != 0) {
1909       GST_INFO_OBJECT (rtpbin,
1910           "bin is buffering, set jitterbuffer as not active");
1911       g_signal_emit_by_name (buffer, "set-active", FALSE, (gint64) 0,
1912           &last_out);
1913     }
1914   }
1915
1916
1917   GST_OBJECT_LOCK (rtpbin);
1918   target = GST_STATE_TARGET (rtpbin);
1919   GST_OBJECT_UNLOCK (rtpbin);
1920
1921   /* from sink to source */
1922   if (demux)
1923     gst_element_set_state (demux, target);
1924
1925   gst_element_set_state (buffer, target);
1926
1927   return stream;
1928
1929   /* ERRORS */
1930 max_streams:
1931   {
1932     GST_WARNING_OBJECT (rtpbin, "stream exceeds maximum (%d)",
1933         rtpbin->max_streams);
1934     return NULL;
1935   }
1936 no_jitterbuffer:
1937   {
1938     g_warning ("rtpbin: could not create rtpjitterbuffer element");
1939     return NULL;
1940   }
1941 no_demux:
1942   {
1943     gst_object_unref (buffer);
1944     g_warning ("rtpbin: could not create rtpptdemux element");
1945     return NULL;
1946   }
1947 }
1948
1949 /* called with RTP_BIN_LOCK */
1950 static void
1951 free_stream (GstRtpBinStream * stream, GstRtpBin * bin)
1952 {
1953   GstRtpBinSession *sess = stream->session;
1954   GSList *clients, *next_client;
1955
1956   GST_DEBUG_OBJECT (bin, "freeing stream %p", stream);
1957
1958   gst_element_set_locked_state (stream->buffer, TRUE);
1959   if (stream->demux)
1960     gst_element_set_locked_state (stream->demux, TRUE);
1961
1962   gst_element_set_state (stream->buffer, GST_STATE_NULL);
1963   if (stream->demux)
1964     gst_element_set_state (stream->demux, GST_STATE_NULL);
1965
1966   if (stream->demux) {
1967     g_signal_handler_disconnect (stream->demux, stream->demux_newpad_sig);
1968     g_signal_handler_disconnect (stream->demux, stream->demux_ptreq_sig);
1969     g_signal_handler_disconnect (stream->demux, stream->demux_ptchange_sig);
1970     g_signal_handler_disconnect (stream->demux, stream->demux_padremoved_sig);
1971   }
1972
1973   if (stream->buffer_handlesync_sig)
1974     g_signal_handler_disconnect (stream->buffer, stream->buffer_handlesync_sig);
1975   if (stream->buffer_ptreq_sig)
1976     g_signal_handler_disconnect (stream->buffer, stream->buffer_ptreq_sig);
1977   if (stream->buffer_ntpstop_sig)
1978     g_signal_handler_disconnect (stream->buffer, stream->buffer_ntpstop_sig);
1979
1980   sess->elements = g_slist_remove (sess->elements, stream->buffer);
1981   remove_bin_element (stream->buffer, bin);
1982   gst_object_unref (stream->buffer);
1983
1984   if (stream->demux)
1985     gst_bin_remove (GST_BIN_CAST (bin), stream->demux);
1986
1987   for (clients = bin->clients; clients; clients = next_client) {
1988     GstRtpBinClient *client = (GstRtpBinClient *) clients->data;
1989     GSList *streams, *next_stream;
1990
1991     next_client = g_slist_next (clients);
1992
1993     for (streams = client->streams; streams; streams = next_stream) {
1994       GstRtpBinStream *ostream = (GstRtpBinStream *) streams->data;
1995
1996       next_stream = g_slist_next (streams);
1997
1998       if (ostream == stream) {
1999         client->streams = g_slist_delete_link (client->streams, streams);
2000         /* If this was the last stream belonging to this client,
2001          * clean up the client. */
2002         if (--client->nstreams == 0) {
2003           bin->clients = g_slist_delete_link (bin->clients, clients);
2004           free_client (client, bin);
2005           break;
2006         }
2007       }
2008     }
2009   }
2010   g_free (stream);
2011 }
2012
2013 /* GObject vmethods */
2014 static void gst_rtp_bin_dispose (GObject * object);
2015 static void gst_rtp_bin_finalize (GObject * object);
2016 static void gst_rtp_bin_set_property (GObject * object, guint prop_id,
2017     const GValue * value, GParamSpec * pspec);
2018 static void gst_rtp_bin_get_property (GObject * object, guint prop_id,
2019     GValue * value, GParamSpec * pspec);
2020
2021 /* GstElement vmethods */
2022 static GstStateChangeReturn gst_rtp_bin_change_state (GstElement * element,
2023     GstStateChange transition);
2024 static GstPad *gst_rtp_bin_request_new_pad (GstElement * element,
2025     GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
2026 static void gst_rtp_bin_release_pad (GstElement * element, GstPad * pad);
2027 static void gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message);
2028
2029 #define gst_rtp_bin_parent_class parent_class
2030 G_DEFINE_TYPE_WITH_PRIVATE (GstRtpBin, gst_rtp_bin, GST_TYPE_BIN);
2031 GST_ELEMENT_REGISTER_DEFINE (rtpbin, "rtpbin", GST_RANK_NONE, GST_TYPE_RTP_BIN);
2032
2033 static gboolean
2034 _gst_element_accumulator (GSignalInvocationHint * ihint,
2035     GValue * return_accu, const GValue * handler_return, gpointer dummy)
2036 {
2037   GstElement *element;
2038
2039   element = g_value_get_object (handler_return);
2040   GST_DEBUG ("got element %" GST_PTR_FORMAT, element);
2041
2042   g_value_set_object (return_accu, element);
2043
2044   /* stop emission if we have an element */
2045   return (element == NULL);
2046 }
2047
2048 static gboolean
2049 _gst_caps_accumulator (GSignalInvocationHint * ihint,
2050     GValue * return_accu, const GValue * handler_return, gpointer dummy)
2051 {
2052   GstCaps *caps;
2053
2054   caps = g_value_get_boxed (handler_return);
2055   GST_DEBUG ("got caps %" GST_PTR_FORMAT, caps);
2056
2057   g_value_set_boxed (return_accu, caps);
2058
2059   /* stop emission if we have a caps */
2060   return (caps == NULL);
2061 }
2062
2063 static void
2064 gst_rtp_bin_class_init (GstRtpBinClass * klass)
2065 {
2066   GObjectClass *gobject_class;
2067   GstElementClass *gstelement_class;
2068   GstBinClass *gstbin_class;
2069
2070   gobject_class = (GObjectClass *) klass;
2071   gstelement_class = (GstElementClass *) klass;
2072   gstbin_class = (GstBinClass *) klass;
2073
2074   gobject_class->dispose = gst_rtp_bin_dispose;
2075   gobject_class->finalize = gst_rtp_bin_finalize;
2076   gobject_class->set_property = gst_rtp_bin_set_property;
2077   gobject_class->get_property = gst_rtp_bin_get_property;
2078
2079   g_object_class_install_property (gobject_class, PROP_LATENCY,
2080       g_param_spec_uint ("latency", "Buffer latency in ms",
2081           "Default amount of ms to buffer in the jitterbuffers", 0,
2082           G_MAXUINT, DEFAULT_LATENCY_MS,
2083           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2084
2085   g_object_class_install_property (gobject_class, PROP_DROP_ON_LATENCY,
2086       g_param_spec_boolean ("drop-on-latency",
2087           "Drop buffers when maximum latency is reached",
2088           "Tells the jitterbuffer to never exceed the given latency in size",
2089           DEFAULT_DROP_ON_LATENCY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2090
2091   /**
2092    * GstRtpBin::request-pt-map:
2093    * @rtpbin: the object which received the signal
2094    * @session: the session
2095    * @pt: the pt
2096    *
2097    * Request the payload type as #GstCaps for @pt in @session.
2098    */
2099   gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP] =
2100       g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass),
2101       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, request_pt_map),
2102       _gst_caps_accumulator, NULL, NULL, GST_TYPE_CAPS, 2, G_TYPE_UINT,
2103       G_TYPE_UINT);
2104
2105     /**
2106    * GstRtpBin::payload-type-change:
2107    * @rtpbin: the object which received the signal
2108    * @session: the session
2109    * @pt: the pt
2110    *
2111    * Signal that the current payload type changed to @pt in @session.
2112    */
2113   gst_rtp_bin_signals[SIGNAL_PAYLOAD_TYPE_CHANGE] =
2114       g_signal_new ("payload-type-change", G_TYPE_FROM_CLASS (klass),
2115       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, payload_type_change),
2116       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2117
2118   /**
2119    * GstRtpBin::clear-pt-map:
2120    * @rtpbin: the object which received the signal
2121    *
2122    * Clear all previously cached pt-mapping obtained with
2123    * #GstRtpBin::request-pt-map.
2124    */
2125   gst_rtp_bin_signals[SIGNAL_CLEAR_PT_MAP] =
2126       g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass),
2127       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
2128           clear_pt_map), NULL, NULL, NULL, G_TYPE_NONE, 0, G_TYPE_NONE);
2129
2130   /**
2131    * GstRtpBin::reset-sync:
2132    * @rtpbin: the object which received the signal
2133    *
2134    * Reset all currently configured lip-sync parameters and require new SR
2135    * packets for all streams before lip-sync is attempted again.
2136    */
2137   gst_rtp_bin_signals[SIGNAL_RESET_SYNC] =
2138       g_signal_new ("reset-sync", G_TYPE_FROM_CLASS (klass),
2139       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
2140           reset_sync), NULL, NULL, NULL, G_TYPE_NONE, 0, G_TYPE_NONE);
2141
2142   /**
2143    * GstRtpBin::get-session:
2144    * @rtpbin: the object which received the signal
2145    * @id: the session id
2146    *
2147    * Request the related GstRtpSession as #GstElement related with session @id.
2148    *
2149    * Since: 1.8
2150    */
2151   gst_rtp_bin_signals[SIGNAL_GET_SESSION] =
2152       g_signal_new ("get-session", G_TYPE_FROM_CLASS (klass),
2153       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
2154           get_session), NULL, NULL, NULL, GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2155
2156   /**
2157    * GstRtpBin::get-internal-session:
2158    * @rtpbin: the object which received the signal
2159    * @id: the session id
2160    *
2161    * Request the internal RTPSession object as #GObject in session @id.
2162    */
2163   gst_rtp_bin_signals[SIGNAL_GET_INTERNAL_SESSION] =
2164       g_signal_new ("get-internal-session", G_TYPE_FROM_CLASS (klass),
2165       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
2166           get_internal_session), NULL, NULL, NULL, RTP_TYPE_SESSION, 1,
2167       G_TYPE_UINT);
2168
2169   /**
2170    * GstRtpBin::get-internal-storage:
2171    * @rtpbin: the object which received the signal
2172    * @id: the session id
2173    *
2174    * Request the internal RTPStorage object as #GObject in session @id. This
2175    * is the internal storage used by the RTPStorage element, which is used to
2176    * keep a backlog of received RTP packets for the session @id.
2177    *
2178    * Since: 1.14
2179    */
2180   gst_rtp_bin_signals[SIGNAL_GET_INTERNAL_STORAGE] =
2181       g_signal_new ("get-internal-storage", G_TYPE_FROM_CLASS (klass),
2182       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
2183           get_internal_storage), NULL, NULL, NULL, G_TYPE_OBJECT, 1,
2184       G_TYPE_UINT);
2185
2186   /**
2187    * GstRtpBin::get-storage:
2188    * @rtpbin: the object which received the signal
2189    * @id: the session id
2190    *
2191    * Request the RTPStorage element as #GObject in session @id. This element
2192    * is used to keep a backlog of received RTP packets for the session @id.
2193    *
2194    * Since: 1.16
2195    */
2196   gst_rtp_bin_signals[SIGNAL_GET_STORAGE] =
2197       g_signal_new ("get-storage", G_TYPE_FROM_CLASS (klass),
2198       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
2199           get_storage), NULL, NULL, NULL, GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2200
2201   /**
2202    * GstRtpBin::clear-ssrc:
2203    * @rtpbin: the object which received the signal
2204    * @id: the session id
2205    * @ssrc: the ssrc
2206    *
2207    * Remove all pads from rtpssrcdemux element associated with the specified
2208    * ssrc. This delegate the action signal to the rtpssrcdemux element
2209    * associated with the specified session.
2210    *
2211    * Since: 1.20
2212    */
2213   gst_rtp_bin_signals[SIGNAL_CLEAR_SSRC] =
2214       g_signal_new ("clear-ssrc", G_TYPE_FROM_CLASS (klass),
2215       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
2216           clear_ssrc), NULL, NULL, NULL, G_TYPE_NONE, 2,
2217       G_TYPE_UINT, G_TYPE_UINT);
2218
2219   /**
2220    * GstRtpBin::on-new-ssrc:
2221    * @rtpbin: the object which received the signal
2222    * @session: the session
2223    * @ssrc: the SSRC
2224    *
2225    * Notify of a new SSRC that entered @session.
2226    */
2227   gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC] =
2228       g_signal_new ("on-new-ssrc", G_TYPE_FROM_CLASS (klass),
2229       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_new_ssrc),
2230       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2231   /**
2232    * GstRtpBin::on-ssrc-collision:
2233    * @rtpbin: the object which received the signal
2234    * @session: the session
2235    * @ssrc: the SSRC
2236    *
2237    * Notify when we have an SSRC collision
2238    */
2239   gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION] =
2240       g_signal_new ("on-ssrc-collision", G_TYPE_FROM_CLASS (klass),
2241       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_collision),
2242       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2243   /**
2244    * GstRtpBin::on-ssrc-validated:
2245    * @rtpbin: the object which received the signal
2246    * @session: the session
2247    * @ssrc: the SSRC
2248    *
2249    * Notify of a new SSRC that became validated.
2250    */
2251   gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED] =
2252       g_signal_new ("on-ssrc-validated", G_TYPE_FROM_CLASS (klass),
2253       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_validated),
2254       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2255   /**
2256    * GstRtpBin::on-ssrc-active:
2257    * @rtpbin: the object which received the signal
2258    * @session: the session
2259    * @ssrc: the SSRC
2260    *
2261    * Notify of a SSRC that is active, i.e., sending RTCP.
2262    */
2263   gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE] =
2264       g_signal_new ("on-ssrc-active", G_TYPE_FROM_CLASS (klass),
2265       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_active),
2266       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2267   /**
2268    * GstRtpBin::on-ssrc-sdes:
2269    * @rtpbin: the object which received the signal
2270    * @session: the session
2271    * @ssrc: the SSRC
2272    *
2273    * Notify of a SSRC that is active, i.e., sending RTCP.
2274    */
2275   gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES] =
2276       g_signal_new ("on-ssrc-sdes", G_TYPE_FROM_CLASS (klass),
2277       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_sdes),
2278       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2279
2280   /**
2281    * GstRtpBin::on-bye-ssrc:
2282    * @rtpbin: the object which received the signal
2283    * @session: the session
2284    * @ssrc: the SSRC
2285    *
2286    * Notify of an SSRC that became inactive because of a BYE packet.
2287    */
2288   gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC] =
2289       g_signal_new ("on-bye-ssrc", G_TYPE_FROM_CLASS (klass),
2290       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_ssrc),
2291       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2292   /**
2293    * GstRtpBin::on-bye-timeout:
2294    * @rtpbin: the object which received the signal
2295    * @session: the session
2296    * @ssrc: the SSRC
2297    *
2298    * Notify of an SSRC that has timed out because of BYE
2299    */
2300   gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT] =
2301       g_signal_new ("on-bye-timeout", G_TYPE_FROM_CLASS (klass),
2302       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_timeout),
2303       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2304   /**
2305    * GstRtpBin::on-timeout:
2306    * @rtpbin: the object which received the signal
2307    * @session: the session
2308    * @ssrc: the SSRC
2309    *
2310    * Notify of an SSRC that has timed out
2311    */
2312   gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT] =
2313       g_signal_new ("on-timeout", G_TYPE_FROM_CLASS (klass),
2314       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_timeout),
2315       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2316   /**
2317    * GstRtpBin::on-sender-timeout:
2318    * @rtpbin: the object which received the signal
2319    * @session: the session
2320    * @ssrc: the SSRC
2321    *
2322    * Notify of a sender SSRC that has timed out and became a receiver
2323    */
2324   gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT] =
2325       g_signal_new ("on-sender-timeout", G_TYPE_FROM_CLASS (klass),
2326       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_sender_timeout),
2327       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2328
2329   /**
2330    * GstRtpBin::on-npt-stop:
2331    * @rtpbin: the object which received the signal
2332    * @session: the session
2333    * @ssrc: the SSRC
2334    *
2335    * Notify that SSRC sender has sent data up to the configured NPT stop time.
2336    */
2337   gst_rtp_bin_signals[SIGNAL_ON_NPT_STOP] =
2338       g_signal_new ("on-npt-stop", G_TYPE_FROM_CLASS (klass),
2339       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_npt_stop),
2340       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2341
2342   /**
2343    * GstRtpBin::request-rtp-encoder:
2344    * @rtpbin: the object which received the signal
2345    * @session: the session
2346    *
2347    * Request an RTP encoder element for the given @session. The encoder
2348    * element will be added to the bin if not previously added.
2349    *
2350    * If no handler is connected, no encoder will be used.
2351    *
2352    * Since: 1.4
2353    */
2354   gst_rtp_bin_signals[SIGNAL_REQUEST_RTP_ENCODER] =
2355       g_signal_new ("request-rtp-encoder", G_TYPE_FROM_CLASS (klass),
2356       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2357           request_rtp_encoder), _gst_element_accumulator, NULL, NULL,
2358       GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2359
2360   /**
2361    * GstRtpBin::request-rtp-decoder:
2362    * @rtpbin: the object which received the signal
2363    * @session: the session
2364    *
2365    * Request an RTP decoder element for the given @session. The decoder
2366    * element will be added to the bin if not previously added.
2367    *
2368    * If no handler is connected, no encoder will be used.
2369    *
2370    * Since: 1.4
2371    */
2372   gst_rtp_bin_signals[SIGNAL_REQUEST_RTP_DECODER] =
2373       g_signal_new ("request-rtp-decoder", G_TYPE_FROM_CLASS (klass),
2374       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2375           request_rtp_decoder), _gst_element_accumulator, NULL,
2376       NULL, GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2377
2378   /**
2379    * GstRtpBin::request-rtcp-encoder:
2380    * @rtpbin: the object which received the signal
2381    * @session: the session
2382    *
2383    * Request an RTCP encoder element for the given @session. The encoder
2384    * element will be added to the bin if not previously added.
2385    *
2386    * If no handler is connected, no encoder will be used.
2387    *
2388    * Since: 1.4
2389    */
2390   gst_rtp_bin_signals[SIGNAL_REQUEST_RTCP_ENCODER] =
2391       g_signal_new ("request-rtcp-encoder", G_TYPE_FROM_CLASS (klass),
2392       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2393           request_rtcp_encoder), _gst_element_accumulator, NULL, NULL,
2394       GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2395
2396   /**
2397    * GstRtpBin::request-rtcp-decoder:
2398    * @rtpbin: the object which received the signal
2399    * @session: the session
2400    *
2401    * Request an RTCP decoder element for the given @session. The decoder
2402    * element will be added to the bin if not previously added.
2403    *
2404    * If no handler is connected, no encoder will be used.
2405    *
2406    * Since: 1.4
2407    */
2408   gst_rtp_bin_signals[SIGNAL_REQUEST_RTCP_DECODER] =
2409       g_signal_new ("request-rtcp-decoder", G_TYPE_FROM_CLASS (klass),
2410       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2411           request_rtcp_decoder), _gst_element_accumulator, NULL, NULL,
2412       GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2413
2414   /**
2415    * GstRtpBin::request-jitterbuffer:
2416    * @rtpbin: the object which received the signal
2417    * @session: the session
2418    *
2419    * Request a jitterbuffer element for the given @session.
2420    *
2421    * If no handler is connected, the default jitterbuffer will be used.
2422    *
2423    * Note: The provided element is expected to conform to the API exposed
2424    * by the standard #GstRtpJitterBuffer. Runtime checks will be made to
2425    * determine whether it exposes properties and signals before attempting
2426    * to set, call or connect to them, and some functionalities of #GstRtpBin
2427    * may not be available when that is not the case.
2428    *
2429    * This should be considered experimental API, as the standard jitterbuffer
2430    * API is susceptible to change, provided elements will have to update their
2431    * custom jitterbuffer's API to match the API of #GstRtpJitterBuffer if and
2432    * when it changes.
2433    *
2434    * Since: 1.18
2435    */
2436   gst_rtp_bin_signals[SIGNAL_REQUEST_JITTERBUFFER] =
2437       g_signal_new ("request-jitterbuffer", G_TYPE_FROM_CLASS (klass),
2438       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2439           request_jitterbuffer), _gst_element_accumulator, NULL,
2440       g_cclosure_marshal_generic, GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2441
2442   /**
2443    * GstRtpBin::new-jitterbuffer:
2444    * @rtpbin: the object which received the signal
2445    * @jitterbuffer: the new jitterbuffer
2446    * @session: the session
2447    * @ssrc: the SSRC
2448    *
2449    * Notify that a new @jitterbuffer was created for @session and @ssrc.
2450    * This signal can, for example, be used to configure @jitterbuffer.
2451    *
2452    * Since: 1.4
2453    */
2454   gst_rtp_bin_signals[SIGNAL_NEW_JITTERBUFFER] =
2455       g_signal_new ("new-jitterbuffer", G_TYPE_FROM_CLASS (klass),
2456       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2457           new_jitterbuffer), NULL, NULL, NULL,
2458       G_TYPE_NONE, 3, GST_TYPE_ELEMENT, G_TYPE_UINT, G_TYPE_UINT);
2459
2460   /**
2461    * GstRtpBin::new-storage:
2462    * @rtpbin: the object which received the signal
2463    * @storage: the new storage
2464    * @session: the session
2465    *
2466    * Notify that a new @storage was created for @session.
2467    * This signal can, for example, be used to configure @storage.
2468    *
2469    * Since: 1.14
2470    */
2471   gst_rtp_bin_signals[SIGNAL_NEW_STORAGE] =
2472       g_signal_new ("new-storage", G_TYPE_FROM_CLASS (klass),
2473       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2474           new_storage), NULL, NULL, NULL,
2475       G_TYPE_NONE, 2, GST_TYPE_ELEMENT, G_TYPE_UINT);
2476
2477   /**
2478    * GstRtpBin::request-aux-sender:
2479    * @rtpbin: the object which received the signal
2480    * @session: the session
2481    *
2482    * Request an AUX sender element for the given @session. The AUX
2483    * element will be added to the bin.
2484    *
2485    * If no handler is connected, no AUX element will be used.
2486    *
2487    * Since: 1.4
2488    */
2489   gst_rtp_bin_signals[SIGNAL_REQUEST_AUX_SENDER] =
2490       g_signal_new ("request-aux-sender", G_TYPE_FROM_CLASS (klass),
2491       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2492           request_aux_sender), _gst_element_accumulator, NULL, NULL,
2493       GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2494
2495   /**
2496    * GstRtpBin::request-aux-receiver:
2497    * @rtpbin: the object which received the signal
2498    * @session: the session
2499    *
2500    * Request an AUX receiver element for the given @session. The AUX
2501    * element will be added to the bin.
2502    *
2503    * If no handler is connected, no AUX element will be used.
2504    *
2505    * Since: 1.4
2506    */
2507   gst_rtp_bin_signals[SIGNAL_REQUEST_AUX_RECEIVER] =
2508       g_signal_new ("request-aux-receiver", G_TYPE_FROM_CLASS (klass),
2509       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2510           request_aux_receiver), _gst_element_accumulator, NULL, NULL,
2511       GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2512
2513   /**
2514    * GstRtpBin::request-fec-decoder:
2515    * @rtpbin: the object which received the signal
2516    * @session: the session index
2517    *
2518    * Request a FEC decoder element for the given @session. The element
2519    * will be added to the bin after the pt demuxer.  If there are multiple
2520    * ssrc's and pt's in @session, this signal may be called multiple times for
2521    * the same @session each corresponding to a newly discovered ssrc.
2522    *
2523    * If no handler is connected, no FEC decoder will be used.
2524    *
2525    * Warning: usage of this signal is not appropriate for the BUNDLE case,
2526    * connect to #GstRtpBin::request-fec-decoder-full instead.
2527    *
2528    * Since: 1.14
2529    */
2530   gst_rtp_bin_signals[SIGNAL_REQUEST_FEC_DECODER] =
2531       g_signal_new ("request-fec-decoder", G_TYPE_FROM_CLASS (klass),
2532       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2533           request_fec_decoder), _gst_element_accumulator, NULL, NULL,
2534       GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2535
2536   /**
2537    * GstRtpBin::request-fec-decoder-full:
2538    * @rtpbin: the object which received the signal
2539    * @session: the session index
2540    * @ssrc: the ssrc of the stream
2541    * @pt: the payload type
2542    *
2543    * Request a FEC decoder element for the given @session. The element
2544    * will be added to the bin after the pt demuxer.  If there are multiple
2545    * ssrc's and pt's in @session, this signal may be called multiple times for
2546    * the same @session each corresponding to a newly discovered ssrc and payload
2547    * type, those are provided as parameters.
2548    *
2549    * If no handler is connected, no FEC decoder will be used.
2550    *
2551    * Since: 1.20
2552    */
2553   gst_rtp_bin_signals[SIGNAL_REQUEST_FEC_DECODER_FULL] =
2554       g_signal_new ("request-fec-decoder-full", G_TYPE_FROM_CLASS (klass),
2555       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2556           request_fec_decoder), _gst_element_accumulator, NULL, NULL,
2557       GST_TYPE_ELEMENT, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
2558
2559   /**
2560    * GstRtpBin::request-fec-encoder:
2561    * @rtpbin: the object which received the signal
2562    * @session: the session index
2563    *
2564    * Request a FEC encoder element for the given @session. The element
2565    * will be added to the bin after the RTPSession.
2566    *
2567    * If no handler is connected, no FEC encoder will be used.
2568    *
2569    * Since: 1.14
2570    */
2571   gst_rtp_bin_signals[SIGNAL_REQUEST_FEC_ENCODER] =
2572       g_signal_new ("request-fec-encoder", G_TYPE_FROM_CLASS (klass),
2573       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2574           request_fec_encoder), _gst_element_accumulator, NULL, NULL,
2575       GST_TYPE_ELEMENT, 1, G_TYPE_UINT);
2576
2577   /**
2578    * GstRtpBin::on-new-sender-ssrc:
2579    * @rtpbin: the object which received the signal
2580    * @session: the session
2581    * @ssrc: the sender SSRC
2582    *
2583    * Notify of a new sender SSRC that entered @session.
2584    *
2585    * Since: 1.8
2586    */
2587   gst_rtp_bin_signals[SIGNAL_ON_NEW_SENDER_SSRC] =
2588       g_signal_new ("on-new-sender-ssrc", G_TYPE_FROM_CLASS (klass),
2589       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_new_sender_ssrc),
2590       NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2591   /**
2592    * GstRtpBin::on-sender-ssrc-active:
2593    * @rtpbin: the object which received the signal
2594    * @session: the session
2595    * @ssrc: the sender SSRC
2596    *
2597    * Notify of a sender SSRC that is active, i.e., sending RTCP.
2598    *
2599    * Since: 1.8
2600    */
2601   gst_rtp_bin_signals[SIGNAL_ON_SENDER_SSRC_ACTIVE] =
2602       g_signal_new ("on-sender-ssrc-active", G_TYPE_FROM_CLASS (klass),
2603       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
2604           on_sender_ssrc_active), NULL, NULL, NULL,
2605       G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
2606
2607   g_object_class_install_property (gobject_class, PROP_SDES,
2608       g_param_spec_boxed ("sdes", "SDES",
2609           "The SDES items of this session",
2610           GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
2611           | GST_PARAM_DOC_SHOW_DEFAULT));
2612
2613   g_object_class_install_property (gobject_class, PROP_DO_LOST,
2614       g_param_spec_boolean ("do-lost", "Do Lost",
2615           "Send an event downstream when a packet is lost", DEFAULT_DO_LOST,
2616           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2617
2618   g_object_class_install_property (gobject_class, PROP_AUTOREMOVE,
2619       g_param_spec_boolean ("autoremove", "Auto Remove",
2620           "Automatically remove timed out sources", DEFAULT_AUTOREMOVE,
2621           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2622
2623   g_object_class_install_property (gobject_class, PROP_IGNORE_PT,
2624       g_param_spec_boolean ("ignore-pt", "Ignore PT",
2625           "Do not demultiplex based on PT values", DEFAULT_IGNORE_PT,
2626           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2627
2628   g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
2629       g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
2630           "Use the pipeline running-time to set the NTP time in the RTCP SR messages "
2631           "(DEPRECATED: Use ntp-time-source property)",
2632           DEFAULT_USE_PIPELINE_CLOCK,
2633           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_DEPRECATED));
2634   /**
2635    * GstRtpBin:buffer-mode:
2636    *
2637    * Control the buffering and timestamping mode used by the jitterbuffer.
2638    */
2639   g_object_class_install_property (gobject_class, PROP_BUFFER_MODE,
2640       g_param_spec_enum ("buffer-mode", "Buffer Mode",
2641           "Control the buffering algorithm in use", RTP_TYPE_JITTER_BUFFER_MODE,
2642           DEFAULT_BUFFER_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2643   /**
2644    * GstRtpBin:ntp-sync:
2645    *
2646    * Set the NTP time from the sender reports as the running-time on the
2647    * buffers. When both the sender and receiver have sychronized
2648    * running-time, i.e. when the clock and base-time is shared
2649    * between the receivers and the and the senders, this option can be
2650    * used to synchronize receivers on multiple machines.
2651    */
2652   g_object_class_install_property (gobject_class, PROP_NTP_SYNC,
2653       g_param_spec_boolean ("ntp-sync", "Sync on NTP clock",
2654           "Synchronize received streams to the NTP clock", DEFAULT_NTP_SYNC,
2655           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2656
2657   /**
2658    * GstRtpBin:rtcp-sync:
2659    *
2660    * If not synchronizing (directly) to the NTP clock, determines how to sync
2661    * the various streams.
2662    */
2663   g_object_class_install_property (gobject_class, PROP_RTCP_SYNC,
2664       g_param_spec_enum ("rtcp-sync", "RTCP Sync",
2665           "Use of RTCP SR in synchronization", GST_RTP_BIN_RTCP_SYNC_TYPE,
2666           DEFAULT_RTCP_SYNC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2667
2668   /**
2669    * GstRtpBin:rtcp-sync-interval:
2670    *
2671    * Determines how often to sync streams using RTCP data.
2672    */
2673   g_object_class_install_property (gobject_class, PROP_RTCP_SYNC_INTERVAL,
2674       g_param_spec_uint ("rtcp-sync-interval", "RTCP Sync Interval",
2675           "RTCP SR interval synchronization (ms) (0 = always)",
2676           0, G_MAXUINT, DEFAULT_RTCP_SYNC_INTERVAL,
2677           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2678
2679   g_object_class_install_property (gobject_class, PROP_DO_SYNC_EVENT,
2680       g_param_spec_boolean ("do-sync-event", "Do Sync Event",
2681           "Send event downstream when a stream is synchronized to the sender",
2682           DEFAULT_DO_SYNC_EVENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2683
2684   /**
2685    * GstRtpBin:do-retransmission:
2686    *
2687    * Enables RTP retransmission on all streams. To control retransmission on
2688    * a per-SSRC basis, connect to the #GstRtpBin::new-jitterbuffer signal and
2689    * set the #GstRtpJitterBuffer:do-retransmission property on the
2690    * #GstRtpJitterBuffer object instead.
2691    */
2692   g_object_class_install_property (gobject_class, PROP_DO_RETRANSMISSION,
2693       g_param_spec_boolean ("do-retransmission", "Do retransmission",
2694           "Enable retransmission on all streams",
2695           DEFAULT_DO_RETRANSMISSION,
2696           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2697
2698   /**
2699    * GstRtpBin:rtp-profile:
2700    *
2701    * Sets the default RTP profile of newly created RTP sessions. The
2702    * profile can be changed afterwards on a per-session basis.
2703    */
2704   g_object_class_install_property (gobject_class, PROP_RTP_PROFILE,
2705       g_param_spec_enum ("rtp-profile", "RTP Profile",
2706           "Default RTP profile of newly created sessions",
2707           GST_TYPE_RTP_PROFILE, DEFAULT_RTP_PROFILE,
2708           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2709
2710   g_object_class_install_property (gobject_class, PROP_NTP_TIME_SOURCE,
2711       g_param_spec_enum ("ntp-time-source", "NTP Time Source",
2712           "NTP time source for RTCP packets",
2713           gst_rtp_ntp_time_source_get_type (), DEFAULT_NTP_TIME_SOURCE,
2714           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2715
2716   g_object_class_install_property (gobject_class, PROP_RTCP_SYNC_SEND_TIME,
2717       g_param_spec_boolean ("rtcp-sync-send-time", "RTCP Sync Send Time",
2718           "Use send time or capture time for RTCP sync "
2719           "(TRUE = send time, FALSE = capture time)",
2720           DEFAULT_RTCP_SYNC_SEND_TIME,
2721           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2722
2723   g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
2724       g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
2725           "Maximum amount of time in ms that the RTP time in RTCP SRs "
2726           "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
2727           DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
2728           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2729
2730   g_object_class_install_property (gobject_class, PROP_MAX_DROPOUT_TIME,
2731       g_param_spec_uint ("max-dropout-time", "Max dropout time",
2732           "The maximum time (milliseconds) of missing packets tolerated.",
2733           0, G_MAXUINT, DEFAULT_MAX_DROPOUT_TIME,
2734           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2735
2736   g_object_class_install_property (gobject_class, PROP_MAX_MISORDER_TIME,
2737       g_param_spec_uint ("max-misorder-time", "Max misorder time",
2738           "The maximum time (milliseconds) of misordered packets tolerated.",
2739           0, G_MAXUINT, DEFAULT_MAX_MISORDER_TIME,
2740           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2741
2742   g_object_class_install_property (gobject_class, PROP_RFC7273_SYNC,
2743       g_param_spec_boolean ("rfc7273-sync", "Sync on RFC7273 clock",
2744           "Synchronize received streams to the RFC7273 clock "
2745           "(requires clock and offset to be provided)", DEFAULT_RFC7273_SYNC,
2746           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2747
2748   g_object_class_install_property (gobject_class, PROP_MAX_STREAMS,
2749       g_param_spec_uint ("max-streams", "Max Streams",
2750           "The maximum number of streams to create for one session",
2751           0, G_MAXUINT, DEFAULT_MAX_STREAMS,
2752           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2753
2754   /**
2755    * GstRtpBin:max-ts-offset-adjustment:
2756    *
2757    * Syncing time stamps to NTP time adds a time offset. This parameter
2758    * specifies the maximum number of nanoseconds per frame that this time offset
2759    * may be adjusted with. This is used to avoid sudden large changes to time
2760    * stamps.
2761    *
2762    * Since: 1.14
2763    */
2764   g_object_class_install_property (gobject_class, PROP_MAX_TS_OFFSET_ADJUSTMENT,
2765       g_param_spec_uint64 ("max-ts-offset-adjustment",
2766           "Max Timestamp Offset Adjustment",
2767           "The maximum number of nanoseconds per frame that time stamp offsets "
2768           "may be adjusted (0 = no limit).", 0, G_MAXUINT64,
2769           DEFAULT_MAX_TS_OFFSET_ADJUSTMENT, G_PARAM_READWRITE |
2770           G_PARAM_STATIC_STRINGS));
2771
2772   /**
2773    * GstRtpBin:max-ts-offset:
2774    *
2775    * Used to set an upper limit of how large a time offset may be. This
2776    * is used to protect against unrealistic values as a result of either
2777    * client,server or clock issues.
2778    *
2779    * Since: 1.14
2780    */
2781   g_object_class_install_property (gobject_class, PROP_MAX_TS_OFFSET,
2782       g_param_spec_int64 ("max-ts-offset", "Max TS Offset",
2783           "The maximum absolute value of the time offset in (nanoseconds). "
2784           "Note, if the ntp-sync parameter is set the default value is "
2785           "changed to 0 (no limit)", 0, G_MAXINT64, DEFAULT_MAX_TS_OFFSET,
2786           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2787
2788   /**
2789    * GstRtpBin:min-ts-offset:
2790    *
2791    * Used to set an lower limit for when a time offset is deemed large enough
2792    * to be useful for sync corrections.
2793    *
2794    * When streaming for instance audio, even very small ts_offsets cause
2795    * audible glitches. This property is used for controlling how sensitive the
2796    * adjustments should be to small deviations in ts_offset, occurring for
2797    * instance due to jittery network conditions or system load.
2798    *
2799    * Since: 1.22
2800    */
2801   g_object_class_install_property (gobject_class, PROP_MIN_TS_OFFSET,
2802       g_param_spec_uint64 ("min-ts-offset", "Min TS Offset",
2803           "The minimum absolute value of the time offset in (nanoseconds). "
2804           "Used to set an lower limit for when a time offset is deemed large "
2805           "enough to be useful for sync corrections."
2806           "Note, if the ntp-sync parameter is set the default value is "
2807           "changed to 0 (no limit)", 0, G_MAXUINT64, DEFAULT_MIN_TS_OFFSET,
2808           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2809
2810   /**
2811    * GstRtpBin:ts-offset-smoothing-factor:
2812    *
2813    * Controls the weighting between previous and current timestamp offsets in
2814    * a running moving average (RMA):
2815    * ts_offset_average(n) =
2816    *   ((ts-offset-smoothing-factor - 1) * ts_offset_average(n - 1) + ts_offset(n)) /
2817    *   ts-offset-smoothing-factor
2818    *
2819    * This can stabilize the timestamp offset and prevent unnecessary skew
2820    * corrections due to jitter introduced by network or system load.
2821    *
2822    * Since: 1.22
2823    */
2824   g_object_class_install_property (gobject_class,
2825       PROP_TS_OFFSET_SMOOTHING_FACTOR,
2826       g_param_spec_uint ("ts-offset-smoothing-factor",
2827           "Timestamp Offset Smoothing Factor",
2828           "Sets a smoothing factor for the timestamp offset in number of "
2829           "values for a calculated running moving average. "
2830           "(0 = no smoothing factor)", 0, G_MAXUINT,
2831           DEFAULT_TS_OFFSET_SMOOTHING_FACTOR,
2832           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2833
2834   /**
2835    * GstRtpBin:fec-decoders:
2836    *
2837    * Used to provide a factory used to build the FEC decoder for a
2838    * given session, as a command line alternative to
2839    * #GstRtpBin::request-fec-decoder.
2840    *
2841    * Expects a GstStructure in the form session_id (gint) -> factory (string)
2842    *
2843    * Since: 1.20
2844    */
2845   g_object_class_install_property (gobject_class, PROP_FEC_DECODERS,
2846       g_param_spec_boxed ("fec-decoders", "Fec Decoders",
2847           "GstStructure mapping from session index to FEC decoder "
2848           "factory, eg "
2849           "fec-decoders='fec,0=\"rtpst2022-1-fecdec\\ size-time\\=1000000000\";'",
2850           GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2851
2852   /**
2853    * GstRtpBin:fec-encoders:
2854    *
2855    * Used to provide a factory used to build the FEC encoder for a
2856    * given session, as a command line alternative to
2857    * #GstRtpBin::request-fec-encoder.
2858    *
2859    * Expects a GstStructure in the form session_id (gint) -> factory (string)
2860    *
2861    * Since: 1.20
2862    */
2863   g_object_class_install_property (gobject_class, PROP_FEC_ENCODERS,
2864       g_param_spec_boxed ("fec-encoders", "Fec Encoders",
2865           "GstStructure mapping from session index to FEC encoder "
2866           "factory, eg "
2867           "fec-encoders='fec,0=\"rtpst2022-1-fecenc\\ rows\\=5\\ columns\\=5\";'",
2868           GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2869
2870   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
2871   gstelement_class->request_new_pad =
2872       GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
2873   gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_release_pad);
2874
2875   /* sink pads */
2876   gst_element_class_add_static_pad_template (gstelement_class,
2877       &rtpbin_recv_rtp_sink_template);
2878   gst_element_class_add_static_pad_template (gstelement_class,
2879       &rtpbin_recv_fec_sink_template);
2880   gst_element_class_add_static_pad_template (gstelement_class,
2881       &rtpbin_recv_rtcp_sink_template);
2882   gst_element_class_add_static_pad_template (gstelement_class,
2883       &rtpbin_send_rtp_sink_template);
2884
2885   /* src pads */
2886   gst_element_class_add_static_pad_template (gstelement_class,
2887       &rtpbin_recv_rtp_src_template);
2888   gst_element_class_add_static_pad_template (gstelement_class,
2889       &rtpbin_send_rtcp_src_template);
2890   gst_element_class_add_static_pad_template (gstelement_class,
2891       &rtpbin_send_rtp_src_template);
2892   gst_element_class_add_static_pad_template (gstelement_class,
2893       &rtpbin_send_fec_src_template);
2894
2895   gst_element_class_set_static_metadata (gstelement_class, "RTP Bin",
2896       "Filter/Network/RTP",
2897       "Real-Time Transport Protocol bin",
2898       "Wim Taymans <wim.taymans@gmail.com>");
2899
2900   gstbin_class->handle_message = GST_DEBUG_FUNCPTR (gst_rtp_bin_handle_message);
2901
2902   klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map);
2903   klass->reset_sync = GST_DEBUG_FUNCPTR (gst_rtp_bin_reset_sync);
2904   klass->get_session = GST_DEBUG_FUNCPTR (gst_rtp_bin_get_session);
2905   klass->get_internal_session =
2906       GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_session);
2907   klass->get_storage = GST_DEBUG_FUNCPTR (gst_rtp_bin_get_storage);
2908   klass->get_internal_storage =
2909       GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_storage);
2910   klass->clear_ssrc = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_ssrc);
2911   klass->request_rtp_encoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_encoder);
2912   klass->request_rtp_decoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_decoder);
2913   klass->request_rtcp_encoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_encoder);
2914   klass->request_rtcp_decoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_decoder);
2915   klass->request_jitterbuffer =
2916       GST_DEBUG_FUNCPTR (gst_rtp_bin_request_jitterbuffer);
2917
2918   GST_DEBUG_CATEGORY_INIT (gst_rtp_bin_debug, "rtpbin", 0, "RTP bin");
2919
2920   gst_type_mark_as_plugin_api (GST_RTP_BIN_RTCP_SYNC_TYPE, 0);
2921 }
2922
2923 static void
2924 gst_rtp_bin_init (GstRtpBin * rtpbin)
2925 {
2926   gchar *cname;
2927
2928   rtpbin->priv = gst_rtp_bin_get_instance_private (rtpbin);
2929   g_mutex_init (&rtpbin->priv->bin_lock);
2930   g_mutex_init (&rtpbin->priv->dyn_lock);
2931
2932   rtpbin->latency_ms = DEFAULT_LATENCY_MS;
2933   rtpbin->latency_ns = DEFAULT_LATENCY_MS * GST_MSECOND;
2934   rtpbin->drop_on_latency = DEFAULT_DROP_ON_LATENCY;
2935   rtpbin->do_lost = DEFAULT_DO_LOST;
2936   rtpbin->ignore_pt = DEFAULT_IGNORE_PT;
2937   rtpbin->ntp_sync = DEFAULT_NTP_SYNC;
2938   rtpbin->rtcp_sync = DEFAULT_RTCP_SYNC;
2939   rtpbin->rtcp_sync_interval = DEFAULT_RTCP_SYNC_INTERVAL;
2940   rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE;
2941   rtpbin->buffer_mode = DEFAULT_BUFFER_MODE;
2942   rtpbin->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
2943   rtpbin->send_sync_event = DEFAULT_DO_SYNC_EVENT;
2944   rtpbin->do_retransmission = DEFAULT_DO_RETRANSMISSION;
2945   rtpbin->rtp_profile = DEFAULT_RTP_PROFILE;
2946   rtpbin->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
2947   rtpbin->rtcp_sync_send_time = DEFAULT_RTCP_SYNC_SEND_TIME;
2948   rtpbin->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
2949   rtpbin->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME;
2950   rtpbin->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
2951   rtpbin->rfc7273_sync = DEFAULT_RFC7273_SYNC;
2952   rtpbin->max_streams = DEFAULT_MAX_STREAMS;
2953   rtpbin->max_ts_offset_adjustment = DEFAULT_MAX_TS_OFFSET_ADJUSTMENT;
2954   rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
2955   rtpbin->max_ts_offset_is_set = FALSE;
2956   rtpbin->min_ts_offset = DEFAULT_MIN_TS_OFFSET;
2957   rtpbin->min_ts_offset_is_set = FALSE;
2958   rtpbin->ts_offset_smoothing_factor = DEFAULT_TS_OFFSET_SMOOTHING_FACTOR;
2959
2960   /* some default SDES entries */
2961   cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
2962   rtpbin->sdes = gst_structure_new ("application/x-rtp-source-sdes",
2963       "cname", G_TYPE_STRING, cname, "tool", G_TYPE_STRING, "GStreamer", NULL);
2964   rtpbin->fec_decoders =
2965       gst_structure_new_empty ("application/x-rtp-fec-decoders");
2966   rtpbin->fec_encoders =
2967       gst_structure_new_empty ("application/x-rtp-fec-encoders");
2968   g_free (cname);
2969 }
2970
2971 static void
2972 gst_rtp_bin_dispose (GObject * object)
2973 {
2974   GstRtpBin *rtpbin;
2975
2976   rtpbin = GST_RTP_BIN (object);
2977
2978   GST_RTP_BIN_LOCK (rtpbin);
2979   GST_DEBUG_OBJECT (object, "freeing sessions");
2980   g_slist_foreach (rtpbin->sessions, (GFunc) free_session, rtpbin);
2981   g_slist_free (rtpbin->sessions);
2982   rtpbin->sessions = NULL;
2983   GST_RTP_BIN_UNLOCK (rtpbin);
2984
2985   G_OBJECT_CLASS (parent_class)->dispose (object);
2986 }
2987
2988 static void
2989 gst_rtp_bin_finalize (GObject * object)
2990 {
2991   GstRtpBin *rtpbin;
2992
2993   rtpbin = GST_RTP_BIN (object);
2994
2995   if (rtpbin->sdes)
2996     gst_structure_free (rtpbin->sdes);
2997
2998   if (rtpbin->fec_decoders)
2999     gst_structure_free (rtpbin->fec_decoders);
3000
3001   if (rtpbin->fec_encoders)
3002     gst_structure_free (rtpbin->fec_encoders);
3003
3004   g_mutex_clear (&rtpbin->priv->bin_lock);
3005   g_mutex_clear (&rtpbin->priv->dyn_lock);
3006
3007   G_OBJECT_CLASS (parent_class)->finalize (object);
3008 }
3009
3010
3011 static void
3012 gst_rtp_bin_set_sdes_struct (GstRtpBin * bin, const GstStructure * sdes)
3013 {
3014   GSList *item;
3015
3016   if (sdes == NULL)
3017     return;
3018
3019   GST_RTP_BIN_LOCK (bin);
3020
3021   GST_OBJECT_LOCK (bin);
3022   if (bin->sdes)
3023     gst_structure_free (bin->sdes);
3024   bin->sdes = gst_structure_copy (sdes);
3025   GST_OBJECT_UNLOCK (bin);
3026
3027   /* store in all sessions */
3028   for (item = bin->sessions; item; item = g_slist_next (item)) {
3029     GstRtpBinSession *session = item->data;
3030     g_object_set (session->session, "sdes", sdes, NULL);
3031   }
3032
3033   GST_RTP_BIN_UNLOCK (bin);
3034 }
3035
3036 static void
3037 gst_rtp_bin_set_fec_decoders_struct (GstRtpBin * bin,
3038     const GstStructure * decoders)
3039 {
3040   if (decoders == NULL)
3041     return;
3042
3043   GST_RTP_BIN_LOCK (bin);
3044
3045   GST_OBJECT_LOCK (bin);
3046   if (bin->fec_decoders)
3047     gst_structure_free (bin->fec_decoders);
3048   bin->fec_decoders = gst_structure_copy (decoders);
3049
3050   GST_OBJECT_UNLOCK (bin);
3051
3052   GST_RTP_BIN_UNLOCK (bin);
3053 }
3054
3055 static void
3056 gst_rtp_bin_set_fec_encoders_struct (GstRtpBin * bin,
3057     const GstStructure * encoders)
3058 {
3059   if (encoders == NULL)
3060     return;
3061
3062   GST_RTP_BIN_LOCK (bin);
3063
3064   GST_OBJECT_LOCK (bin);
3065   if (bin->fec_encoders)
3066     gst_structure_free (bin->fec_encoders);
3067   bin->fec_encoders = gst_structure_copy (encoders);
3068
3069   GST_OBJECT_UNLOCK (bin);
3070
3071   GST_RTP_BIN_UNLOCK (bin);
3072 }
3073
3074 static GstStructure *
3075 gst_rtp_bin_get_sdes_struct (GstRtpBin * bin)
3076 {
3077   GstStructure *result;
3078
3079   GST_OBJECT_LOCK (bin);
3080   result = gst_structure_copy (bin->sdes);
3081   GST_OBJECT_UNLOCK (bin);
3082
3083   return result;
3084 }
3085
3086 static GstStructure *
3087 gst_rtp_bin_get_fec_decoders_struct (GstRtpBin * bin)
3088 {
3089   GstStructure *result;
3090
3091   GST_OBJECT_LOCK (bin);
3092   result = gst_structure_copy (bin->fec_decoders);
3093   GST_OBJECT_UNLOCK (bin);
3094
3095   return result;
3096 }
3097
3098 static GstStructure *
3099 gst_rtp_bin_get_fec_encoders_struct (GstRtpBin * bin)
3100 {
3101   GstStructure *result;
3102
3103   GST_OBJECT_LOCK (bin);
3104   result = gst_structure_copy (bin->fec_encoders);
3105   GST_OBJECT_UNLOCK (bin);
3106
3107   return result;
3108 }
3109
3110 static void
3111 gst_rtp_bin_set_property (GObject * object, guint prop_id,
3112     const GValue * value, GParamSpec * pspec)
3113 {
3114   GstRtpBin *rtpbin;
3115
3116   rtpbin = GST_RTP_BIN (object);
3117
3118   switch (prop_id) {
3119     case PROP_LATENCY:
3120       GST_RTP_BIN_LOCK (rtpbin);
3121       rtpbin->latency_ms = g_value_get_uint (value);
3122       rtpbin->latency_ns = rtpbin->latency_ms * GST_MSECOND;
3123       GST_RTP_BIN_UNLOCK (rtpbin);
3124       /* propagate the property down to the jitterbuffer */
3125       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "latency", value);
3126       break;
3127     case PROP_DROP_ON_LATENCY:
3128       GST_RTP_BIN_LOCK (rtpbin);
3129       rtpbin->drop_on_latency = g_value_get_boolean (value);
3130       GST_RTP_BIN_UNLOCK (rtpbin);
3131       /* propagate the property down to the jitterbuffer */
3132       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
3133           "drop-on-latency", value);
3134       break;
3135     case PROP_SDES:
3136       gst_rtp_bin_set_sdes_struct (rtpbin, g_value_get_boxed (value));
3137       break;
3138     case PROP_DO_LOST:
3139       GST_RTP_BIN_LOCK (rtpbin);
3140       rtpbin->do_lost = g_value_get_boolean (value);
3141       GST_RTP_BIN_UNLOCK (rtpbin);
3142       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "do-lost", value);
3143       break;
3144     case PROP_NTP_SYNC:
3145       rtpbin->ntp_sync = g_value_get_boolean (value);
3146       /* The default value of max_ts_offset depends on ntp_sync. If user
3147        * hasn't set it then change default value */
3148       if (!rtpbin->max_ts_offset_is_set) {
3149         if (rtpbin->ntp_sync) {
3150           rtpbin->max_ts_offset = 0;
3151         } else {
3152           rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
3153         }
3154       }
3155       if (!rtpbin->min_ts_offset_is_set) {
3156         if (rtpbin->ntp_sync) {
3157           rtpbin->min_ts_offset = 0;
3158         } else {
3159           rtpbin->min_ts_offset = DEFAULT_MIN_TS_OFFSET;
3160         }
3161       }
3162       break;
3163     case PROP_RTCP_SYNC:
3164       g_atomic_int_set (&rtpbin->rtcp_sync, g_value_get_enum (value));
3165       break;
3166     case PROP_RTCP_SYNC_INTERVAL:
3167       rtpbin->rtcp_sync_interval = g_value_get_uint (value);
3168       break;
3169     case PROP_IGNORE_PT:
3170       rtpbin->ignore_pt = g_value_get_boolean (value);
3171       break;
3172     case PROP_AUTOREMOVE:
3173       rtpbin->priv->autoremove = g_value_get_boolean (value);
3174       break;
3175     case PROP_USE_PIPELINE_CLOCK:
3176     {
3177       GSList *sessions;
3178       GST_RTP_BIN_LOCK (rtpbin);
3179       rtpbin->use_pipeline_clock = g_value_get_boolean (value);
3180       for (sessions = rtpbin->sessions; sessions;
3181           sessions = g_slist_next (sessions)) {
3182         GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
3183
3184         g_object_set (G_OBJECT (session->session),
3185             "use-pipeline-clock", rtpbin->use_pipeline_clock, NULL);
3186       }
3187       GST_RTP_BIN_UNLOCK (rtpbin);
3188     }
3189       break;
3190     case PROP_DO_SYNC_EVENT:
3191       rtpbin->send_sync_event = g_value_get_boolean (value);
3192       break;
3193     case PROP_BUFFER_MODE:
3194       GST_RTP_BIN_LOCK (rtpbin);
3195       rtpbin->buffer_mode = g_value_get_enum (value);
3196       GST_RTP_BIN_UNLOCK (rtpbin);
3197       /* propagate the property down to the jitterbuffer */
3198       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "mode", value);
3199       break;
3200     case PROP_DO_RETRANSMISSION:
3201       GST_RTP_BIN_LOCK (rtpbin);
3202       rtpbin->do_retransmission = g_value_get_boolean (value);
3203       GST_RTP_BIN_UNLOCK (rtpbin);
3204       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
3205           "do-retransmission", value);
3206       break;
3207     case PROP_RTP_PROFILE:
3208       rtpbin->rtp_profile = g_value_get_enum (value);
3209       break;
3210     case PROP_NTP_TIME_SOURCE:{
3211       GSList *sessions;
3212       GST_RTP_BIN_LOCK (rtpbin);
3213       rtpbin->ntp_time_source = g_value_get_enum (value);
3214       for (sessions = rtpbin->sessions; sessions;
3215           sessions = g_slist_next (sessions)) {
3216         GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
3217
3218         g_object_set (G_OBJECT (session->session),
3219             "ntp-time-source", rtpbin->ntp_time_source, NULL);
3220       }
3221       GST_RTP_BIN_UNLOCK (rtpbin);
3222       break;
3223     }
3224     case PROP_RTCP_SYNC_SEND_TIME:{
3225       GSList *sessions;
3226       GST_RTP_BIN_LOCK (rtpbin);
3227       rtpbin->rtcp_sync_send_time = g_value_get_boolean (value);
3228       for (sessions = rtpbin->sessions; sessions;
3229           sessions = g_slist_next (sessions)) {
3230         GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
3231
3232         g_object_set (G_OBJECT (session->session),
3233             "rtcp-sync-send-time", rtpbin->rtcp_sync_send_time, NULL);
3234       }
3235       GST_RTP_BIN_UNLOCK (rtpbin);
3236       break;
3237     }
3238     case PROP_MAX_RTCP_RTP_TIME_DIFF:
3239       GST_RTP_BIN_LOCK (rtpbin);
3240       rtpbin->max_rtcp_rtp_time_diff = g_value_get_int (value);
3241       GST_RTP_BIN_UNLOCK (rtpbin);
3242       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
3243           "max-rtcp-rtp-time-diff", value);
3244       break;
3245     case PROP_MAX_DROPOUT_TIME:
3246       GST_RTP_BIN_LOCK (rtpbin);
3247       rtpbin->max_dropout_time = g_value_get_uint (value);
3248       GST_RTP_BIN_UNLOCK (rtpbin);
3249       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
3250           "max-dropout-time", value);
3251       gst_rtp_bin_propagate_property_to_session (rtpbin, "max-dropout-time",
3252           value);
3253       break;
3254     case PROP_MAX_MISORDER_TIME:
3255       GST_RTP_BIN_LOCK (rtpbin);
3256       rtpbin->max_misorder_time = g_value_get_uint (value);
3257       GST_RTP_BIN_UNLOCK (rtpbin);
3258       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
3259           "max-misorder-time", value);
3260       gst_rtp_bin_propagate_property_to_session (rtpbin, "max-misorder-time",
3261           value);
3262       break;
3263     case PROP_RFC7273_SYNC:
3264       rtpbin->rfc7273_sync = g_value_get_boolean (value);
3265       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
3266           "rfc7273-sync", value);
3267       break;
3268     case PROP_MAX_STREAMS:
3269       rtpbin->max_streams = g_value_get_uint (value);
3270       break;
3271     case PROP_MAX_TS_OFFSET_ADJUSTMENT:
3272       rtpbin->max_ts_offset_adjustment = g_value_get_uint64 (value);
3273       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
3274           "max-ts-offset-adjustment", value);
3275       break;
3276     case PROP_MAX_TS_OFFSET:
3277       rtpbin->max_ts_offset = g_value_get_int64 (value);
3278       rtpbin->max_ts_offset_is_set = TRUE;
3279       break;
3280     case PROP_MIN_TS_OFFSET:
3281       rtpbin->min_ts_offset = g_value_get_uint64 (value);
3282       rtpbin->min_ts_offset_is_set = TRUE;
3283       break;
3284     case PROP_TS_OFFSET_SMOOTHING_FACTOR:
3285       rtpbin->ts_offset_smoothing_factor = g_value_get_uint (value);
3286       break;
3287     case PROP_FEC_DECODERS:
3288       gst_rtp_bin_set_fec_decoders_struct (rtpbin, g_value_get_boxed (value));
3289       break;
3290     case PROP_FEC_ENCODERS:
3291       gst_rtp_bin_set_fec_encoders_struct (rtpbin, g_value_get_boxed (value));
3292       break;
3293     default:
3294       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3295       break;
3296   }
3297 }
3298
3299 static void
3300 gst_rtp_bin_get_property (GObject * object, guint prop_id,
3301     GValue * value, GParamSpec * pspec)
3302 {
3303   GstRtpBin *rtpbin;
3304
3305   rtpbin = GST_RTP_BIN (object);
3306
3307   switch (prop_id) {
3308     case PROP_LATENCY:
3309       GST_RTP_BIN_LOCK (rtpbin);
3310       g_value_set_uint (value, rtpbin->latency_ms);
3311       GST_RTP_BIN_UNLOCK (rtpbin);
3312       break;
3313     case PROP_DROP_ON_LATENCY:
3314       GST_RTP_BIN_LOCK (rtpbin);
3315       g_value_set_boolean (value, rtpbin->drop_on_latency);
3316       GST_RTP_BIN_UNLOCK (rtpbin);
3317       break;
3318     case PROP_SDES:
3319       g_value_take_boxed (value, gst_rtp_bin_get_sdes_struct (rtpbin));
3320       break;
3321     case PROP_DO_LOST:
3322       GST_RTP_BIN_LOCK (rtpbin);
3323       g_value_set_boolean (value, rtpbin->do_lost);
3324       GST_RTP_BIN_UNLOCK (rtpbin);
3325       break;
3326     case PROP_IGNORE_PT:
3327       g_value_set_boolean (value, rtpbin->ignore_pt);
3328       break;
3329     case PROP_NTP_SYNC:
3330       g_value_set_boolean (value, rtpbin->ntp_sync);
3331       break;
3332     case PROP_RTCP_SYNC:
3333       g_value_set_enum (value, g_atomic_int_get (&rtpbin->rtcp_sync));
3334       break;
3335     case PROP_RTCP_SYNC_INTERVAL:
3336       g_value_set_uint (value, rtpbin->rtcp_sync_interval);
3337       break;
3338     case PROP_AUTOREMOVE:
3339       g_value_set_boolean (value, rtpbin->priv->autoremove);
3340       break;
3341     case PROP_BUFFER_MODE:
3342       g_value_set_enum (value, rtpbin->buffer_mode);
3343       break;
3344     case PROP_USE_PIPELINE_CLOCK:
3345       g_value_set_boolean (value, rtpbin->use_pipeline_clock);
3346       break;
3347     case PROP_DO_SYNC_EVENT:
3348       g_value_set_boolean (value, rtpbin->send_sync_event);
3349       break;
3350     case PROP_DO_RETRANSMISSION:
3351       GST_RTP_BIN_LOCK (rtpbin);
3352       g_value_set_boolean (value, rtpbin->do_retransmission);
3353       GST_RTP_BIN_UNLOCK (rtpbin);
3354       break;
3355     case PROP_RTP_PROFILE:
3356       g_value_set_enum (value, rtpbin->rtp_profile);
3357       break;
3358     case PROP_NTP_TIME_SOURCE:
3359       g_value_set_enum (value, rtpbin->ntp_time_source);
3360       break;
3361     case PROP_RTCP_SYNC_SEND_TIME:
3362       g_value_set_boolean (value, rtpbin->rtcp_sync_send_time);
3363       break;
3364     case PROP_MAX_RTCP_RTP_TIME_DIFF:
3365       GST_RTP_BIN_LOCK (rtpbin);
3366       g_value_set_int (value, rtpbin->max_rtcp_rtp_time_diff);
3367       GST_RTP_BIN_UNLOCK (rtpbin);
3368       break;
3369     case PROP_MAX_DROPOUT_TIME:
3370       g_value_set_uint (value, rtpbin->max_dropout_time);
3371       break;
3372     case PROP_MAX_MISORDER_TIME:
3373       g_value_set_uint (value, rtpbin->max_misorder_time);
3374       break;
3375     case PROP_RFC7273_SYNC:
3376       g_value_set_boolean (value, rtpbin->rfc7273_sync);
3377       break;
3378     case PROP_MAX_STREAMS:
3379       g_value_set_uint (value, rtpbin->max_streams);
3380       break;
3381     case PROP_MAX_TS_OFFSET_ADJUSTMENT:
3382       g_value_set_uint64 (value, rtpbin->max_ts_offset_adjustment);
3383       break;
3384     case PROP_MAX_TS_OFFSET:
3385       g_value_set_int64 (value, rtpbin->max_ts_offset);
3386       break;
3387     case PROP_MIN_TS_OFFSET:
3388       g_value_set_uint64 (value, rtpbin->min_ts_offset);
3389       break;
3390     case PROP_TS_OFFSET_SMOOTHING_FACTOR:
3391       g_value_set_uint (value, rtpbin->ts_offset_smoothing_factor);
3392       break;
3393     case PROP_FEC_DECODERS:
3394       g_value_take_boxed (value, gst_rtp_bin_get_fec_decoders_struct (rtpbin));
3395       break;
3396     case PROP_FEC_ENCODERS:
3397       g_value_take_boxed (value, gst_rtp_bin_get_fec_encoders_struct (rtpbin));
3398       break;
3399     default:
3400       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3401       break;
3402   }
3403 }
3404
3405 static void
3406 gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
3407 {
3408   GstRtpBin *rtpbin;
3409
3410   rtpbin = GST_RTP_BIN (bin);
3411
3412   switch (GST_MESSAGE_TYPE (message)) {
3413     case GST_MESSAGE_ELEMENT:
3414     {
3415       const GstStructure *s = gst_message_get_structure (message);
3416
3417       /* we change the structure name and add the session ID to it */
3418       if (gst_structure_has_name (s, "application/x-rtp-source-sdes")) {
3419         GstRtpBinSession *sess;
3420
3421         /* find the session we set it as object data */
3422         sess = g_object_get_data (G_OBJECT (GST_MESSAGE_SRC (message)),
3423             "GstRTPBin.session");
3424
3425         if (G_LIKELY (sess)) {
3426           message = gst_message_make_writable (message);
3427           s = gst_message_get_structure (message);
3428           gst_structure_set ((GstStructure *) s, "session", G_TYPE_UINT,
3429               sess->id, NULL);
3430         }
3431       }
3432       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
3433       break;
3434     }
3435     case GST_MESSAGE_BUFFERING:
3436     {
3437       gint percent;
3438       gint min_percent = 100;
3439       GSList *sessions, *streams;
3440       GstRtpBinStream *stream;
3441       gboolean change = FALSE, active = FALSE;
3442       GstClockTime min_out_time;
3443       GstBufferingMode mode;
3444       gint avg_in, avg_out;
3445       gint64 buffering_left;
3446
3447       gst_message_parse_buffering (message, &percent);
3448       gst_message_parse_buffering_stats (message, &mode, &avg_in, &avg_out,
3449           &buffering_left);
3450
3451       stream =
3452           g_object_get_data (G_OBJECT (GST_MESSAGE_SRC (message)),
3453           "GstRTPBin.stream");
3454
3455       GST_DEBUG_OBJECT (bin, "got percent %d from stream %p", percent, stream);
3456
3457       /* get the stream */
3458       if (G_LIKELY (stream)) {
3459         GST_RTP_BIN_LOCK (rtpbin);
3460         /* fill in the percent */
3461         stream->percent = percent;
3462
3463         /* calculate the min value for all streams */
3464         for (sessions = rtpbin->sessions; sessions;
3465             sessions = g_slist_next (sessions)) {
3466           GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
3467
3468           GST_RTP_SESSION_LOCK (session);
3469           if (session->streams) {
3470             for (streams = session->streams; streams;
3471                 streams = g_slist_next (streams)) {
3472               GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
3473
3474               GST_DEBUG_OBJECT (bin, "stream %p percent %d", stream,
3475                   stream->percent);
3476
3477               /* find min percent */
3478               if (min_percent > stream->percent)
3479                 min_percent = stream->percent;
3480             }
3481           } else {
3482             GST_INFO_OBJECT (bin,
3483                 "session has no streams, setting min_percent to 0");
3484             min_percent = 0;
3485           }
3486           GST_RTP_SESSION_UNLOCK (session);
3487         }
3488         GST_DEBUG_OBJECT (bin, "min percent %d", min_percent);
3489
3490         if (rtpbin->buffering) {
3491           if (min_percent == 100) {
3492             rtpbin->buffering = FALSE;
3493             active = TRUE;
3494             change = TRUE;
3495           }
3496         } else {
3497           if (min_percent < 100) {
3498             /* pause the streams */
3499             rtpbin->buffering = TRUE;
3500             active = FALSE;
3501             change = TRUE;
3502           }
3503         }
3504         GST_RTP_BIN_UNLOCK (rtpbin);
3505
3506         gst_message_unref (message);
3507
3508         /* make a new buffering message with the min value */
3509         message =
3510             gst_message_new_buffering (GST_OBJECT_CAST (bin), min_percent);
3511         gst_message_set_buffering_stats (message, mode, avg_in, avg_out,
3512             buffering_left);
3513
3514         if (G_UNLIKELY (change)) {
3515           GstClock *clock;
3516           guint64 running_time = 0;
3517           guint64 offset = 0;
3518
3519           /* figure out the running time when we have a clock */
3520           if (G_LIKELY ((clock =
3521                       gst_element_get_clock (GST_ELEMENT_CAST (bin))))) {
3522             guint64 now, base_time;
3523
3524             now = gst_clock_get_time (clock);
3525             base_time = gst_element_get_base_time (GST_ELEMENT_CAST (bin));
3526             running_time = now - base_time;
3527             gst_object_unref (clock);
3528           }
3529           GST_DEBUG_OBJECT (bin,
3530               "running time now %" GST_TIME_FORMAT,
3531               GST_TIME_ARGS (running_time));
3532
3533           GST_RTP_BIN_LOCK (rtpbin);
3534
3535           /* when we reactivate, calculate the offsets so that all streams have
3536            * an output time that is at least as big as the running_time */
3537           offset = 0;
3538           if (active) {
3539             if (running_time > rtpbin->buffer_start) {
3540               offset = running_time - rtpbin->buffer_start;
3541               if (offset >= rtpbin->latency_ns)
3542                 offset -= rtpbin->latency_ns;
3543               else
3544                 offset = 0;
3545             }
3546           }
3547
3548           /* pause all streams */
3549           min_out_time = -1;
3550           for (sessions = rtpbin->sessions; sessions;
3551               sessions = g_slist_next (sessions)) {
3552             GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
3553
3554             GST_RTP_SESSION_LOCK (session);
3555             for (streams = session->streams; streams;
3556                 streams = g_slist_next (streams)) {
3557               GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
3558               GstElement *element = stream->buffer;
3559               guint64 last_out = -1;
3560
3561               if (g_signal_lookup ("set-active", G_OBJECT_TYPE (element)) != 0) {
3562                 g_signal_emit_by_name (element, "set-active", active, offset,
3563                     &last_out);
3564               }
3565
3566               if (!active) {
3567                 g_object_get (element, "percent", &stream->percent, NULL);
3568
3569                 if (last_out == -1)
3570                   last_out = 0;
3571                 if (min_out_time == -1 || last_out < min_out_time)
3572                   min_out_time = last_out;
3573               }
3574
3575               GST_DEBUG_OBJECT (bin,
3576                   "setting %p to %d, offset %" GST_TIME_FORMAT ", last %"
3577                   GST_TIME_FORMAT ", percent %d", element, active,
3578                   GST_TIME_ARGS (offset), GST_TIME_ARGS (last_out),
3579                   stream->percent);
3580             }
3581             GST_RTP_SESSION_UNLOCK (session);
3582           }
3583           GST_DEBUG_OBJECT (bin,
3584               "min out time %" GST_TIME_FORMAT, GST_TIME_ARGS (min_out_time));
3585
3586           /* the buffer_start is the min out time of all paused jitterbuffers */
3587           if (!active)
3588             rtpbin->buffer_start = min_out_time;
3589
3590           GST_RTP_BIN_UNLOCK (rtpbin);
3591         }
3592       }
3593       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
3594       break;
3595     }
3596     default:
3597     {
3598       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
3599       break;
3600     }
3601   }
3602 }
3603
3604 static GstStateChangeReturn
3605 gst_rtp_bin_change_state (GstElement * element, GstStateChange transition)
3606 {
3607   GstStateChangeReturn res;
3608   GstRtpBin *rtpbin;
3609   GstRtpBinPrivate *priv;
3610
3611   rtpbin = GST_RTP_BIN (element);
3612   priv = rtpbin->priv;
3613
3614   switch (transition) {
3615     case GST_STATE_CHANGE_NULL_TO_READY:
3616       break;
3617     case GST_STATE_CHANGE_READY_TO_PAUSED:
3618       priv->last_ntpnstime = 0;
3619       GST_LOG_OBJECT (rtpbin, "clearing shutdown flag");
3620       g_atomic_int_set (&priv->shutdown, 0);
3621       break;
3622     case GST_STATE_CHANGE_PAUSED_TO_READY:
3623       GST_LOG_OBJECT (rtpbin, "setting shutdown flag");
3624       g_atomic_int_set (&priv->shutdown, 1);
3625       /* wait for all callbacks to end by taking the lock. No new callbacks will
3626        * be able to happen as we set the shutdown flag. */
3627       GST_RTP_BIN_DYN_LOCK (rtpbin);
3628       GST_LOG_OBJECT (rtpbin, "dynamic lock taken, we can continue shutdown");
3629       GST_RTP_BIN_DYN_UNLOCK (rtpbin);
3630       break;
3631     default:
3632       break;
3633   }
3634
3635   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3636
3637   switch (transition) {
3638     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
3639       break;
3640     case GST_STATE_CHANGE_PAUSED_TO_READY:
3641       break;
3642     case GST_STATE_CHANGE_READY_TO_NULL:
3643       break;
3644     default:
3645       break;
3646   }
3647   return res;
3648 }
3649
3650 static GstElement *
3651 session_request_element_full (GstRtpBinSession * session, guint signal,
3652     guint ssrc, guint8 pt)
3653 {
3654   GstElement *element = NULL;
3655   GstRtpBin *bin = session->bin;
3656
3657   g_signal_emit (bin, gst_rtp_bin_signals[signal], 0, session->id, ssrc, pt,
3658       &element);
3659
3660   if (element) {
3661     if (!bin_manage_element (bin, element))
3662       goto manage_failed;
3663     session->elements = g_slist_prepend (session->elements, element);
3664   }
3665   return element;
3666
3667   /* ERRORS */
3668 manage_failed:
3669   {
3670     GST_WARNING_OBJECT (bin, "unable to manage element");
3671     gst_object_unref (element);
3672     return NULL;
3673   }
3674 }
3675
3676 static GstElement *
3677 session_request_element (GstRtpBinSession * session, guint signal)
3678 {
3679   GstElement *element = NULL;
3680   GstRtpBin *bin = session->bin;
3681
3682   g_signal_emit (bin, gst_rtp_bin_signals[signal], 0, session->id, &element);
3683
3684   if (element) {
3685     if (!bin_manage_element (bin, element))
3686       goto manage_failed;
3687     session->elements = g_slist_prepend (session->elements, element);
3688   }
3689   return element;
3690
3691   /* ERRORS */
3692 manage_failed:
3693   {
3694     GST_WARNING_OBJECT (bin, "unable to manage element");
3695     gst_object_unref (element);
3696     return NULL;
3697   }
3698 }
3699
3700 static gboolean
3701 copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
3702 {
3703   GstPad *gpad = GST_PAD_CAST (user_data);
3704
3705   GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
3706   gst_pad_store_sticky_event (gpad, *event);
3707
3708   return TRUE;
3709 }
3710
3711 static gboolean
3712 ensure_early_fec_decoder (GstRtpBin * rtpbin, GstRtpBinSession * session)
3713 {
3714   const gchar *factory;
3715   gchar *sess_id_str;
3716
3717   if (session->early_fec_decoder)
3718     goto done;
3719
3720   sess_id_str = g_strdup_printf ("%u", session->id);
3721   factory = gst_structure_get_string (rtpbin->fec_decoders, sess_id_str);
3722   g_free (sess_id_str);
3723
3724   /* First try the property */
3725   if (factory) {
3726     GError *err = NULL;
3727
3728     session->early_fec_decoder =
3729         gst_parse_bin_from_description_full (factory, TRUE, NULL,
3730         GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS | GST_PARSE_FLAG_FATAL_ERRORS,
3731         &err);
3732     if (!session->early_fec_decoder) {
3733       GST_ERROR_OBJECT (rtpbin, "Failed to build decoder from factory: %s",
3734           err->message);
3735     }
3736
3737     bin_manage_element (session->bin, session->early_fec_decoder);
3738     session->elements =
3739         g_slist_prepend (session->elements, session->early_fec_decoder);
3740     GST_INFO_OBJECT (rtpbin, "Built FEC decoder: %" GST_PTR_FORMAT
3741         " for session %u", session->early_fec_decoder, session->id);
3742   }
3743
3744   /* Do not fallback to the signal as the signal expects a fec decoder to
3745    * be placed at a different place in the pipeline */
3746
3747 done:
3748   return session->early_fec_decoder != NULL;
3749 }
3750
3751 static void
3752 expose_recv_src_pad (GstRtpBin * rtpbin, GstPad * pad, GstRtpBinStream * stream,
3753     guint8 pt)
3754 {
3755   GstElementClass *klass;
3756   GstPadTemplate *templ;
3757   gchar *padname;
3758   GstPad *gpad;
3759
3760   gst_object_ref (pad);
3761
3762   if (stream->session->storage) {
3763     /* First try the legacy signal, with no ssrc and pt as parameters.
3764      * This will likely cause issues for the BUNDLE case. */
3765     GstElement *fec_decoder =
3766         session_request_element (stream->session, SIGNAL_REQUEST_FEC_DECODER);
3767
3768     /* Now try the new signal, where the application can provide a FEC
3769      * decoder according to ssrc and pt. */
3770     if (!fec_decoder) {
3771       fec_decoder =
3772           session_request_element_full (stream->session,
3773           SIGNAL_REQUEST_FEC_DECODER_FULL, stream->ssrc, pt);
3774     }
3775
3776     if (fec_decoder) {
3777       GstPad *sinkpad, *srcpad;
3778       GstPadLinkReturn ret;
3779
3780       sinkpad = gst_element_get_static_pad (fec_decoder, "sink");
3781
3782       if (!sinkpad)
3783         goto fec_decoder_sink_failed;
3784
3785       ret = gst_pad_link (pad, sinkpad);
3786       gst_object_unref (sinkpad);
3787
3788       if (ret != GST_PAD_LINK_OK)
3789         goto fec_decoder_link_failed;
3790
3791       srcpad = gst_element_get_static_pad (fec_decoder, "src");
3792
3793       if (!srcpad)
3794         goto fec_decoder_src_failed;
3795
3796       gst_pad_sticky_events_foreach (pad, copy_sticky_events, srcpad);
3797       gst_object_unref (pad);
3798       pad = srcpad;
3799     }
3800   }
3801
3802   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
3803
3804   /* ghost the pad to the parent */
3805   klass = GST_ELEMENT_GET_CLASS (rtpbin);
3806   templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%u_%u_%u");
3807   padname = g_strdup_printf ("recv_rtp_src_%u_%u_%u",
3808       stream->session->id, stream->ssrc, pt);
3809   gpad = gst_ghost_pad_new_from_template (padname, pad, templ);
3810   g_free (padname);
3811   g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", gpad);
3812
3813   gst_pad_set_active (gpad, TRUE);
3814   GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
3815
3816   gst_pad_sticky_events_foreach (pad, copy_sticky_events, gpad);
3817   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad);
3818
3819 done:
3820   gst_object_unref (pad);
3821
3822   return;
3823
3824 shutdown:
3825   {
3826     GST_DEBUG ("ignoring, we are shutting down");
3827     goto done;
3828   }
3829 fec_decoder_sink_failed:
3830   {
3831     g_warning ("rtpbin: failed to get fec encoder sink pad for session %u",
3832         stream->session->id);
3833     goto done;
3834   }
3835 fec_decoder_src_failed:
3836   {
3837     g_warning ("rtpbin: failed to get fec encoder src pad for session %u",
3838         stream->session->id);
3839     goto done;
3840   }
3841 fec_decoder_link_failed:
3842   {
3843     g_warning ("rtpbin: failed to link fec decoder for session %u",
3844         stream->session->id);
3845     goto done;
3846   }
3847 }
3848
3849 /* a new pad (SSRC) was created in @session. This signal is emitted from the
3850  * payload demuxer. */
3851 static void
3852 new_payload_found (GstElement * element, guint pt, GstPad * pad,
3853     GstRtpBinStream * stream)
3854 {
3855   GstRtpBin *rtpbin;
3856
3857   rtpbin = stream->bin;
3858
3859   GST_DEBUG_OBJECT (rtpbin, "new payload pad %u", pt);
3860
3861   expose_recv_src_pad (rtpbin, pad, stream, pt);
3862 }
3863
3864 static void
3865 payload_pad_removed (GstElement * element, GstPad * pad,
3866     GstRtpBinStream * stream)
3867 {
3868   GstRtpBin *rtpbin;
3869   GstPad *gpad;
3870
3871   rtpbin = stream->bin;
3872
3873   GST_DEBUG ("payload pad removed");
3874
3875   GST_RTP_BIN_DYN_LOCK (rtpbin);
3876   if ((gpad = g_object_get_data (G_OBJECT (pad), "GstRTPBin.ghostpad"))) {
3877     g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", NULL);
3878
3879     gst_pad_set_active (gpad, FALSE);
3880     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), gpad);
3881   }
3882   GST_RTP_BIN_DYN_UNLOCK (rtpbin);
3883 }
3884
3885 static GstCaps *
3886 pt_map_requested (GstElement * element, guint pt, GstRtpBinSession * session)
3887 {
3888   GstRtpBin *rtpbin;
3889   GstCaps *caps;
3890
3891   rtpbin = session->bin;
3892
3893   GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %u in session %u", pt,
3894       session->id);
3895
3896   caps = get_pt_map (session, pt);
3897   if (!caps)
3898     goto no_caps;
3899
3900   return caps;
3901
3902   /* ERRORS */
3903 no_caps:
3904   {
3905     GST_DEBUG_OBJECT (rtpbin, "could not get caps");
3906     return NULL;
3907   }
3908 }
3909
3910 static GstCaps *
3911 ptdemux_pt_map_requested (GstElement * element, guint pt,
3912     GstRtpBinSession * session)
3913 {
3914   GstCaps *ret = pt_map_requested (element, pt, session);
3915
3916   if (ret && gst_caps_get_size (ret) == 1) {
3917     const GstStructure *s = gst_caps_get_structure (ret, 0);
3918     gboolean is_fec;
3919
3920     if (gst_structure_get_boolean (s, "is-fec", &is_fec) && is_fec) {
3921       GValue v = G_VALUE_INIT;
3922       GValue v2 = G_VALUE_INIT;
3923
3924       GST_INFO_OBJECT (session->bin, "Will ignore FEC pt %u in session %u", pt,
3925           session->id);
3926       g_value_init (&v, GST_TYPE_ARRAY);
3927       g_value_init (&v2, G_TYPE_INT);
3928       g_object_get_property (G_OBJECT (element), "ignored-payload-types", &v);
3929       g_value_set_int (&v2, pt);
3930       gst_value_array_append_value (&v, &v2);
3931       g_value_unset (&v2);
3932       g_object_set_property (G_OBJECT (element), "ignored-payload-types", &v);
3933       g_value_unset (&v);
3934     }
3935   }
3936
3937   return ret;
3938 }
3939
3940 static void
3941 payload_type_change (GstElement * element, guint pt, GstRtpBinSession * session)
3942 {
3943   GST_DEBUG_OBJECT (session->bin,
3944       "emitting signal for pt type changed to %u in session %u", pt,
3945       session->id);
3946
3947   g_signal_emit (session->bin, gst_rtp_bin_signals[SIGNAL_PAYLOAD_TYPE_CHANGE],
3948       0, session->id, pt);
3949 }
3950
3951 /* emitted when caps changed for the session */
3952 static void
3953 caps_changed (GstPad * pad, GParamSpec * pspec, GstRtpBinSession * session)
3954 {
3955   GstRtpBin *bin;
3956   GstCaps *caps;
3957   gint payload;
3958   const GstStructure *s;
3959
3960   bin = session->bin;
3961
3962   g_object_get (pad, "caps", &caps, NULL);
3963
3964   if (caps == NULL)
3965     return;
3966
3967   GST_DEBUG_OBJECT (bin, "got caps %" GST_PTR_FORMAT, caps);
3968
3969   s = gst_caps_get_structure (caps, 0);
3970
3971   /* get payload, finish when it's not there */
3972   if (!gst_structure_get_int (s, "payload", &payload)) {
3973     gst_caps_unref (caps);
3974     return;
3975   }
3976
3977   GST_RTP_SESSION_LOCK (session);
3978   GST_DEBUG_OBJECT (bin, "insert caps for payload %d", payload);
3979   g_hash_table_insert (session->ptmap, GINT_TO_POINTER (payload), caps);
3980   GST_RTP_SESSION_UNLOCK (session);
3981 }
3982
3983 /* a new pad (SSRC) was created in @session */
3984 static void
3985 new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
3986     GstRtpBinSession * session)
3987 {
3988   GstRtpBin *rtpbin;
3989   GstRtpBinStream *stream;
3990   GstPad *sinkpad, *srcpad;
3991   gchar *padname;
3992
3993   rtpbin = session->bin;
3994
3995   GST_DEBUG_OBJECT (rtpbin, "new SSRC pad %08x, %s:%s", ssrc,
3996       GST_DEBUG_PAD_NAME (pad));
3997
3998   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
3999
4000   GST_RTP_SESSION_LOCK (session);
4001
4002   /* create new stream */
4003   stream = create_stream (session, ssrc);
4004   if (!stream)
4005     goto no_stream;
4006
4007   /* get pad and link */
4008   GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTP");
4009   padname = g_strdup_printf ("src_%u", ssrc);
4010   srcpad = gst_element_get_static_pad (element, padname);
4011   g_free (padname);
4012
4013   if (session->early_fec_decoder) {
4014     GST_DEBUG_OBJECT (rtpbin, "linking fec decoder");
4015     sinkpad = gst_element_get_static_pad (session->early_fec_decoder, "sink");
4016     gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_NOTHING);
4017     gst_object_unref (sinkpad);
4018     gst_object_unref (srcpad);
4019     srcpad = gst_element_get_static_pad (session->early_fec_decoder, "src");
4020   }
4021
4022   sinkpad = gst_element_get_static_pad (stream->buffer, "sink");
4023   gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_NOTHING);
4024   gst_object_unref (sinkpad);
4025   gst_object_unref (srcpad);
4026
4027   sinkpad = gst_element_request_pad_simple (stream->buffer, "sink_rtcp");
4028   if (sinkpad) {
4029     GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTCP");
4030     padname = g_strdup_printf ("rtcp_src_%u", ssrc);
4031     srcpad = gst_element_get_static_pad (element, padname);
4032     g_free (padname);
4033     gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_NOTHING);
4034     gst_object_unref (sinkpad);
4035     gst_object_unref (srcpad);
4036   }
4037
4038   if (g_signal_lookup ("handle-sync", G_OBJECT_TYPE (stream->buffer)) != 0) {
4039     /* connect to the RTCP sync signal from the jitterbuffer */
4040     GST_DEBUG_OBJECT (rtpbin, "connecting sync signal");
4041     stream->buffer_handlesync_sig = g_signal_connect (stream->buffer,
4042         "handle-sync", (GCallback) gst_rtp_bin_handle_sync, stream);
4043   }
4044
4045   if (stream->demux) {
4046     /* connect to the new-pad signal of the payload demuxer, this will expose the
4047      * new pad by ghosting it. */
4048     stream->demux_newpad_sig = g_signal_connect (stream->demux,
4049         "new-payload-type", (GCallback) new_payload_found, stream);
4050     stream->demux_padremoved_sig = g_signal_connect (stream->demux,
4051         "pad-removed", (GCallback) payload_pad_removed, stream);
4052
4053     /* connect to the request-pt-map signal. This signal will be emitted by the
4054      * demuxer so that it can apply a proper caps on the buffers for the
4055      * depayloaders. */
4056     stream->demux_ptreq_sig = g_signal_connect (stream->demux,
4057         "request-pt-map", (GCallback) ptdemux_pt_map_requested, session);
4058     /* connect to the  signal so it can be forwarded. */
4059     stream->demux_ptchange_sig = g_signal_connect (stream->demux,
4060         "payload-type-change", (GCallback) payload_type_change, session);
4061
4062     GST_RTP_SESSION_UNLOCK (session);
4063     GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
4064   } else {
4065     /* add rtpjitterbuffer src pad to pads */
4066     GstPad *pad;
4067
4068     pad = gst_element_get_static_pad (stream->buffer, "src");
4069
4070     GST_RTP_SESSION_UNLOCK (session);
4071     GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
4072
4073     expose_recv_src_pad (rtpbin, pad, stream, 255);
4074
4075     gst_object_unref (pad);
4076   }
4077
4078   return;
4079
4080   /* ERRORS */
4081 shutdown:
4082   {
4083     GST_DEBUG_OBJECT (rtpbin, "we are shutting down");
4084     return;
4085   }
4086 no_stream:
4087   {
4088     GST_RTP_SESSION_UNLOCK (session);
4089     GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
4090     GST_DEBUG_OBJECT (rtpbin, "could not create stream");
4091     return;
4092   }
4093 }
4094
4095 static GstPad *
4096 complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
4097 {
4098   guint sessid = session->id;
4099   GstPad *recv_rtp_sink;
4100   GstElement *decoder;
4101
4102   g_assert (!session->recv_rtp_sink);
4103
4104   /* get recv_rtp pad and store */
4105   session->recv_rtp_sink =
4106       gst_element_request_pad_simple (session->session, "recv_rtp_sink");
4107   if (session->recv_rtp_sink == NULL)
4108     goto pad_failed;
4109
4110   g_signal_connect (session->recv_rtp_sink, "notify::caps",
4111       (GCallback) caps_changed, session);
4112
4113   GST_DEBUG_OBJECT (rtpbin, "requesting RTP decoder");
4114   decoder = session_request_element (session, SIGNAL_REQUEST_RTP_DECODER);
4115   if (decoder) {
4116     GstPad *decsrc, *decsink;
4117     GstPadLinkReturn ret;
4118
4119     GST_DEBUG_OBJECT (rtpbin, "linking RTP decoder");
4120     decsink = gst_element_get_static_pad (decoder, "rtp_sink");
4121     if (decsink == NULL)
4122       goto dec_sink_failed;
4123
4124     recv_rtp_sink = decsink;
4125
4126     decsrc = gst_element_get_static_pad (decoder, "rtp_src");
4127     if (decsrc == NULL)
4128       goto dec_src_failed;
4129
4130     ret = gst_pad_link (decsrc, session->recv_rtp_sink);
4131
4132     gst_object_unref (decsrc);
4133
4134     if (ret != GST_PAD_LINK_OK)
4135       goto dec_link_failed;
4136
4137   } else {
4138     GST_DEBUG_OBJECT (rtpbin, "no RTP decoder given");
4139     recv_rtp_sink = gst_object_ref (session->recv_rtp_sink);
4140   }
4141
4142   return recv_rtp_sink;
4143
4144   /* ERRORS */
4145 pad_failed:
4146   {
4147     g_warning ("rtpbin: failed to get session recv_rtp_sink pad");
4148     return NULL;
4149   }
4150 dec_sink_failed:
4151   {
4152     g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
4153     return NULL;
4154   }
4155 dec_src_failed:
4156   {
4157     g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
4158     gst_object_unref (recv_rtp_sink);
4159     return NULL;
4160   }
4161 dec_link_failed:
4162   {
4163     g_warning ("rtpbin: failed to link rtp decoder for session %u", sessid);
4164     gst_object_unref (recv_rtp_sink);
4165     return NULL;
4166   }
4167 }
4168
4169 static void
4170 complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session,
4171     guint sessid)
4172 {
4173   GstElement *aux;
4174   GstPad *recv_rtp_src;
4175
4176   g_assert (!session->recv_rtp_src);
4177
4178   session->recv_rtp_src =
4179       gst_element_get_static_pad (session->session, "recv_rtp_src");
4180   if (session->recv_rtp_src == NULL)
4181     goto pad_failed;
4182
4183   /* find out if we need AUX elements */
4184   aux = session_request_element (session, SIGNAL_REQUEST_AUX_RECEIVER);
4185   if (aux) {
4186     gchar *pname;
4187     GstPad *auxsink;
4188     GstPadLinkReturn ret;
4189
4190     GST_DEBUG_OBJECT (rtpbin, "linking AUX receiver");
4191
4192     pname = g_strdup_printf ("sink_%u", sessid);
4193     auxsink = gst_element_get_static_pad (aux, pname);
4194     g_free (pname);
4195     if (auxsink == NULL)
4196       goto aux_sink_failed;
4197
4198     ret = gst_pad_link (session->recv_rtp_src, auxsink);
4199     gst_object_unref (auxsink);
4200     if (ret != GST_PAD_LINK_OK)
4201       goto aux_link_failed;
4202
4203     /* this can be NULL when this AUX element is not to be linked any further */
4204     pname = g_strdup_printf ("src_%u", sessid);
4205     recv_rtp_src = gst_element_get_static_pad (aux, pname);
4206     g_free (pname);
4207   } else {
4208     recv_rtp_src = gst_object_ref (session->recv_rtp_src);
4209   }
4210
4211   /* Add a storage element if needed */
4212   if (recv_rtp_src && session->storage) {
4213     GstPadLinkReturn ret;
4214     GstPad *sinkpad = gst_element_get_static_pad (session->storage, "sink");
4215
4216     ret = gst_pad_link (recv_rtp_src, sinkpad);
4217
4218     gst_object_unref (sinkpad);
4219     gst_object_unref (recv_rtp_src);
4220
4221     if (ret != GST_PAD_LINK_OK)
4222       goto storage_link_failed;
4223
4224     recv_rtp_src = gst_element_get_static_pad (session->storage, "src");
4225   }
4226
4227   if (recv_rtp_src) {
4228     GstPad *sinkdpad;
4229
4230     GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTP sink pad");
4231     sinkdpad = gst_element_get_static_pad (session->demux, "sink");
4232     GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
4233     gst_pad_link_full (recv_rtp_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
4234     gst_object_unref (sinkdpad);
4235     gst_object_unref (recv_rtp_src);
4236
4237     /* connect to the new-ssrc-pad signal of the SSRC demuxer */
4238     session->demux_newpad_sig = g_signal_connect (session->demux,
4239         "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session);
4240     session->demux_padremoved_sig = g_signal_connect (session->demux,
4241         "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session);
4242   }
4243
4244   return;
4245
4246 pad_failed:
4247   {
4248     g_warning ("rtpbin: failed to get session recv_rtp_src pad");
4249     return;
4250   }
4251 aux_sink_failed:
4252   {
4253     g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
4254     return;
4255   }
4256 aux_link_failed:
4257   {
4258     g_warning ("rtpbin: failed to link AUX pad to session %u", sessid);
4259     return;
4260   }
4261 storage_link_failed:
4262   {
4263     g_warning ("rtpbin: failed to link storage");
4264     return;
4265   }
4266 }
4267
4268 /* Create a pad for receiving RTP for the session in @name. Must be called with
4269  * RTP_BIN_LOCK.
4270  */
4271 static GstPad *
4272 create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
4273 {
4274   guint sessid;
4275   GstRtpBinSession *session;
4276   GstPad *recv_rtp_sink;
4277
4278   /* first get the session number */
4279   if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
4280     goto no_name;
4281
4282   GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
4283
4284   /* get or create session */
4285   session = find_session_by_id (rtpbin, sessid);
4286   if (!session) {
4287     GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
4288     /* create session now */
4289     session = create_session (rtpbin, sessid);
4290     if (session == NULL)
4291       goto create_error;
4292   }
4293
4294   /* check if pad was requested */
4295   if (session->recv_rtp_sink_ghost != NULL)
4296     return session->recv_rtp_sink_ghost;
4297
4298   /* setup the session sink pad */
4299   recv_rtp_sink = complete_session_sink (rtpbin, session);
4300   if (!recv_rtp_sink)
4301     goto session_sink_failed;
4302
4303   GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
4304   session->recv_rtp_sink_ghost =
4305       gst_ghost_pad_new_from_template (name, recv_rtp_sink, templ);
4306   gst_object_unref (recv_rtp_sink);
4307   gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
4308   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
4309
4310   complete_session_receiver (rtpbin, session, sessid);
4311
4312   return session->recv_rtp_sink_ghost;
4313
4314   /* ERRORS */
4315 no_name:
4316   {
4317     g_warning ("rtpbin: cannot find session id for pad: %s",
4318         GST_STR_NULL (name));
4319     return NULL;
4320   }
4321 create_error:
4322   {
4323     /* create_session already warned */
4324     return NULL;
4325   }
4326 session_sink_failed:
4327   {
4328     /* warning already done */
4329     return NULL;
4330   }
4331 }
4332
4333 static void
4334 remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
4335 {
4336   if (session->demux_newpad_sig) {
4337     g_signal_handler_disconnect (session->demux, session->demux_newpad_sig);
4338     session->demux_newpad_sig = 0;
4339   }
4340   if (session->demux_padremoved_sig) {
4341     g_signal_handler_disconnect (session->demux, session->demux_padremoved_sig);
4342     session->demux_padremoved_sig = 0;
4343   }
4344   if (session->recv_rtp_src) {
4345     gst_object_unref (session->recv_rtp_src);
4346     session->recv_rtp_src = NULL;
4347   }
4348   if (session->recv_rtp_sink) {
4349     gst_element_release_request_pad (session->session, session->recv_rtp_sink);
4350     gst_object_unref (session->recv_rtp_sink);
4351     session->recv_rtp_sink = NULL;
4352   }
4353   if (session->recv_rtp_sink_ghost) {
4354     gst_pad_set_active (session->recv_rtp_sink_ghost, FALSE);
4355     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
4356         session->recv_rtp_sink_ghost);
4357     session->recv_rtp_sink_ghost = NULL;
4358   }
4359 }
4360
4361 static GstPad *
4362 complete_session_fec (GstRtpBin * rtpbin, GstRtpBinSession * session,
4363     guint fec_idx)
4364 {
4365   gchar *padname;
4366   GstPad *ret;
4367
4368   if (!ensure_early_fec_decoder (rtpbin, session))
4369     goto no_decoder;
4370
4371   GST_DEBUG_OBJECT (rtpbin, "getting FEC sink pad");
4372   padname = g_strdup_printf ("fec_%u", fec_idx);
4373   ret = gst_element_request_pad_simple (session->early_fec_decoder, padname);
4374   g_free (padname);
4375
4376   if (ret == NULL)
4377     goto pad_failed;
4378
4379   session->recv_fec_sinks = g_slist_prepend (session->recv_fec_sinks, ret);
4380
4381   return ret;
4382
4383 pad_failed:
4384   {
4385     g_warning ("rtpbin: failed to get decoder fec pad");
4386     return NULL;
4387   }
4388 no_decoder:
4389   {
4390     g_warning ("rtpbin: failed to build FEC decoder for session %u",
4391         session->id);
4392     return NULL;
4393   }
4394 }
4395
4396 static GstPad *
4397 complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session,
4398     guint sessid)
4399 {
4400   GstElement *decoder;
4401   GstPad *sinkdpad;
4402   GstPad *decsink = NULL;
4403
4404   /* get recv_rtp pad and store */
4405   GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad");
4406   session->recv_rtcp_sink =
4407       gst_element_request_pad_simple (session->session, "recv_rtcp_sink");
4408   if (session->recv_rtcp_sink == NULL)
4409     goto pad_failed;
4410
4411   GST_DEBUG_OBJECT (rtpbin, "getting RTCP decoder");
4412   decoder = session_request_element (session, SIGNAL_REQUEST_RTCP_DECODER);
4413   if (decoder) {
4414     GstPad *decsrc;
4415     GstPadLinkReturn ret;
4416
4417     GST_DEBUG_OBJECT (rtpbin, "linking RTCP decoder");
4418     decsink = gst_element_get_static_pad (decoder, "rtcp_sink");
4419     decsrc = gst_element_get_static_pad (decoder, "rtcp_src");
4420
4421     if (decsink == NULL)
4422       goto dec_sink_failed;
4423
4424     if (decsrc == NULL)
4425       goto dec_src_failed;
4426
4427     ret = gst_pad_link (decsrc, session->recv_rtcp_sink);
4428
4429     gst_object_unref (decsrc);
4430
4431     if (ret != GST_PAD_LINK_OK)
4432       goto dec_link_failed;
4433   } else {
4434     GST_DEBUG_OBJECT (rtpbin, "no RTCP decoder given");
4435     decsink = gst_object_ref (session->recv_rtcp_sink);
4436   }
4437
4438   /* get srcpad, link to SSRCDemux */
4439   GST_DEBUG_OBJECT (rtpbin, "getting sync src pad");
4440   session->sync_src = gst_element_get_static_pad (session->session, "sync_src");
4441   if (session->sync_src == NULL)
4442     goto src_pad_failed;
4443
4444   GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTCP sink pad");
4445   sinkdpad = gst_element_get_static_pad (session->demux, "rtcp_sink");
4446   gst_pad_link_full (session->sync_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
4447   gst_object_unref (sinkdpad);
4448
4449   return decsink;
4450
4451 pad_failed:
4452   {
4453     g_warning ("rtpbin: failed to get session rtcp_sink pad");
4454     return NULL;
4455   }
4456 dec_sink_failed:
4457   {
4458     g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
4459     return NULL;
4460   }
4461 dec_src_failed:
4462   {
4463     g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
4464     goto cleanup;
4465   }
4466 dec_link_failed:
4467   {
4468     g_warning ("rtpbin: failed to link rtcp decoder for session %u", sessid);
4469     goto cleanup;
4470   }
4471 src_pad_failed:
4472   {
4473     g_warning ("rtpbin: failed to get session sync_src pad");
4474   }
4475
4476 cleanup:
4477   gst_object_unref (decsink);
4478   return NULL;
4479 }
4480
4481 /* Create a pad for receiving RTCP for the session in @name. Must be called with
4482  * RTP_BIN_LOCK.
4483  */
4484 static GstPad *
4485 create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
4486     const gchar * name)
4487 {
4488   guint sessid;
4489   GstRtpBinSession *session;
4490   GstPad *decsink = NULL;
4491
4492   /* first get the session number */
4493   if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1)
4494     goto no_name;
4495
4496   GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
4497
4498   /* get or create the session */
4499   session = find_session_by_id (rtpbin, sessid);
4500   if (!session) {
4501     GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
4502     /* create session now */
4503     session = create_session (rtpbin, sessid);
4504     if (session == NULL)
4505       goto create_error;
4506   }
4507
4508   /* check if pad was requested */
4509   if (session->recv_rtcp_sink_ghost != NULL)
4510     return session->recv_rtcp_sink_ghost;
4511
4512   decsink = complete_session_rtcp (rtpbin, session, sessid);
4513   if (!decsink)
4514     goto create_error;
4515
4516   session->recv_rtcp_sink_ghost =
4517       gst_ghost_pad_new_from_template (name, decsink, templ);
4518   gst_object_unref (decsink);
4519   gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE);
4520   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin),
4521       session->recv_rtcp_sink_ghost);
4522
4523   return session->recv_rtcp_sink_ghost;
4524
4525   /* ERRORS */
4526 no_name:
4527   {
4528     g_warning ("rtpbin: cannot find session id for pad: %s",
4529         GST_STR_NULL (name));
4530     return NULL;
4531   }
4532 create_error:
4533   {
4534     /* create_session already warned */
4535     return NULL;
4536   }
4537 }
4538
4539 static GstPad *
4540 create_recv_fec (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
4541 {
4542   guint sessid, fec_idx;
4543   GstRtpBinSession *session;
4544   GstPad *decsink = NULL;
4545   GstPad *ghost;
4546
4547   /* first get the session number */
4548   if (name == NULL
4549       || sscanf (name, "recv_fec_sink_%u_%u", &sessid, &fec_idx) != 2)
4550     goto no_name;
4551
4552   if (fec_idx > 1)
4553     goto invalid_idx;
4554
4555   GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
4556
4557   /* get or create the session */
4558   session = find_session_by_id (rtpbin, sessid);
4559   if (!session) {
4560     GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
4561     /* create session now */
4562     session = create_session (rtpbin, sessid);
4563     if (session == NULL)
4564       goto create_error;
4565   }
4566
4567   decsink = complete_session_fec (rtpbin, session, fec_idx);
4568   if (!decsink)
4569     goto create_error;
4570
4571   ghost = gst_ghost_pad_new_from_template (name, decsink, templ);
4572   session->recv_fec_sink_ghosts =
4573       g_slist_prepend (session->recv_fec_sink_ghosts, ghost);
4574   gst_object_unref (decsink);
4575   gst_pad_set_active (ghost, TRUE);
4576   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), ghost);
4577
4578   return ghost;
4579
4580   /* ERRORS */
4581 no_name:
4582   {
4583     g_warning ("rtpbin: cannot find session id for pad: %s",
4584         GST_STR_NULL (name));
4585     return NULL;
4586   }
4587 invalid_idx:
4588   {
4589     g_warning ("rtpbin: invalid FEC index: %s", GST_STR_NULL (name));
4590     return NULL;
4591   }
4592 create_error:
4593   {
4594     /* create_session already warned */
4595     return NULL;
4596   }
4597 }
4598
4599 static void
4600 remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session)
4601 {
4602   if (session->recv_rtcp_sink_ghost) {
4603     gst_pad_set_active (session->recv_rtcp_sink_ghost, FALSE);
4604     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
4605         session->recv_rtcp_sink_ghost);
4606     session->recv_rtcp_sink_ghost = NULL;
4607   }
4608   if (session->sync_src) {
4609     /* releasing the request pad should also unref the sync pad */
4610     gst_object_unref (session->sync_src);
4611     session->sync_src = NULL;
4612   }
4613   if (session->recv_rtcp_sink) {
4614     gst_element_release_request_pad (session->session, session->recv_rtcp_sink);
4615     gst_object_unref (session->recv_rtcp_sink);
4616     session->recv_rtcp_sink = NULL;
4617   }
4618 }
4619
4620 static void
4621 remove_recv_fec_for_pad (GstRtpBin * rtpbin, GstRtpBinSession * session,
4622     GstPad * ghost)
4623 {
4624   GSList *item;
4625   GstPad *target;
4626
4627   target = gst_ghost_pad_get_target (GST_GHOST_PAD (ghost));
4628
4629   if (target) {
4630     item = g_slist_find (session->recv_fec_sinks, target);
4631     if (item) {
4632       gst_element_release_request_pad (session->early_fec_decoder, item->data);
4633       session->recv_fec_sinks =
4634           g_slist_delete_link (session->recv_fec_sinks, item);
4635     }
4636     gst_object_unref (target);
4637   }
4638
4639   item = g_slist_find (session->recv_fec_sink_ghosts, ghost);
4640   if (item)
4641     session->recv_fec_sink_ghosts =
4642         g_slist_delete_link (session->recv_fec_sink_ghosts, item);
4643
4644   gst_pad_set_active (ghost, FALSE);
4645   gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), ghost);
4646 }
4647
4648 static void
4649 remove_recv_fec (GstRtpBin * rtpbin, GstRtpBinSession * session)
4650 {
4651   GSList *copy;
4652   GSList *tmp;
4653
4654   copy = g_slist_copy (session->recv_fec_sink_ghosts);
4655
4656   for (tmp = copy; tmp; tmp = tmp->next) {
4657     remove_recv_fec_for_pad (rtpbin, session, (GstPad *) tmp->data);
4658   }
4659
4660   g_slist_free (copy);
4661 }
4662
4663 static gboolean
4664 complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
4665 {
4666   gchar *gname;
4667   guint sessid = session->id;
4668   GstPad *send_rtp_src;
4669   GstElement *encoder;
4670   GstElementClass *klass;
4671   GstPadTemplate *templ;
4672   gboolean ret = FALSE;
4673
4674   /* get srcpad */
4675   send_rtp_src = gst_element_get_static_pad (session->session, "send_rtp_src");
4676
4677   if (send_rtp_src == NULL)
4678     goto no_srcpad;
4679
4680   GST_DEBUG_OBJECT (rtpbin, "getting RTP encoder");
4681   encoder = session_request_element (session, SIGNAL_REQUEST_RTP_ENCODER);
4682   if (encoder) {
4683     gchar *ename;
4684     GstPad *encsrc, *encsink;
4685     GstPadLinkReturn ret;
4686
4687     GST_DEBUG_OBJECT (rtpbin, "linking RTP encoder");
4688     ename = g_strdup_printf ("rtp_src_%u", sessid);
4689     encsrc = gst_element_get_static_pad (encoder, ename);
4690     g_free (ename);
4691
4692     if (encsrc == NULL)
4693       goto enc_src_failed;
4694
4695     ename = g_strdup_printf ("rtp_sink_%u", sessid);
4696     encsink = gst_element_get_static_pad (encoder, ename);
4697     g_free (ename);
4698     if (encsink == NULL)
4699       goto enc_sink_failed;
4700
4701     ret = gst_pad_link (send_rtp_src, encsink);
4702     gst_object_unref (encsink);
4703     gst_object_unref (send_rtp_src);
4704
4705     send_rtp_src = encsrc;
4706
4707     if (ret != GST_PAD_LINK_OK)
4708       goto enc_link_failed;
4709   } else {
4710     GST_DEBUG_OBJECT (rtpbin, "no RTP encoder given");
4711   }
4712
4713   /* ghost the new source pad */
4714   klass = GST_ELEMENT_GET_CLASS (rtpbin);
4715   gname = g_strdup_printf ("send_rtp_src_%u", sessid);
4716   templ = gst_element_class_get_pad_template (klass, "send_rtp_src_%u");
4717   session->send_rtp_src_ghost =
4718       gst_ghost_pad_new_from_template (gname, send_rtp_src, templ);
4719   gst_pad_set_active (session->send_rtp_src_ghost, TRUE);
4720   gst_pad_sticky_events_foreach (send_rtp_src, copy_sticky_events,
4721       session->send_rtp_src_ghost);
4722   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_src_ghost);
4723   g_free (gname);
4724
4725   ret = TRUE;
4726
4727 done:
4728   if (send_rtp_src)
4729     gst_object_unref (send_rtp_src);
4730
4731   return ret;
4732
4733   /* ERRORS */
4734 no_srcpad:
4735   {
4736     g_warning ("rtpbin: failed to get rtp source pad for session %u", sessid);
4737     goto done;
4738   }
4739 enc_src_failed:
4740   {
4741     g_warning ("rtpbin: failed to get %" GST_PTR_FORMAT
4742         " src pad for session %u", encoder, sessid);
4743     goto done;
4744   }
4745 enc_sink_failed:
4746   {
4747     g_warning ("rtpbin: failed to get %" GST_PTR_FORMAT
4748         " sink pad for session %u", encoder, sessid);
4749     goto done;
4750   }
4751 enc_link_failed:
4752   {
4753     g_warning ("rtpbin: failed to link %" GST_PTR_FORMAT " for session %u",
4754         encoder, sessid);
4755     goto done;
4756   }
4757 }
4758
4759 static gboolean
4760 setup_aux_sender_fold (const GValue * item, GValue * result, gpointer user_data)
4761 {
4762   GstPad *pad;
4763   gchar *name;
4764   guint sessid;
4765   GstRtpBinSession *session = user_data, *newsess;
4766   GstRtpBin *rtpbin = session->bin;
4767   GstPadLinkReturn ret;
4768
4769   pad = g_value_get_object (item);
4770   name = gst_pad_get_name (pad);
4771
4772   if (name == NULL || sscanf (name, "src_%u", &sessid) != 1)
4773     goto no_name;
4774
4775   g_free (name);
4776
4777   newsess = find_session_by_id (rtpbin, sessid);
4778   if (newsess == NULL) {
4779     /* create new session */
4780     newsess = create_session (rtpbin, sessid);
4781     if (newsess == NULL)
4782       goto create_error;
4783   } else if (newsess->send_rtp_sink != NULL)
4784     goto existing_session;
4785
4786   /* get send_rtp pad and store */
4787   newsess->send_rtp_sink =
4788       gst_element_request_pad_simple (newsess->session, "send_rtp_sink");
4789   if (newsess->send_rtp_sink == NULL)
4790     goto pad_failed;
4791
4792   ret = gst_pad_link (pad, newsess->send_rtp_sink);
4793   if (ret != GST_PAD_LINK_OK)
4794     goto aux_link_failed;
4795
4796   if (!complete_session_src (rtpbin, newsess))
4797     goto session_src_failed;
4798
4799   return TRUE;
4800
4801   /* ERRORS */
4802 no_name:
4803   {
4804     GST_WARNING ("ignoring invalid pad name %s", GST_STR_NULL (name));
4805     g_free (name);
4806     return TRUE;
4807   }
4808 create_error:
4809   {
4810     /* create_session already warned */
4811     return FALSE;
4812   }
4813 existing_session:
4814   {
4815     GST_DEBUG_OBJECT (rtpbin,
4816         "skipping src_%i setup, since it is already configured.", sessid);
4817     return TRUE;
4818   }
4819 pad_failed:
4820   {
4821     g_warning ("rtpbin: failed to get session pad for session %u", sessid);
4822     return FALSE;
4823   }
4824 aux_link_failed:
4825   {
4826     g_warning ("rtpbin: failed to link AUX for session %u", sessid);
4827     return FALSE;
4828   }
4829 session_src_failed:
4830   {
4831     g_warning ("rtpbin: failed to complete AUX for session %u", sessid);
4832     return FALSE;
4833   }
4834 }
4835
4836 static gboolean
4837 setup_aux_sender (GstRtpBin * rtpbin, GstRtpBinSession * session,
4838     GstElement * aux)
4839 {
4840   GstIterator *it;
4841   GValue result = { 0, };
4842   GstIteratorResult res;
4843
4844   it = gst_element_iterate_src_pads (aux);
4845   res = gst_iterator_fold (it, setup_aux_sender_fold, &result, session);
4846   gst_iterator_free (it);
4847
4848   return res == GST_ITERATOR_DONE;
4849 }
4850
4851 static void
4852 fec_encoder_pad_added_cb (GstElement * encoder, GstPad * pad,
4853     GstRtpBinSession * session)
4854 {
4855   GstElementClass *klass;
4856   gchar *gname;
4857   GstPadTemplate *templ;
4858   guint fec_idx;
4859   GstPad *ghost;
4860
4861   if (sscanf (GST_PAD_NAME (pad), "fec_%u", &fec_idx) != 1) {
4862     GST_WARNING_OBJECT (session->bin,
4863         "FEC encoder added pad with name not matching fec_%%u (%s)",
4864         GST_PAD_NAME (pad));
4865     goto done;
4866   }
4867
4868   GST_INFO_OBJECT (session->bin, "FEC encoder for session %u exposed new pad",
4869       session->id);
4870
4871   GST_RTP_BIN_LOCK (session->bin);
4872   klass = GST_ELEMENT_GET_CLASS (session->bin);
4873   gname = g_strdup_printf ("send_fec_src_%u_%u", session->id, fec_idx);
4874   templ = gst_element_class_get_pad_template (klass, "send_fec_src_%u_%u");
4875   ghost = gst_ghost_pad_new_from_template (gname, pad, templ);
4876   session->send_fec_src_ghosts =
4877       g_slist_prepend (session->send_fec_src_ghosts, ghost);
4878   gst_pad_set_active (ghost, TRUE);
4879   gst_pad_sticky_events_foreach (pad, copy_sticky_events, ghost);
4880   gst_element_add_pad (GST_ELEMENT (session->bin), ghost);
4881   g_free (gname);
4882   GST_RTP_BIN_UNLOCK (session->bin);
4883
4884 done:
4885   return;
4886 }
4887
4888 static GstElement *
4889 request_fec_encoder (GstRtpBin * rtpbin, GstRtpBinSession * session,
4890     guint sessid)
4891 {
4892   GstElement *ret = NULL;
4893   const gchar *factory;
4894   gchar *sess_id_str;
4895
4896   sess_id_str = g_strdup_printf ("%u", sessid);
4897   factory = gst_structure_get_string (rtpbin->fec_encoders, sess_id_str);
4898   g_free (sess_id_str);
4899
4900   /* First try the property */
4901   if (factory) {
4902     GError *err = NULL;
4903
4904     ret =
4905         gst_parse_bin_from_description_full (factory, TRUE, NULL,
4906         GST_PARSE_FLAG_NO_SINGLE_ELEMENT_BINS | GST_PARSE_FLAG_FATAL_ERRORS,
4907         &err);
4908     if (!ret) {
4909       GST_ERROR_OBJECT (rtpbin, "Failed to build encoder from factory: %s",
4910           err->message);
4911       goto done;
4912     }
4913
4914     bin_manage_element (session->bin, ret);
4915     session->elements = g_slist_prepend (session->elements, ret);
4916     GST_INFO_OBJECT (rtpbin, "Built FEC encoder: %" GST_PTR_FORMAT
4917         " for session %u", ret, sessid);
4918   }
4919
4920   /* Fallback to the signal */
4921   if (!ret)
4922     ret = session_request_element (session, SIGNAL_REQUEST_FEC_ENCODER);
4923
4924   if (ret) {
4925     g_signal_connect (ret, "pad-added", G_CALLBACK (fec_encoder_pad_added_cb),
4926         session);
4927   }
4928
4929 done:
4930   return ret;
4931 }
4932
4933 /* Create a pad for sending RTP for the session in @name. Must be called with
4934  * RTP_BIN_LOCK.
4935  */
4936 static GstPad *
4937 create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
4938 {
4939   gchar *pname;
4940   guint sessid;
4941   GstPad *send_rtp_sink;
4942   GstElement *aux;
4943   GstElement *encoder;
4944   GstElement *prev = NULL;
4945   GstRtpBinSession *session;
4946
4947   /* first get the session number */
4948   if (name == NULL || sscanf (name, "send_rtp_sink_%u", &sessid) != 1)
4949     goto no_name;
4950
4951   /* get or create session */
4952   session = find_session_by_id (rtpbin, sessid);
4953   if (!session) {
4954     /* create session now */
4955     session = create_session (rtpbin, sessid);
4956     if (session == NULL)
4957       goto create_error;
4958   }
4959
4960   /* check if pad was requested */
4961   if (session->send_rtp_sink_ghost != NULL)
4962     return session->send_rtp_sink_ghost;
4963
4964   /* check if we are already using this session as a sender */
4965   if (session->send_rtp_sink != NULL)
4966     goto existing_session;
4967
4968   encoder = request_fec_encoder (rtpbin, session, sessid);
4969
4970   if (encoder) {
4971     GST_DEBUG_OBJECT (rtpbin, "Linking FEC encoder");
4972
4973     send_rtp_sink = gst_element_get_static_pad (encoder, "sink");
4974
4975     if (!send_rtp_sink)
4976       goto enc_sink_failed;
4977
4978     prev = encoder;
4979   }
4980
4981   GST_DEBUG_OBJECT (rtpbin, "getting RTP AUX sender");
4982   aux = session_request_element (session, SIGNAL_REQUEST_AUX_SENDER);
4983   if (aux) {
4984     GstPad *sinkpad;
4985     GST_DEBUG_OBJECT (rtpbin, "linking AUX sender");
4986     if (!setup_aux_sender (rtpbin, session, aux))
4987       goto aux_session_failed;
4988
4989     pname = g_strdup_printf ("sink_%u", sessid);
4990     sinkpad = gst_element_get_static_pad (aux, pname);
4991     g_free (pname);
4992
4993     if (sinkpad == NULL)
4994       goto aux_sink_failed;
4995
4996     if (!prev) {
4997       send_rtp_sink = sinkpad;
4998     } else {
4999       GstPad *srcpad = gst_element_get_static_pad (prev, "src");
5000       GstPadLinkReturn ret;
5001
5002       ret = gst_pad_link (srcpad, sinkpad);
5003       gst_object_unref (srcpad);
5004       if (ret != GST_PAD_LINK_OK) {
5005         goto aux_link_failed;
5006       }
5007       gst_object_unref (sinkpad);
5008     }
5009     prev = aux;
5010   } else {
5011     /* get send_rtp pad and store */
5012     session->send_rtp_sink =
5013         gst_element_request_pad_simple (session->session, "send_rtp_sink");
5014     if (session->send_rtp_sink == NULL)
5015       goto pad_failed;
5016
5017     if (!complete_session_src (rtpbin, session))
5018       goto session_src_failed;
5019
5020     if (!prev) {
5021       send_rtp_sink = gst_object_ref (session->send_rtp_sink);
5022     } else {
5023       GstPad *srcpad = gst_element_get_static_pad (prev, "src");
5024       GstPadLinkReturn ret;
5025
5026       ret = gst_pad_link (srcpad, session->send_rtp_sink);
5027       gst_object_unref (srcpad);
5028       if (ret != GST_PAD_LINK_OK)
5029         goto session_link_failed;
5030     }
5031   }
5032
5033   session->send_rtp_sink_ghost =
5034       gst_ghost_pad_new_from_template (name, send_rtp_sink, templ);
5035   gst_object_unref (send_rtp_sink);
5036   gst_pad_set_active (session->send_rtp_sink_ghost, TRUE);
5037   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_sink_ghost);
5038
5039   return session->send_rtp_sink_ghost;
5040
5041   /* ERRORS */
5042 no_name:
5043   {
5044     g_warning ("rtpbin: cannot find session id for pad: %s",
5045         GST_STR_NULL (name));
5046     return NULL;
5047   }
5048 create_error:
5049   {
5050     /* create_session already warned */
5051     return NULL;
5052   }
5053 existing_session:
5054   {
5055     g_warning ("rtpbin: session %u is already in use", sessid);
5056     return NULL;
5057   }
5058 aux_session_failed:
5059   {
5060     g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
5061     return NULL;
5062   }
5063 aux_sink_failed:
5064   {
5065     g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
5066     return NULL;
5067   }
5068 aux_link_failed:
5069   {
5070     g_warning ("rtpbin: failed to link %" GST_PTR_FORMAT " for session %u",
5071         aux, sessid);
5072     return NULL;
5073   }
5074 pad_failed:
5075   {
5076     g_warning ("rtpbin: failed to get session pad for session %u", sessid);
5077     return NULL;
5078   }
5079 session_src_failed:
5080   {
5081     g_warning ("rtpbin: failed to setup source pads for session %u", sessid);
5082     return NULL;
5083   }
5084 session_link_failed:
5085   {
5086     g_warning ("rtpbin: failed to link %" GST_PTR_FORMAT " for session %u",
5087         session, sessid);
5088     return NULL;
5089   }
5090 enc_sink_failed:
5091   {
5092     g_warning ("rtpbin: failed to get %" GST_PTR_FORMAT
5093         " sink pad for session %u", encoder, sessid);
5094     return NULL;
5095   }
5096 }
5097
5098 static void
5099 remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
5100 {
5101   if (session->send_rtp_src_ghost) {
5102     gst_pad_set_active (session->send_rtp_src_ghost, FALSE);
5103     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
5104         session->send_rtp_src_ghost);
5105     session->send_rtp_src_ghost = NULL;
5106   }
5107   if (session->send_rtp_sink) {
5108     gst_element_release_request_pad (GST_ELEMENT_CAST (session->session),
5109         session->send_rtp_sink);
5110     gst_object_unref (session->send_rtp_sink);
5111     session->send_rtp_sink = NULL;
5112   }
5113   if (session->send_rtp_sink_ghost) {
5114     gst_pad_set_active (session->send_rtp_sink_ghost, FALSE);
5115     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
5116         session->send_rtp_sink_ghost);
5117     session->send_rtp_sink_ghost = NULL;
5118   }
5119 }
5120
5121 static void
5122 remove_send_fec (GstRtpBin * rtpbin, GstRtpBinSession * session)
5123 {
5124   GSList *tmp;
5125
5126   for (tmp = session->send_fec_src_ghosts; tmp; tmp = tmp->next) {
5127     GstPad *ghost = GST_PAD (tmp->data);
5128     gst_pad_set_active (ghost, FALSE);
5129     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), ghost);
5130   }
5131
5132   g_slist_free (session->send_fec_src_ghosts);
5133   session->send_fec_src_ghosts = NULL;
5134 }
5135
5136 /* Create a pad for sending RTCP for the session in @name. Must be called with
5137  * RTP_BIN_LOCK.
5138  */
5139 static GstPad *
5140 create_send_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
5141     const gchar * name)
5142 {
5143   guint sessid;
5144   GstPad *encsrc;
5145   GstElement *encoder;
5146   GstRtpBinSession *session;
5147
5148   /* first get the session number */
5149   if (name == NULL || sscanf (name, "send_rtcp_src_%u", &sessid) != 1)
5150     goto no_name;
5151
5152   /* get or create session */
5153   session = find_session_by_id (rtpbin, sessid);
5154   if (!session) {
5155     GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
5156     /* create session now */
5157     session = create_session (rtpbin, sessid);
5158     if (session == NULL)
5159       goto create_error;
5160   }
5161
5162   /* check if pad was requested */
5163   if (session->send_rtcp_src_ghost != NULL)
5164     return session->send_rtcp_src_ghost;
5165
5166   /* get rtcp_src pad and store */
5167   session->send_rtcp_src =
5168       gst_element_request_pad_simple (session->session, "send_rtcp_src");
5169   if (session->send_rtcp_src == NULL)
5170     goto pad_failed;
5171
5172   GST_DEBUG_OBJECT (rtpbin, "getting RTCP encoder");
5173   encoder = session_request_element (session, SIGNAL_REQUEST_RTCP_ENCODER);
5174   if (encoder) {
5175     gchar *ename;
5176     GstPad *encsink;
5177     GstPadLinkReturn ret;
5178
5179     GST_DEBUG_OBJECT (rtpbin, "linking RTCP encoder");
5180
5181     ename = g_strdup_printf ("rtcp_src_%u", sessid);
5182     encsrc = gst_element_get_static_pad (encoder, ename);
5183     g_free (ename);
5184     if (encsrc == NULL)
5185       goto enc_src_failed;
5186
5187     ename = g_strdup_printf ("rtcp_sink_%u", sessid);
5188     encsink = gst_element_get_static_pad (encoder, ename);
5189     g_free (ename);
5190     if (encsink == NULL)
5191       goto enc_sink_failed;
5192
5193     ret = gst_pad_link (session->send_rtcp_src, encsink);
5194     gst_object_unref (encsink);
5195
5196     if (ret != GST_PAD_LINK_OK)
5197       goto enc_link_failed;
5198   } else {
5199     GST_DEBUG_OBJECT (rtpbin, "no RTCP encoder given");
5200     encsrc = gst_object_ref (session->send_rtcp_src);
5201   }
5202
5203   session->send_rtcp_src_ghost =
5204       gst_ghost_pad_new_from_template (name, encsrc, templ);
5205   gst_object_unref (encsrc);
5206   gst_pad_set_active (session->send_rtcp_src_ghost, TRUE);
5207   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtcp_src_ghost);
5208
5209   return session->send_rtcp_src_ghost;
5210
5211   /* ERRORS */
5212 no_name:
5213   {
5214     g_warning ("rtpbin: cannot find session id for pad: %s",
5215         GST_STR_NULL (name));
5216     return NULL;
5217   }
5218 create_error:
5219   {
5220     /* create_session already warned */
5221     return NULL;
5222   }
5223 pad_failed:
5224   {
5225     g_warning ("rtpbin: failed to get rtcp pad for session %u", sessid);
5226     return NULL;
5227   }
5228 enc_src_failed:
5229   {
5230     g_warning ("rtpbin: failed to get encoder src pad for session %u", sessid);
5231     return NULL;
5232   }
5233 enc_sink_failed:
5234   {
5235     g_warning ("rtpbin: failed to get encoder sink pad for session %u", sessid);
5236     gst_object_unref (encsrc);
5237     return NULL;
5238   }
5239 enc_link_failed:
5240   {
5241     g_warning ("rtpbin: failed to link rtcp encoder for session %u", sessid);
5242     gst_object_unref (encsrc);
5243     return NULL;
5244   }
5245 }
5246
5247 static void
5248 remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session)
5249 {
5250   if (session->send_rtcp_src_ghost) {
5251     gst_pad_set_active (session->send_rtcp_src_ghost, FALSE);
5252     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
5253         session->send_rtcp_src_ghost);
5254     session->send_rtcp_src_ghost = NULL;
5255   }
5256   if (session->send_rtcp_src) {
5257     gst_element_release_request_pad (session->session, session->send_rtcp_src);
5258     gst_object_unref (session->send_rtcp_src);
5259     session->send_rtcp_src = NULL;
5260   }
5261 }
5262
5263 /* If the requested name is NULL we should create a name with
5264  * the session number assuming we want the lowest possible session
5265  * with a free pad like the template */
5266 static gchar *
5267 gst_rtp_bin_get_free_pad_name (GstElement * element, GstPadTemplate * templ)
5268 {
5269   gboolean name_found = FALSE;
5270   gint session = 0;
5271   GstIterator *pad_it = NULL;
5272   gchar *pad_name = NULL;
5273   GValue data = { 0, };
5274
5275   GST_DEBUG_OBJECT (element, "find a free pad name for template");
5276   while (!name_found) {
5277     gboolean done = FALSE;
5278
5279     g_free (pad_name);
5280     pad_name = g_strdup_printf (templ->name_template, session++);
5281     pad_it = gst_element_iterate_pads (GST_ELEMENT (element));
5282     name_found = TRUE;
5283     while (!done) {
5284       switch (gst_iterator_next (pad_it, &data)) {
5285         case GST_ITERATOR_OK:
5286         {
5287           GstPad *pad;
5288           gchar *name;
5289
5290           pad = g_value_get_object (&data);
5291           name = gst_pad_get_name (pad);
5292
5293           if (strcmp (name, pad_name) == 0) {
5294             done = TRUE;
5295             name_found = FALSE;
5296           }
5297           g_free (name);
5298           g_value_reset (&data);
5299           break;
5300         }
5301         case GST_ITERATOR_ERROR:
5302         case GST_ITERATOR_RESYNC:
5303           /* restart iteration */
5304           done = TRUE;
5305           name_found = FALSE;
5306           session = 0;
5307           break;
5308         case GST_ITERATOR_DONE:
5309           done = TRUE;
5310           break;
5311       }
5312     }
5313     g_value_unset (&data);
5314     gst_iterator_free (pad_it);
5315   }
5316
5317   GST_DEBUG_OBJECT (element, "free pad name found: '%s'", pad_name);
5318   return pad_name;
5319 }
5320
5321 /*
5322  */
5323 static GstPad *
5324 gst_rtp_bin_request_new_pad (GstElement * element,
5325     GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
5326 {
5327   GstRtpBin *rtpbin;
5328   GstElementClass *klass;
5329   GstPad *result;
5330
5331   gchar *pad_name = NULL;
5332
5333   g_return_val_if_fail (templ != NULL, NULL);
5334   g_return_val_if_fail (GST_IS_RTP_BIN (element), NULL);
5335
5336   rtpbin = GST_RTP_BIN (element);
5337   klass = GST_ELEMENT_GET_CLASS (element);
5338
5339   GST_RTP_BIN_LOCK (rtpbin);
5340
5341   if (name == NULL) {
5342     /* use a free pad name */
5343     pad_name = gst_rtp_bin_get_free_pad_name (element, templ);
5344   } else {
5345     /* use the provided name */
5346     pad_name = g_strdup (name);
5347   }
5348
5349   GST_DEBUG_OBJECT (rtpbin, "Trying to request a pad with name %s", pad_name);
5350
5351   /* figure out the template */
5352   if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink_%u")) {
5353     result = create_recv_rtp (rtpbin, templ, pad_name);
5354   } else if (templ == gst_element_class_get_pad_template (klass,
5355           "recv_rtcp_sink_%u")) {
5356     result = create_recv_rtcp (rtpbin, templ, pad_name);
5357   } else if (templ == gst_element_class_get_pad_template (klass,
5358           "send_rtp_sink_%u")) {
5359     result = create_send_rtp (rtpbin, templ, pad_name);
5360   } else if (templ == gst_element_class_get_pad_template (klass,
5361           "send_rtcp_src_%u")) {
5362     result = create_send_rtcp (rtpbin, templ, pad_name);
5363   } else if (templ == gst_element_class_get_pad_template (klass,
5364           "recv_fec_sink_%u_%u")) {
5365     result = create_recv_fec (rtpbin, templ, pad_name);
5366   } else
5367     goto wrong_template;
5368
5369   g_free (pad_name);
5370   GST_RTP_BIN_UNLOCK (rtpbin);
5371
5372   return result;
5373
5374   /* ERRORS */
5375 wrong_template:
5376   {
5377     g_free (pad_name);
5378     GST_RTP_BIN_UNLOCK (rtpbin);
5379     g_warning ("rtpbin: this is not our template");
5380     return NULL;
5381   }
5382 }
5383
5384 static void
5385 gst_rtp_bin_release_pad (GstElement * element, GstPad * pad)
5386 {
5387   GstRtpBinSession *session;
5388   GstRtpBin *rtpbin;
5389
5390   g_return_if_fail (GST_IS_GHOST_PAD (pad));
5391   g_return_if_fail (GST_IS_RTP_BIN (element));
5392
5393   rtpbin = GST_RTP_BIN (element);
5394
5395   GST_RTP_BIN_LOCK (rtpbin);
5396   GST_DEBUG_OBJECT (rtpbin, "Trying to release pad %s:%s",
5397       GST_DEBUG_PAD_NAME (pad));
5398
5399   if (!(session = find_session_by_pad (rtpbin, pad)))
5400     goto unknown_pad;
5401
5402   if (session->recv_rtp_sink_ghost == pad) {
5403     remove_recv_rtp (rtpbin, session);
5404   } else if (session->recv_rtcp_sink_ghost == pad) {
5405     remove_recv_rtcp (rtpbin, session);
5406   } else if (session->send_rtp_sink_ghost == pad) {
5407     remove_send_rtp (rtpbin, session);
5408   } else if (session->send_rtcp_src_ghost == pad) {
5409     remove_rtcp (rtpbin, session);
5410   } else if (pad_is_recv_fec (session, pad)) {
5411     remove_recv_fec_for_pad (rtpbin, session, pad);
5412   }
5413
5414   /* no more request pads, free the complete session */
5415   if (session->recv_rtp_sink_ghost == NULL
5416       && session->recv_rtcp_sink_ghost == NULL
5417       && session->send_rtp_sink_ghost == NULL
5418       && session->send_rtcp_src_ghost == NULL
5419       && session->recv_fec_sink_ghosts == NULL) {
5420     GST_DEBUG_OBJECT (rtpbin, "no more pads for session %p", session);
5421     rtpbin->sessions = g_slist_remove (rtpbin->sessions, session);
5422     free_session (session, rtpbin);
5423   }
5424   GST_RTP_BIN_UNLOCK (rtpbin);
5425
5426   return;
5427
5428   /* ERROR */
5429 unknown_pad:
5430   {
5431     GST_RTP_BIN_UNLOCK (rtpbin);
5432     g_warning ("rtpbin: %s:%s is not one of our request pads",
5433         GST_DEBUG_PAD_NAME (pad));
5434     return;
5435   }
5436 }