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