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