52d21ffdd9ed00d3fab99b0fbd74d2a40b941c54
[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   g_object_class_install_property (gobject_class, PROP_MAX_TS_OFFSET_ADJUSTMENT,
2649       g_param_spec_uint64 ("max-ts-offset-adjustment",
2650           "Max Timestamp Offset Adjustment",
2651           "The maximum number of nanoseconds per frame that time stamp offsets "
2652           "may be adjusted (0 = no limit).", 0, G_MAXUINT64,
2653           DEFAULT_MAX_TS_OFFSET_ADJUSTMENT, G_PARAM_READWRITE |
2654           G_PARAM_STATIC_STRINGS));
2655
2656   /**
2657    * GstRtpBin:max-ts-offset:
2658    *
2659    * Used to set an upper limit of how large a time offset may be. This
2660    * is used to protect against unrealistic values as a result of either
2661    * client,server or clock issues.
2662    */
2663   g_object_class_install_property (gobject_class, PROP_MAX_TS_OFFSET,
2664       g_param_spec_int64 ("max-ts-offset", "Max TS Offset",
2665           "The maximum absolute value of the time offset in (nanoseconds). "
2666           "Note, if the ntp-sync parameter is set the default value is "
2667           "changed to 0 (no limit)", 0, G_MAXINT64, DEFAULT_MAX_TS_OFFSET,
2668           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2669
2670   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
2671   gstelement_class->request_new_pad =
2672       GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
2673   gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_release_pad);
2674
2675   /* sink pads */
2676   gst_element_class_add_static_pad_template (gstelement_class,
2677       &rtpbin_recv_rtp_sink_template);
2678   gst_element_class_add_static_pad_template (gstelement_class,
2679       &rtpbin_recv_rtcp_sink_template);
2680   gst_element_class_add_static_pad_template (gstelement_class,
2681       &rtpbin_send_rtp_sink_template);
2682
2683   /* src pads */
2684   gst_element_class_add_static_pad_template (gstelement_class,
2685       &rtpbin_recv_rtp_src_template);
2686   gst_element_class_add_static_pad_template (gstelement_class,
2687       &rtpbin_send_rtcp_src_template);
2688   gst_element_class_add_static_pad_template (gstelement_class,
2689       &rtpbin_send_rtp_src_template);
2690
2691   gst_element_class_set_static_metadata (gstelement_class, "RTP Bin",
2692       "Filter/Network/RTP",
2693       "Real-Time Transport Protocol bin",
2694       "Wim Taymans <wim.taymans@gmail.com>");
2695
2696   gstbin_class->handle_message = GST_DEBUG_FUNCPTR (gst_rtp_bin_handle_message);
2697
2698   klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map);
2699   klass->reset_sync = GST_DEBUG_FUNCPTR (gst_rtp_bin_reset_sync);
2700   klass->get_session = GST_DEBUG_FUNCPTR (gst_rtp_bin_get_session);
2701   klass->get_internal_session =
2702       GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_session);
2703   klass->get_internal_storage =
2704       GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_storage);
2705   klass->request_rtp_encoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_encoder);
2706   klass->request_rtp_decoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_decoder);
2707   klass->request_rtcp_encoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_encoder);
2708   klass->request_rtcp_decoder = GST_DEBUG_FUNCPTR (gst_rtp_bin_request_decoder);
2709
2710   GST_DEBUG_CATEGORY_INIT (gst_rtp_bin_debug, "rtpbin", 0, "RTP bin");
2711 }
2712
2713 static void
2714 gst_rtp_bin_init (GstRtpBin * rtpbin)
2715 {
2716   gchar *cname;
2717
2718   rtpbin->priv = GST_RTP_BIN_GET_PRIVATE (rtpbin);
2719   g_mutex_init (&rtpbin->priv->bin_lock);
2720   g_mutex_init (&rtpbin->priv->dyn_lock);
2721
2722   rtpbin->latency_ms = DEFAULT_LATENCY_MS;
2723   rtpbin->latency_ns = DEFAULT_LATENCY_MS * GST_MSECOND;
2724   rtpbin->drop_on_latency = DEFAULT_DROP_ON_LATENCY;
2725   rtpbin->do_lost = DEFAULT_DO_LOST;
2726   rtpbin->ignore_pt = DEFAULT_IGNORE_PT;
2727   rtpbin->ntp_sync = DEFAULT_NTP_SYNC;
2728   rtpbin->rtcp_sync = DEFAULT_RTCP_SYNC;
2729   rtpbin->rtcp_sync_interval = DEFAULT_RTCP_SYNC_INTERVAL;
2730   rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE;
2731   rtpbin->buffer_mode = DEFAULT_BUFFER_MODE;
2732   rtpbin->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
2733   rtpbin->send_sync_event = DEFAULT_DO_SYNC_EVENT;
2734   rtpbin->do_retransmission = DEFAULT_DO_RETRANSMISSION;
2735   rtpbin->rtp_profile = DEFAULT_RTP_PROFILE;
2736   rtpbin->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
2737   rtpbin->rtcp_sync_send_time = DEFAULT_RTCP_SYNC_SEND_TIME;
2738   rtpbin->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
2739   rtpbin->max_dropout_time = DEFAULT_MAX_DROPOUT_TIME;
2740   rtpbin->max_misorder_time = DEFAULT_MAX_MISORDER_TIME;
2741   rtpbin->rfc7273_sync = DEFAULT_RFC7273_SYNC;
2742   rtpbin->max_streams = DEFAULT_MAX_STREAMS;
2743   rtpbin->max_ts_offset_adjustment = DEFAULT_MAX_TS_OFFSET_ADJUSTMENT;
2744   rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
2745   rtpbin->max_ts_offset_is_set = FALSE;
2746
2747   /* some default SDES entries */
2748   cname = g_strdup_printf ("user%u@host-%x", g_random_int (), g_random_int ());
2749   rtpbin->sdes = gst_structure_new ("application/x-rtp-source-sdes",
2750       "cname", G_TYPE_STRING, cname, "tool", G_TYPE_STRING, "GStreamer", NULL);
2751   g_free (cname);
2752 }
2753
2754 static void
2755 gst_rtp_bin_dispose (GObject * object)
2756 {
2757   GstRtpBin *rtpbin;
2758
2759   rtpbin = GST_RTP_BIN (object);
2760
2761   GST_RTP_BIN_LOCK (rtpbin);
2762   GST_DEBUG_OBJECT (object, "freeing sessions");
2763   g_slist_foreach (rtpbin->sessions, (GFunc) free_session, rtpbin);
2764   g_slist_free (rtpbin->sessions);
2765   rtpbin->sessions = NULL;
2766   GST_RTP_BIN_UNLOCK (rtpbin);
2767
2768   G_OBJECT_CLASS (parent_class)->dispose (object);
2769 }
2770
2771 static void
2772 gst_rtp_bin_finalize (GObject * object)
2773 {
2774   GstRtpBin *rtpbin;
2775
2776   rtpbin = GST_RTP_BIN (object);
2777
2778   if (rtpbin->sdes)
2779     gst_structure_free (rtpbin->sdes);
2780
2781   g_mutex_clear (&rtpbin->priv->bin_lock);
2782   g_mutex_clear (&rtpbin->priv->dyn_lock);
2783
2784   G_OBJECT_CLASS (parent_class)->finalize (object);
2785 }
2786
2787
2788 static void
2789 gst_rtp_bin_set_sdes_struct (GstRtpBin * bin, const GstStructure * sdes)
2790 {
2791   GSList *item;
2792
2793   if (sdes == NULL)
2794     return;
2795
2796   GST_RTP_BIN_LOCK (bin);
2797
2798   GST_OBJECT_LOCK (bin);
2799   if (bin->sdes)
2800     gst_structure_free (bin->sdes);
2801   bin->sdes = gst_structure_copy (sdes);
2802   GST_OBJECT_UNLOCK (bin);
2803
2804   /* store in all sessions */
2805   for (item = bin->sessions; item; item = g_slist_next (item)) {
2806     GstRtpBinSession *session = item->data;
2807     g_object_set (session->session, "sdes", sdes, NULL);
2808   }
2809
2810   GST_RTP_BIN_UNLOCK (bin);
2811 }
2812
2813 static GstStructure *
2814 gst_rtp_bin_get_sdes_struct (GstRtpBin * bin)
2815 {
2816   GstStructure *result;
2817
2818   GST_OBJECT_LOCK (bin);
2819   result = gst_structure_copy (bin->sdes);
2820   GST_OBJECT_UNLOCK (bin);
2821
2822   return result;
2823 }
2824
2825 static void
2826 gst_rtp_bin_set_property (GObject * object, guint prop_id,
2827     const GValue * value, GParamSpec * pspec)
2828 {
2829   GstRtpBin *rtpbin;
2830
2831   rtpbin = GST_RTP_BIN (object);
2832
2833   switch (prop_id) {
2834     case PROP_LATENCY:
2835       GST_RTP_BIN_LOCK (rtpbin);
2836       rtpbin->latency_ms = g_value_get_uint (value);
2837       rtpbin->latency_ns = rtpbin->latency_ms * GST_MSECOND;
2838       GST_RTP_BIN_UNLOCK (rtpbin);
2839       /* propagate the property down to the jitterbuffer */
2840       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "latency", value);
2841       break;
2842     case PROP_DROP_ON_LATENCY:
2843       GST_RTP_BIN_LOCK (rtpbin);
2844       rtpbin->drop_on_latency = g_value_get_boolean (value);
2845       GST_RTP_BIN_UNLOCK (rtpbin);
2846       /* propagate the property down to the jitterbuffer */
2847       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
2848           "drop-on-latency", value);
2849       break;
2850     case PROP_SDES:
2851       gst_rtp_bin_set_sdes_struct (rtpbin, g_value_get_boxed (value));
2852       break;
2853     case PROP_DO_LOST:
2854       GST_RTP_BIN_LOCK (rtpbin);
2855       rtpbin->do_lost = g_value_get_boolean (value);
2856       GST_RTP_BIN_UNLOCK (rtpbin);
2857       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "do-lost", value);
2858       break;
2859     case PROP_NTP_SYNC:
2860       rtpbin->ntp_sync = g_value_get_boolean (value);
2861       /* The default value of max_ts_offset depends on ntp_sync. If user
2862        * hasn't set it then change default value */
2863       if (!rtpbin->max_ts_offset_is_set) {
2864         if (rtpbin->ntp_sync) {
2865           rtpbin->max_ts_offset = 0;
2866         } else {
2867           rtpbin->max_ts_offset = DEFAULT_MAX_TS_OFFSET;
2868         }
2869       }
2870       break;
2871     case PROP_RTCP_SYNC:
2872       g_atomic_int_set (&rtpbin->rtcp_sync, g_value_get_enum (value));
2873       break;
2874     case PROP_RTCP_SYNC_INTERVAL:
2875       rtpbin->rtcp_sync_interval = g_value_get_uint (value);
2876       break;
2877     case PROP_IGNORE_PT:
2878       rtpbin->ignore_pt = g_value_get_boolean (value);
2879       break;
2880     case PROP_AUTOREMOVE:
2881       rtpbin->priv->autoremove = g_value_get_boolean (value);
2882       break;
2883     case PROP_USE_PIPELINE_CLOCK:
2884     {
2885       GSList *sessions;
2886       GST_RTP_BIN_LOCK (rtpbin);
2887       rtpbin->use_pipeline_clock = g_value_get_boolean (value);
2888       for (sessions = rtpbin->sessions; sessions;
2889           sessions = g_slist_next (sessions)) {
2890         GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
2891
2892         g_object_set (G_OBJECT (session->session),
2893             "use-pipeline-clock", rtpbin->use_pipeline_clock, NULL);
2894       }
2895       GST_RTP_BIN_UNLOCK (rtpbin);
2896     }
2897       break;
2898     case PROP_DO_SYNC_EVENT:
2899       rtpbin->send_sync_event = g_value_get_boolean (value);
2900       break;
2901     case PROP_BUFFER_MODE:
2902       GST_RTP_BIN_LOCK (rtpbin);
2903       rtpbin->buffer_mode = g_value_get_enum (value);
2904       GST_RTP_BIN_UNLOCK (rtpbin);
2905       /* propagate the property down to the jitterbuffer */
2906       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "mode", value);
2907       break;
2908     case PROP_DO_RETRANSMISSION:
2909       GST_RTP_BIN_LOCK (rtpbin);
2910       rtpbin->do_retransmission = g_value_get_boolean (value);
2911       GST_RTP_BIN_UNLOCK (rtpbin);
2912       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
2913           "do-retransmission", value);
2914       break;
2915     case PROP_RTP_PROFILE:
2916       rtpbin->rtp_profile = g_value_get_enum (value);
2917       break;
2918     case PROP_NTP_TIME_SOURCE:{
2919       GSList *sessions;
2920       GST_RTP_BIN_LOCK (rtpbin);
2921       rtpbin->ntp_time_source = g_value_get_enum (value);
2922       for (sessions = rtpbin->sessions; sessions;
2923           sessions = g_slist_next (sessions)) {
2924         GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
2925
2926         g_object_set (G_OBJECT (session->session),
2927             "ntp-time-source", rtpbin->ntp_time_source, NULL);
2928       }
2929       GST_RTP_BIN_UNLOCK (rtpbin);
2930       break;
2931     }
2932     case PROP_RTCP_SYNC_SEND_TIME:{
2933       GSList *sessions;
2934       GST_RTP_BIN_LOCK (rtpbin);
2935       rtpbin->rtcp_sync_send_time = g_value_get_boolean (value);
2936       for (sessions = rtpbin->sessions; sessions;
2937           sessions = g_slist_next (sessions)) {
2938         GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
2939
2940         g_object_set (G_OBJECT (session->session),
2941             "rtcp-sync-send-time", rtpbin->rtcp_sync_send_time, NULL);
2942       }
2943       GST_RTP_BIN_UNLOCK (rtpbin);
2944       break;
2945     }
2946     case PROP_MAX_RTCP_RTP_TIME_DIFF:
2947       GST_RTP_BIN_LOCK (rtpbin);
2948       rtpbin->max_rtcp_rtp_time_diff = g_value_get_int (value);
2949       GST_RTP_BIN_UNLOCK (rtpbin);
2950       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
2951           "max-rtcp-rtp-time-diff", value);
2952       break;
2953     case PROP_MAX_DROPOUT_TIME:
2954       GST_RTP_BIN_LOCK (rtpbin);
2955       rtpbin->max_dropout_time = g_value_get_uint (value);
2956       GST_RTP_BIN_UNLOCK (rtpbin);
2957       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
2958           "max-dropout-time", value);
2959       gst_rtp_bin_propagate_property_to_session (rtpbin, "max-dropout-time",
2960           value);
2961       break;
2962     case PROP_MAX_MISORDER_TIME:
2963       GST_RTP_BIN_LOCK (rtpbin);
2964       rtpbin->max_misorder_time = g_value_get_uint (value);
2965       GST_RTP_BIN_UNLOCK (rtpbin);
2966       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
2967           "max-misorder-time", value);
2968       gst_rtp_bin_propagate_property_to_session (rtpbin, "max-misorder-time",
2969           value);
2970       break;
2971     case PROP_RFC7273_SYNC:
2972       rtpbin->rfc7273_sync = g_value_get_boolean (value);
2973       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
2974           "rfc7273-sync", value);
2975       break;
2976     case PROP_MAX_STREAMS:
2977       rtpbin->max_streams = g_value_get_uint (value);
2978       break;
2979     case PROP_MAX_TS_OFFSET_ADJUSTMENT:
2980       rtpbin->max_ts_offset_adjustment = g_value_get_uint64 (value);
2981       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin,
2982           "max-ts-offset-adjustment", value);
2983       break;
2984     case PROP_MAX_TS_OFFSET:
2985       rtpbin->max_ts_offset = g_value_get_int64 (value);
2986       rtpbin->max_ts_offset_is_set = TRUE;
2987       break;
2988     default:
2989       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2990       break;
2991   }
2992 }
2993
2994 static void
2995 gst_rtp_bin_get_property (GObject * object, guint prop_id,
2996     GValue * value, GParamSpec * pspec)
2997 {
2998   GstRtpBin *rtpbin;
2999
3000   rtpbin = GST_RTP_BIN (object);
3001
3002   switch (prop_id) {
3003     case PROP_LATENCY:
3004       GST_RTP_BIN_LOCK (rtpbin);
3005       g_value_set_uint (value, rtpbin->latency_ms);
3006       GST_RTP_BIN_UNLOCK (rtpbin);
3007       break;
3008     case PROP_DROP_ON_LATENCY:
3009       GST_RTP_BIN_LOCK (rtpbin);
3010       g_value_set_boolean (value, rtpbin->drop_on_latency);
3011       GST_RTP_BIN_UNLOCK (rtpbin);
3012       break;
3013     case PROP_SDES:
3014       g_value_take_boxed (value, gst_rtp_bin_get_sdes_struct (rtpbin));
3015       break;
3016     case PROP_DO_LOST:
3017       GST_RTP_BIN_LOCK (rtpbin);
3018       g_value_set_boolean (value, rtpbin->do_lost);
3019       GST_RTP_BIN_UNLOCK (rtpbin);
3020       break;
3021     case PROP_IGNORE_PT:
3022       g_value_set_boolean (value, rtpbin->ignore_pt);
3023       break;
3024     case PROP_NTP_SYNC:
3025       g_value_set_boolean (value, rtpbin->ntp_sync);
3026       break;
3027     case PROP_RTCP_SYNC:
3028       g_value_set_enum (value, g_atomic_int_get (&rtpbin->rtcp_sync));
3029       break;
3030     case PROP_RTCP_SYNC_INTERVAL:
3031       g_value_set_uint (value, rtpbin->rtcp_sync_interval);
3032       break;
3033     case PROP_AUTOREMOVE:
3034       g_value_set_boolean (value, rtpbin->priv->autoremove);
3035       break;
3036     case PROP_BUFFER_MODE:
3037       g_value_set_enum (value, rtpbin->buffer_mode);
3038       break;
3039     case PROP_USE_PIPELINE_CLOCK:
3040       g_value_set_boolean (value, rtpbin->use_pipeline_clock);
3041       break;
3042     case PROP_DO_SYNC_EVENT:
3043       g_value_set_boolean (value, rtpbin->send_sync_event);
3044       break;
3045     case PROP_DO_RETRANSMISSION:
3046       GST_RTP_BIN_LOCK (rtpbin);
3047       g_value_set_boolean (value, rtpbin->do_retransmission);
3048       GST_RTP_BIN_UNLOCK (rtpbin);
3049       break;
3050     case PROP_RTP_PROFILE:
3051       g_value_set_enum (value, rtpbin->rtp_profile);
3052       break;
3053     case PROP_NTP_TIME_SOURCE:
3054       g_value_set_enum (value, rtpbin->ntp_time_source);
3055       break;
3056     case PROP_RTCP_SYNC_SEND_TIME:
3057       g_value_set_boolean (value, rtpbin->rtcp_sync_send_time);
3058       break;
3059     case PROP_MAX_RTCP_RTP_TIME_DIFF:
3060       GST_RTP_BIN_LOCK (rtpbin);
3061       g_value_set_int (value, rtpbin->max_rtcp_rtp_time_diff);
3062       GST_RTP_BIN_UNLOCK (rtpbin);
3063       break;
3064     case PROP_MAX_DROPOUT_TIME:
3065       g_value_set_uint (value, rtpbin->max_dropout_time);
3066       break;
3067     case PROP_MAX_MISORDER_TIME:
3068       g_value_set_uint (value, rtpbin->max_misorder_time);
3069       break;
3070     case PROP_RFC7273_SYNC:
3071       g_value_set_boolean (value, rtpbin->rfc7273_sync);
3072       break;
3073     case PROP_MAX_STREAMS:
3074       g_value_set_uint (value, rtpbin->max_streams);
3075       break;
3076     case PROP_MAX_TS_OFFSET_ADJUSTMENT:
3077       g_value_set_uint64 (value, rtpbin->max_ts_offset_adjustment);
3078       break;
3079     case PROP_MAX_TS_OFFSET:
3080       g_value_set_int64 (value, rtpbin->max_ts_offset);
3081       break;
3082     default:
3083       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3084       break;
3085   }
3086 }
3087
3088 static void
3089 gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
3090 {
3091   GstRtpBin *rtpbin;
3092
3093   rtpbin = GST_RTP_BIN (bin);
3094
3095   switch (GST_MESSAGE_TYPE (message)) {
3096     case GST_MESSAGE_ELEMENT:
3097     {
3098       const GstStructure *s = gst_message_get_structure (message);
3099
3100       /* we change the structure name and add the session ID to it */
3101       if (gst_structure_has_name (s, "application/x-rtp-source-sdes")) {
3102         GstRtpBinSession *sess;
3103
3104         /* find the session we set it as object data */
3105         sess = g_object_get_data (G_OBJECT (GST_MESSAGE_SRC (message)),
3106             "GstRTPBin.session");
3107
3108         if (G_LIKELY (sess)) {
3109           message = gst_message_make_writable (message);
3110           s = gst_message_get_structure (message);
3111           gst_structure_set ((GstStructure *) s, "session", G_TYPE_UINT,
3112               sess->id, NULL);
3113         }
3114       }
3115       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
3116       break;
3117     }
3118     case GST_MESSAGE_BUFFERING:
3119     {
3120       gint percent;
3121       gint min_percent = 100;
3122       GSList *sessions, *streams;
3123       GstRtpBinStream *stream;
3124       gboolean change = FALSE, active = FALSE;
3125       GstClockTime min_out_time;
3126       GstBufferingMode mode;
3127       gint avg_in, avg_out;
3128       gint64 buffering_left;
3129
3130       gst_message_parse_buffering (message, &percent);
3131       gst_message_parse_buffering_stats (message, &mode, &avg_in, &avg_out,
3132           &buffering_left);
3133
3134       stream =
3135           g_object_get_data (G_OBJECT (GST_MESSAGE_SRC (message)),
3136           "GstRTPBin.stream");
3137
3138       GST_DEBUG_OBJECT (bin, "got percent %d from stream %p", percent, stream);
3139
3140       /* get the stream */
3141       if (G_LIKELY (stream)) {
3142         GST_RTP_BIN_LOCK (rtpbin);
3143         /* fill in the percent */
3144         stream->percent = percent;
3145
3146         /* calculate the min value for all streams */
3147         for (sessions = rtpbin->sessions; sessions;
3148             sessions = g_slist_next (sessions)) {
3149           GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
3150
3151           GST_RTP_SESSION_LOCK (session);
3152           if (session->streams) {
3153             for (streams = session->streams; streams;
3154                 streams = g_slist_next (streams)) {
3155               GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
3156
3157               GST_DEBUG_OBJECT (bin, "stream %p percent %d", stream,
3158                   stream->percent);
3159
3160               /* find min percent */
3161               if (min_percent > stream->percent)
3162                 min_percent = stream->percent;
3163             }
3164           } else {
3165             GST_INFO_OBJECT (bin,
3166                 "session has no streams, setting min_percent to 0");
3167             min_percent = 0;
3168           }
3169           GST_RTP_SESSION_UNLOCK (session);
3170         }
3171         GST_DEBUG_OBJECT (bin, "min percent %d", min_percent);
3172
3173         if (rtpbin->buffering) {
3174           if (min_percent == 100) {
3175             rtpbin->buffering = FALSE;
3176             active = TRUE;
3177             change = TRUE;
3178           }
3179         } else {
3180           if (min_percent < 100) {
3181             /* pause the streams */
3182             rtpbin->buffering = TRUE;
3183             active = FALSE;
3184             change = TRUE;
3185           }
3186         }
3187         GST_RTP_BIN_UNLOCK (rtpbin);
3188
3189         gst_message_unref (message);
3190
3191         /* make a new buffering message with the min value */
3192         message =
3193             gst_message_new_buffering (GST_OBJECT_CAST (bin), min_percent);
3194         gst_message_set_buffering_stats (message, mode, avg_in, avg_out,
3195             buffering_left);
3196
3197         if (G_UNLIKELY (change)) {
3198           GstClock *clock;
3199           guint64 running_time = 0;
3200           guint64 offset = 0;
3201
3202           /* figure out the running time when we have a clock */
3203           if (G_LIKELY ((clock =
3204                       gst_element_get_clock (GST_ELEMENT_CAST (bin))))) {
3205             guint64 now, base_time;
3206
3207             now = gst_clock_get_time (clock);
3208             base_time = gst_element_get_base_time (GST_ELEMENT_CAST (bin));
3209             running_time = now - base_time;
3210             gst_object_unref (clock);
3211           }
3212           GST_DEBUG_OBJECT (bin,
3213               "running time now %" GST_TIME_FORMAT,
3214               GST_TIME_ARGS (running_time));
3215
3216           GST_RTP_BIN_LOCK (rtpbin);
3217
3218           /* when we reactivate, calculate the offsets so that all streams have
3219            * an output time that is at least as big as the running_time */
3220           offset = 0;
3221           if (active) {
3222             if (running_time > rtpbin->buffer_start) {
3223               offset = running_time - rtpbin->buffer_start;
3224               if (offset >= rtpbin->latency_ns)
3225                 offset -= rtpbin->latency_ns;
3226               else
3227                 offset = 0;
3228             }
3229           }
3230
3231           /* pause all streams */
3232           min_out_time = -1;
3233           for (sessions = rtpbin->sessions; sessions;
3234               sessions = g_slist_next (sessions)) {
3235             GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
3236
3237             GST_RTP_SESSION_LOCK (session);
3238             for (streams = session->streams; streams;
3239                 streams = g_slist_next (streams)) {
3240               GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
3241               GstElement *element = stream->buffer;
3242               guint64 last_out;
3243
3244               g_signal_emit_by_name (element, "set-active", active, offset,
3245                   &last_out);
3246
3247               if (!active) {
3248                 g_object_get (element, "percent", &stream->percent, NULL);
3249
3250                 if (last_out == -1)
3251                   last_out = 0;
3252                 if (min_out_time == -1 || last_out < min_out_time)
3253                   min_out_time = last_out;
3254               }
3255
3256               GST_DEBUG_OBJECT (bin,
3257                   "setting %p to %d, offset %" GST_TIME_FORMAT ", last %"
3258                   GST_TIME_FORMAT ", percent %d", element, active,
3259                   GST_TIME_ARGS (offset), GST_TIME_ARGS (last_out),
3260                   stream->percent);
3261             }
3262             GST_RTP_SESSION_UNLOCK (session);
3263           }
3264           GST_DEBUG_OBJECT (bin,
3265               "min out time %" GST_TIME_FORMAT, GST_TIME_ARGS (min_out_time));
3266
3267           /* the buffer_start is the min out time of all paused jitterbuffers */
3268           if (!active)
3269             rtpbin->buffer_start = min_out_time;
3270
3271           GST_RTP_BIN_UNLOCK (rtpbin);
3272         }
3273       }
3274       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
3275       break;
3276     }
3277     default:
3278     {
3279       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
3280       break;
3281     }
3282   }
3283 }
3284
3285 static GstStateChangeReturn
3286 gst_rtp_bin_change_state (GstElement * element, GstStateChange transition)
3287 {
3288   GstStateChangeReturn res;
3289   GstRtpBin *rtpbin;
3290   GstRtpBinPrivate *priv;
3291
3292   rtpbin = GST_RTP_BIN (element);
3293   priv = rtpbin->priv;
3294
3295   switch (transition) {
3296     case GST_STATE_CHANGE_NULL_TO_READY:
3297       break;
3298     case GST_STATE_CHANGE_READY_TO_PAUSED:
3299       priv->last_ntpnstime = 0;
3300       GST_LOG_OBJECT (rtpbin, "clearing shutdown flag");
3301       g_atomic_int_set (&priv->shutdown, 0);
3302       break;
3303     case GST_STATE_CHANGE_PAUSED_TO_READY:
3304       GST_LOG_OBJECT (rtpbin, "setting shutdown flag");
3305       g_atomic_int_set (&priv->shutdown, 1);
3306       /* wait for all callbacks to end by taking the lock. No new callbacks will
3307        * be able to happen as we set the shutdown flag. */
3308       GST_RTP_BIN_DYN_LOCK (rtpbin);
3309       GST_LOG_OBJECT (rtpbin, "dynamic lock taken, we can continue shutdown");
3310       GST_RTP_BIN_DYN_UNLOCK (rtpbin);
3311       break;
3312     default:
3313       break;
3314   }
3315
3316   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
3317
3318   switch (transition) {
3319     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
3320       break;
3321     case GST_STATE_CHANGE_PAUSED_TO_READY:
3322       break;
3323     case GST_STATE_CHANGE_READY_TO_NULL:
3324       break;
3325     default:
3326       break;
3327   }
3328   return res;
3329 }
3330
3331 static GstElement *
3332 session_request_element (GstRtpBinSession * session, guint signal)
3333 {
3334   GstElement *element = NULL;
3335   GstRtpBin *bin = session->bin;
3336
3337   g_signal_emit (bin, gst_rtp_bin_signals[signal], 0, session->id, &element);
3338
3339   if (element) {
3340     if (!bin_manage_element (bin, element))
3341       goto manage_failed;
3342     session->elements = g_slist_prepend (session->elements, element);
3343   }
3344   return element;
3345
3346   /* ERRORS */
3347 manage_failed:
3348   {
3349     GST_WARNING_OBJECT (bin, "unable to manage element");
3350     gst_object_unref (element);
3351     return NULL;
3352   }
3353 }
3354
3355 static gboolean
3356 copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
3357 {
3358   GstPad *gpad = GST_PAD_CAST (user_data);
3359
3360   GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
3361   gst_pad_store_sticky_event (gpad, *event);
3362
3363   return TRUE;
3364 }
3365
3366 /* a new pad (SSRC) was created in @session. This signal is emited from the
3367  * payload demuxer. */
3368 static void
3369 new_payload_found (GstElement * element, guint pt, GstPad * pad,
3370     GstRtpBinStream * stream)
3371 {
3372   GstRtpBin *rtpbin;
3373   GstElementClass *klass;
3374   GstPadTemplate *templ;
3375   gchar *padname;
3376   GstPad *gpad;
3377
3378   rtpbin = stream->bin;
3379
3380   GST_DEBUG_OBJECT (rtpbin, "new payload pad %u", pt);
3381
3382   pad = gst_object_ref (pad);
3383
3384   if (stream->session->storage) {
3385     GstElement *fec_decoder =
3386         session_request_element (stream->session, SIGNAL_REQUEST_FEC_DECODER);
3387
3388     if (fec_decoder) {
3389       GstPad *sinkpad, *srcpad;
3390       GstPadLinkReturn ret;
3391
3392       sinkpad = gst_element_get_static_pad (fec_decoder, "sink");
3393
3394       if (!sinkpad)
3395         goto fec_decoder_sink_failed;
3396
3397       ret = gst_pad_link (pad, sinkpad);
3398       gst_object_unref (sinkpad);
3399
3400       if (ret != GST_PAD_LINK_OK)
3401         goto fec_decoder_link_failed;
3402
3403       srcpad = gst_element_get_static_pad (fec_decoder, "src");
3404
3405       if (!srcpad)
3406         goto fec_decoder_src_failed;
3407
3408       gst_pad_sticky_events_foreach (pad, copy_sticky_events, srcpad);
3409       gst_object_unref (pad);
3410       pad = srcpad;
3411     }
3412   }
3413
3414   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
3415
3416   /* ghost the pad to the parent */
3417   klass = GST_ELEMENT_GET_CLASS (rtpbin);
3418   templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%u_%u_%u");
3419   padname = g_strdup_printf ("recv_rtp_src_%u_%u_%u",
3420       stream->session->id, stream->ssrc, pt);
3421   gpad = gst_ghost_pad_new_from_template (padname, pad, templ);
3422   g_free (padname);
3423   g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", gpad);
3424
3425   gst_pad_set_active (gpad, TRUE);
3426   GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
3427
3428   gst_pad_sticky_events_foreach (pad, copy_sticky_events, gpad);
3429   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad);
3430
3431 done:
3432   gst_object_unref (pad);
3433
3434   return;
3435
3436 shutdown:
3437   {
3438     GST_DEBUG ("ignoring, we are shutting down");
3439     goto done;
3440   }
3441 fec_decoder_sink_failed:
3442   {
3443     g_warning ("rtpbin: failed to get fec encoder sink pad for session %u",
3444         stream->session->id);
3445     goto done;
3446   }
3447 fec_decoder_src_failed:
3448   {
3449     g_warning ("rtpbin: failed to get fec encoder src pad for session %u",
3450         stream->session->id);
3451     goto done;
3452   }
3453 fec_decoder_link_failed:
3454   {
3455     g_warning ("rtpbin: failed to link fec decoder for session %u",
3456         stream->session->id);
3457     goto done;
3458   }
3459 }
3460
3461 static void
3462 payload_pad_removed (GstElement * element, GstPad * pad,
3463     GstRtpBinStream * stream)
3464 {
3465   GstRtpBin *rtpbin;
3466   GstPad *gpad;
3467
3468   rtpbin = stream->bin;
3469
3470   GST_DEBUG ("payload pad removed");
3471
3472   GST_RTP_BIN_DYN_LOCK (rtpbin);
3473   if ((gpad = g_object_get_data (G_OBJECT (pad), "GstRTPBin.ghostpad"))) {
3474     g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", NULL);
3475
3476     gst_pad_set_active (gpad, FALSE);
3477     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), gpad);
3478   }
3479   GST_RTP_BIN_DYN_UNLOCK (rtpbin);
3480 }
3481
3482 static GstCaps *
3483 pt_map_requested (GstElement * element, guint pt, GstRtpBinSession * session)
3484 {
3485   GstRtpBin *rtpbin;
3486   GstCaps *caps;
3487
3488   rtpbin = session->bin;
3489
3490   GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %u in session %u", pt,
3491       session->id);
3492
3493   caps = get_pt_map (session, pt);
3494   if (!caps)
3495     goto no_caps;
3496
3497   return caps;
3498
3499   /* ERRORS */
3500 no_caps:
3501   {
3502     GST_DEBUG_OBJECT (rtpbin, "could not get caps");
3503     return NULL;
3504   }
3505 }
3506
3507 static GstCaps *
3508 ptdemux_pt_map_requested (GstElement * element, guint pt,
3509     GstRtpBinSession * session)
3510 {
3511   GstCaps *ret = pt_map_requested (element, pt, session);
3512
3513   if (ret && gst_caps_get_size (ret) == 1) {
3514     const GstStructure *s = gst_caps_get_structure (ret, 0);
3515     gboolean is_fec;
3516
3517     if (gst_structure_get_boolean (s, "is-fec", &is_fec) && is_fec) {
3518       GValue v = G_VALUE_INIT;
3519       GValue v2 = G_VALUE_INIT;
3520
3521       GST_INFO_OBJECT (session->bin, "Will ignore FEC pt %u in session %u", pt,
3522           session->id);
3523       g_value_init (&v, GST_TYPE_ARRAY);
3524       g_value_init (&v2, G_TYPE_INT);
3525       g_object_get_property (G_OBJECT (element), "ignored-payload-types", &v);
3526       g_value_set_int (&v2, pt);
3527       gst_value_array_append_value (&v, &v2);
3528       g_value_unset (&v2);
3529       g_object_set_property (G_OBJECT (element), "ignored-payload-types", &v);
3530       g_value_unset (&v);
3531     }
3532   }
3533
3534   return ret;
3535 }
3536
3537 static void
3538 payload_type_change (GstElement * element, guint pt, GstRtpBinSession * session)
3539 {
3540   GST_DEBUG_OBJECT (session->bin,
3541       "emiting signal for pt type changed to %u in session %u", pt,
3542       session->id);
3543
3544   g_signal_emit (session->bin, gst_rtp_bin_signals[SIGNAL_PAYLOAD_TYPE_CHANGE],
3545       0, session->id, pt);
3546 }
3547
3548 /* emited when caps changed for the session */
3549 static void
3550 caps_changed (GstPad * pad, GParamSpec * pspec, GstRtpBinSession * session)
3551 {
3552   GstRtpBin *bin;
3553   GstCaps *caps;
3554   gint payload;
3555   const GstStructure *s;
3556
3557   bin = session->bin;
3558
3559   g_object_get (pad, "caps", &caps, NULL);
3560
3561   if (caps == NULL)
3562     return;
3563
3564   GST_DEBUG_OBJECT (bin, "got caps %" GST_PTR_FORMAT, caps);
3565
3566   s = gst_caps_get_structure (caps, 0);
3567
3568   /* get payload, finish when it's not there */
3569   if (!gst_structure_get_int (s, "payload", &payload)) {
3570     gst_caps_unref (caps);
3571     return;
3572   }
3573
3574   GST_RTP_SESSION_LOCK (session);
3575   GST_DEBUG_OBJECT (bin, "insert caps for payload %d", payload);
3576   g_hash_table_insert (session->ptmap, GINT_TO_POINTER (payload), caps);
3577   GST_RTP_SESSION_UNLOCK (session);
3578 }
3579
3580 /* a new pad (SSRC) was created in @session */
3581 static void
3582 new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
3583     GstRtpBinSession * session)
3584 {
3585   GstRtpBin *rtpbin;
3586   GstRtpBinStream *stream;
3587   GstPad *sinkpad, *srcpad;
3588   gchar *padname;
3589
3590   rtpbin = session->bin;
3591
3592   GST_DEBUG_OBJECT (rtpbin, "new SSRC pad %08x, %s:%s", ssrc,
3593       GST_DEBUG_PAD_NAME (pad));
3594
3595   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
3596
3597   GST_RTP_SESSION_LOCK (session);
3598
3599   /* create new stream */
3600   stream = create_stream (session, ssrc);
3601   if (!stream)
3602     goto no_stream;
3603
3604   /* get pad and link */
3605   GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTP");
3606   padname = g_strdup_printf ("src_%u", ssrc);
3607   srcpad = gst_element_get_static_pad (element, padname);
3608   g_free (padname);
3609   sinkpad = gst_element_get_static_pad (stream->buffer, "sink");
3610   gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_NOTHING);
3611   gst_object_unref (sinkpad);
3612   gst_object_unref (srcpad);
3613
3614   GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTCP");
3615   padname = g_strdup_printf ("rtcp_src_%u", ssrc);
3616   srcpad = gst_element_get_static_pad (element, padname);
3617   g_free (padname);
3618   sinkpad = gst_element_get_request_pad (stream->buffer, "sink_rtcp");
3619   gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_NOTHING);
3620   gst_object_unref (sinkpad);
3621   gst_object_unref (srcpad);
3622
3623   /* connect to the RTCP sync signal from the jitterbuffer */
3624   GST_DEBUG_OBJECT (rtpbin, "connecting sync signal");
3625   stream->buffer_handlesync_sig = g_signal_connect (stream->buffer,
3626       "handle-sync", (GCallback) gst_rtp_bin_handle_sync, stream);
3627
3628   if (stream->demux) {
3629     /* connect to the new-pad signal of the payload demuxer, this will expose the
3630      * new pad by ghosting it. */
3631     stream->demux_newpad_sig = g_signal_connect (stream->demux,
3632         "new-payload-type", (GCallback) new_payload_found, stream);
3633     stream->demux_padremoved_sig = g_signal_connect (stream->demux,
3634         "pad-removed", (GCallback) payload_pad_removed, stream);
3635
3636     /* connect to the request-pt-map signal. This signal will be emited by the
3637      * demuxer so that it can apply a proper caps on the buffers for the
3638      * depayloaders. */
3639     stream->demux_ptreq_sig = g_signal_connect (stream->demux,
3640         "request-pt-map", (GCallback) ptdemux_pt_map_requested, session);
3641     /* connect to the  signal so it can be forwarded. */
3642     stream->demux_ptchange_sig = g_signal_connect (stream->demux,
3643         "payload-type-change", (GCallback) payload_type_change, session);
3644   } else {
3645     /* add rtpjitterbuffer src pad to pads */
3646     GstElementClass *klass;
3647     GstPadTemplate *templ;
3648     gchar *padname;
3649     GstPad *gpad, *pad;
3650
3651     pad = gst_element_get_static_pad (stream->buffer, "src");
3652
3653     /* ghost the pad to the parent */
3654     klass = GST_ELEMENT_GET_CLASS (rtpbin);
3655     templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%u_%u_%u");
3656     padname = g_strdup_printf ("recv_rtp_src_%u_%u_%u",
3657         stream->session->id, stream->ssrc, 255);
3658     gpad = gst_ghost_pad_new_from_template (padname, pad, templ);
3659     g_free (padname);
3660
3661     gst_pad_set_active (gpad, TRUE);
3662     gst_pad_sticky_events_foreach (pad, copy_sticky_events, gpad);
3663     gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad);
3664
3665     gst_object_unref (pad);
3666   }
3667
3668   GST_RTP_SESSION_UNLOCK (session);
3669   GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
3670
3671   return;
3672
3673   /* ERRORS */
3674 shutdown:
3675   {
3676     GST_DEBUG_OBJECT (rtpbin, "we are shutting down");
3677     return;
3678   }
3679 no_stream:
3680   {
3681     GST_RTP_SESSION_UNLOCK (session);
3682     GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
3683     GST_DEBUG_OBJECT (rtpbin, "could not create stream");
3684     return;
3685   }
3686 }
3687
3688 static void
3689 session_maybe_create_bundle_demuxer (GstRtpBinSession * session)
3690 {
3691   GstRtpBin *rtpbin;
3692
3693   if (session->bundle_demux)
3694     return;
3695
3696   rtpbin = session->bin;
3697   if (g_signal_has_handler_pending (rtpbin,
3698           gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC], 0, TRUE)) {
3699     GST_DEBUG_OBJECT (rtpbin, "Adding a bundle SSRC demuxer to session %u",
3700         session->id);
3701     session->bundle_demux = gst_element_factory_make ("rtpssrcdemux", NULL);
3702     session->bundle_demux_newpad_sig = g_signal_connect (session->bundle_demux,
3703         "new-ssrc-pad", (GCallback) new_bundled_ssrc_pad_found, session);
3704
3705     gst_bin_add (GST_BIN_CAST (rtpbin), session->bundle_demux);
3706     gst_element_sync_state_with_parent (session->bundle_demux);
3707   } else {
3708     GST_DEBUG_OBJECT (rtpbin,
3709         "No handler for the on-bundled-ssrc signal so no need for a bundle SSRC demuxer in session %u",
3710         session->id);
3711   }
3712 }
3713
3714 static GstPad *
3715 complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session,
3716     gboolean bundle_demuxer_needed)
3717 {
3718   guint sessid = session->id;
3719   GstPad *recv_rtp_sink;
3720   GstPad *funnel_src;
3721   GstElement *decoder;
3722
3723   g_assert (!session->recv_rtp_sink);
3724
3725   /* get recv_rtp pad and store */
3726   session->recv_rtp_sink =
3727       gst_element_get_request_pad (session->session, "recv_rtp_sink");
3728   if (session->recv_rtp_sink == NULL)
3729     goto pad_failed;
3730
3731   g_signal_connect (session->recv_rtp_sink, "notify::caps",
3732       (GCallback) caps_changed, session);
3733
3734   if (bundle_demuxer_needed)
3735     session_maybe_create_bundle_demuxer (session);
3736
3737   GST_DEBUG_OBJECT (rtpbin, "requesting RTP decoder");
3738   decoder = session_request_element (session, SIGNAL_REQUEST_RTP_DECODER);
3739   if (decoder) {
3740     GstPad *decsrc, *decsink;
3741     GstPadLinkReturn ret;
3742
3743     GST_DEBUG_OBJECT (rtpbin, "linking RTP decoder");
3744     decsink = gst_element_get_static_pad (decoder, "rtp_sink");
3745     if (decsink == NULL)
3746       goto dec_sink_failed;
3747
3748     recv_rtp_sink = decsink;
3749
3750     decsrc = gst_element_get_static_pad (decoder, "rtp_src");
3751     if (decsrc == NULL)
3752       goto dec_src_failed;
3753
3754     if (session->bundle_demux) {
3755       GstPad *demux_sink;
3756       demux_sink = gst_element_get_static_pad (session->bundle_demux, "sink");
3757       ret = gst_pad_link (decsrc, demux_sink);
3758       gst_object_unref (demux_sink);
3759     } else {
3760       ret = gst_pad_link (decsrc, session->recv_rtp_sink);
3761     }
3762     gst_object_unref (decsrc);
3763
3764     if (ret != GST_PAD_LINK_OK)
3765       goto dec_link_failed;
3766
3767   } else {
3768     GST_DEBUG_OBJECT (rtpbin, "no RTP decoder given");
3769     if (session->bundle_demux) {
3770       recv_rtp_sink =
3771           gst_element_get_static_pad (session->bundle_demux, "sink");
3772     } else {
3773       recv_rtp_sink =
3774           gst_element_get_request_pad (session->rtp_funnel, "sink_%u");
3775     }
3776   }
3777
3778   funnel_src = gst_element_get_static_pad (session->rtp_funnel, "src");
3779   gst_pad_link (funnel_src, session->recv_rtp_sink);
3780   gst_object_unref (funnel_src);
3781
3782   return recv_rtp_sink;
3783
3784   /* ERRORS */
3785 pad_failed:
3786   {
3787     g_warning ("rtpbin: failed to get session recv_rtp_sink pad");
3788     return NULL;
3789   }
3790 dec_sink_failed:
3791   {
3792     g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
3793     return NULL;
3794   }
3795 dec_src_failed:
3796   {
3797     g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
3798     gst_object_unref (recv_rtp_sink);
3799     return NULL;
3800   }
3801 dec_link_failed:
3802   {
3803     g_warning ("rtpbin: failed to link rtp decoder for session %u", sessid);
3804     gst_object_unref (recv_rtp_sink);
3805     return NULL;
3806   }
3807 }
3808
3809 static void
3810 complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session,
3811     guint sessid)
3812 {
3813   GstElement *aux;
3814   GstPad *recv_rtp_src;
3815
3816   g_assert (!session->recv_rtp_src);
3817
3818   session->recv_rtp_src =
3819       gst_element_get_static_pad (session->session, "recv_rtp_src");
3820   if (session->recv_rtp_src == NULL)
3821     goto pad_failed;
3822
3823   /* find out if we need AUX elements */
3824   aux = session_request_element (session, SIGNAL_REQUEST_AUX_RECEIVER);
3825   if (aux) {
3826     gchar *pname;
3827     GstPad *auxsink;
3828     GstPadLinkReturn ret;
3829
3830     GST_DEBUG_OBJECT (rtpbin, "linking AUX receiver");
3831
3832     pname = g_strdup_printf ("sink_%u", sessid);
3833     auxsink = gst_element_get_static_pad (aux, pname);
3834     g_free (pname);
3835     if (auxsink == NULL)
3836       goto aux_sink_failed;
3837
3838     ret = gst_pad_link (session->recv_rtp_src, auxsink);
3839     gst_object_unref (auxsink);
3840     if (ret != GST_PAD_LINK_OK)
3841       goto aux_link_failed;
3842
3843     /* this can be NULL when this AUX element is not to be linked any further */
3844     pname = g_strdup_printf ("src_%u", sessid);
3845     recv_rtp_src = gst_element_get_static_pad (aux, pname);
3846     g_free (pname);
3847   } else {
3848     recv_rtp_src = gst_object_ref (session->recv_rtp_src);
3849   }
3850
3851   /* Add a storage element if needed */
3852   if (recv_rtp_src && session->storage) {
3853     GstPadLinkReturn ret;
3854     GstPad *sinkpad = gst_element_get_static_pad (session->storage, "sink");
3855
3856     ret = gst_pad_link (recv_rtp_src, sinkpad);
3857
3858     gst_object_unref (sinkpad);
3859     gst_object_unref (recv_rtp_src);
3860
3861     if (ret != GST_PAD_LINK_OK)
3862       goto storage_link_failed;
3863
3864     recv_rtp_src = gst_element_get_static_pad (session->storage, "src");
3865   }
3866
3867   if (recv_rtp_src) {
3868     GstPad *sinkdpad;
3869
3870     GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTP sink pad");
3871     sinkdpad = gst_element_get_static_pad (session->demux, "sink");
3872     GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
3873     gst_pad_link_full (recv_rtp_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
3874     gst_object_unref (sinkdpad);
3875     gst_object_unref (recv_rtp_src);
3876
3877     /* connect to the new-ssrc-pad signal of the SSRC demuxer */
3878     session->demux_newpad_sig = g_signal_connect (session->demux,
3879         "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session);
3880     session->demux_padremoved_sig = g_signal_connect (session->demux,
3881         "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session);
3882   }
3883
3884   return;
3885
3886 pad_failed:
3887   {
3888     g_warning ("rtpbin: failed to get session recv_rtp_src pad");
3889     return;
3890   }
3891 aux_sink_failed:
3892   {
3893     g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
3894     return;
3895   }
3896 aux_link_failed:
3897   {
3898     g_warning ("rtpbin: failed to link AUX pad to session %u", sessid);
3899     return;
3900   }
3901 storage_link_failed:
3902   {
3903     g_warning ("rtpbin: failed to link storage");
3904     return;
3905   }
3906 }
3907
3908 /* Create a pad for receiving RTP for the session in @name. Must be called with
3909  * RTP_BIN_LOCK.
3910  */
3911 static GstPad *
3912 create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
3913 {
3914   guint sessid;
3915   GstRtpBinSession *session;
3916   GstPad *recv_rtp_sink;
3917
3918   /* first get the session number */
3919   if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
3920     goto no_name;
3921
3922   GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
3923
3924   /* get or create session */
3925   session = find_session_by_id (rtpbin, sessid);
3926   if (!session) {
3927     GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
3928     /* create session now */
3929     session = create_session (rtpbin, sessid);
3930     if (session == NULL)
3931       goto create_error;
3932   }
3933
3934   /* check if pad was requested */
3935   if (session->recv_rtp_sink_ghost != NULL)
3936     return session->recv_rtp_sink_ghost;
3937
3938   /* setup the session sink pad */
3939   recv_rtp_sink = complete_session_sink (rtpbin, session, TRUE);
3940   if (!recv_rtp_sink)
3941     goto session_sink_failed;
3942
3943
3944   GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
3945   session->recv_rtp_sink_ghost =
3946       gst_ghost_pad_new_from_template (name, recv_rtp_sink, templ);
3947   gst_object_unref (recv_rtp_sink);
3948   gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
3949   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
3950
3951   complete_session_receiver (rtpbin, session, sessid);
3952
3953   return session->recv_rtp_sink_ghost;
3954
3955   /* ERRORS */
3956 no_name:
3957   {
3958     g_warning ("rtpbin: invalid name given");
3959     return NULL;
3960   }
3961 create_error:
3962   {
3963     /* create_session already warned */
3964     return NULL;
3965   }
3966 session_sink_failed:
3967   {
3968     /* warning already done */
3969     return NULL;
3970   }
3971 }
3972
3973 static void
3974 remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
3975 {
3976   if (session->demux_newpad_sig) {
3977     g_signal_handler_disconnect (session->demux, session->demux_newpad_sig);
3978     session->demux_newpad_sig = 0;
3979   }
3980   if (session->demux_padremoved_sig) {
3981     g_signal_handler_disconnect (session->demux, session->demux_padremoved_sig);
3982     session->demux_padremoved_sig = 0;
3983   }
3984   if (session->bundle_demux_newpad_sig) {
3985     g_signal_handler_disconnect (session->bundle_demux,
3986         session->bundle_demux_newpad_sig);
3987     session->bundle_demux_newpad_sig = 0;
3988   }
3989   if (session->recv_rtp_src) {
3990     gst_object_unref (session->recv_rtp_src);
3991     session->recv_rtp_src = NULL;
3992   }
3993   if (session->recv_rtp_sink) {
3994     gst_element_release_request_pad (session->session, session->recv_rtp_sink);
3995     gst_object_unref (session->recv_rtp_sink);
3996     session->recv_rtp_sink = NULL;
3997   }
3998   if (session->recv_rtp_sink_ghost) {
3999     gst_pad_set_active (session->recv_rtp_sink_ghost, FALSE);
4000     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
4001         session->recv_rtp_sink_ghost);
4002     session->recv_rtp_sink_ghost = NULL;
4003   }
4004 }
4005
4006 static GstPad *
4007 complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session,
4008     guint sessid, gboolean bundle_demuxer_needed)
4009 {
4010   GstElement *decoder;
4011   GstPad *sinkdpad;
4012   GstPad *decsink = NULL;
4013   GstPad *funnel_src;
4014
4015   /* get recv_rtp pad and store */
4016   GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad");
4017   session->recv_rtcp_sink =
4018       gst_element_get_request_pad (session->session, "recv_rtcp_sink");
4019   if (session->recv_rtcp_sink == NULL)
4020     goto pad_failed;
4021
4022   if (bundle_demuxer_needed)
4023     session_maybe_create_bundle_demuxer (session);
4024
4025   GST_DEBUG_OBJECT (rtpbin, "getting RTCP decoder");
4026   decoder = session_request_element (session, SIGNAL_REQUEST_RTCP_DECODER);
4027   if (decoder) {
4028     GstPad *decsrc;
4029     GstPadLinkReturn ret;
4030
4031     GST_DEBUG_OBJECT (rtpbin, "linking RTCP decoder");
4032     decsink = gst_element_get_static_pad (decoder, "rtcp_sink");
4033     decsrc = gst_element_get_static_pad (decoder, "rtcp_src");
4034
4035     if (decsink == NULL)
4036       goto dec_sink_failed;
4037
4038     if (decsrc == NULL)
4039       goto dec_src_failed;
4040
4041     if (session->bundle_demux) {
4042       GstPad *demux_sink;
4043       demux_sink =
4044           gst_element_get_static_pad (session->bundle_demux, "rtcp_sink");
4045       ret = gst_pad_link (decsrc, demux_sink);
4046       gst_object_unref (demux_sink);
4047     } else {
4048       ret = gst_pad_link (decsrc, session->recv_rtcp_sink);
4049     }
4050     gst_object_unref (decsrc);
4051
4052     if (ret != GST_PAD_LINK_OK)
4053       goto dec_link_failed;
4054   } else {
4055     GST_DEBUG_OBJECT (rtpbin, "no RTCP decoder given");
4056     if (session->bundle_demux) {
4057       decsink = gst_element_get_static_pad (session->bundle_demux, "rtcp_sink");
4058     } else {
4059       decsink = gst_element_get_request_pad (session->rtcp_funnel, "sink_%u");
4060     }
4061   }
4062
4063   /* get srcpad, link to SSRCDemux */
4064   GST_DEBUG_OBJECT (rtpbin, "getting sync src pad");
4065   session->sync_src = gst_element_get_static_pad (session->session, "sync_src");
4066   if (session->sync_src == NULL)
4067     goto src_pad_failed;
4068
4069   GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTCP sink pad");
4070   sinkdpad = gst_element_get_static_pad (session->demux, "rtcp_sink");
4071   gst_pad_link_full (session->sync_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
4072   gst_object_unref (sinkdpad);
4073
4074   funnel_src = gst_element_get_static_pad (session->rtcp_funnel, "src");
4075   gst_pad_link (funnel_src, session->recv_rtcp_sink);
4076   gst_object_unref (funnel_src);
4077
4078   return decsink;
4079
4080 pad_failed:
4081   {
4082     g_warning ("rtpbin: failed to get session rtcp_sink pad");
4083     return NULL;
4084   }
4085 dec_sink_failed:
4086   {
4087     g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
4088     return NULL;
4089   }
4090 dec_src_failed:
4091   {
4092     g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
4093     goto cleanup;
4094   }
4095 dec_link_failed:
4096   {
4097     g_warning ("rtpbin: failed to link rtcp decoder for session %u", sessid);
4098     goto cleanup;
4099   }
4100 src_pad_failed:
4101   {
4102     g_warning ("rtpbin: failed to get session sync_src pad");
4103   }
4104
4105 cleanup:
4106   gst_object_unref (decsink);
4107   return NULL;
4108 }
4109
4110 /* Create a pad for receiving RTCP for the session in @name. Must be called with
4111  * RTP_BIN_LOCK.
4112  */
4113 static GstPad *
4114 create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
4115     const gchar * name)
4116 {
4117   guint sessid;
4118   GstRtpBinSession *session;
4119   GstPad *decsink = NULL;
4120
4121   /* first get the session number */
4122   if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1)
4123     goto no_name;
4124
4125   GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
4126
4127   /* get or create the session */
4128   session = find_session_by_id (rtpbin, sessid);
4129   if (!session) {
4130     GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
4131     /* create session now */
4132     session = create_session (rtpbin, sessid);
4133     if (session == NULL)
4134       goto create_error;
4135   }
4136
4137   /* check if pad was requested */
4138   if (session->recv_rtcp_sink_ghost != NULL)
4139     return session->recv_rtcp_sink_ghost;
4140
4141   decsink = complete_session_rtcp (rtpbin, session, sessid, TRUE);
4142   if (!decsink)
4143     goto create_error;
4144
4145   session->recv_rtcp_sink_ghost =
4146       gst_ghost_pad_new_from_template (name, decsink, templ);
4147   gst_object_unref (decsink);
4148   gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE);
4149   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin),
4150       session->recv_rtcp_sink_ghost);
4151
4152   return session->recv_rtcp_sink_ghost;
4153
4154   /* ERRORS */
4155 no_name:
4156   {
4157     g_warning ("rtpbin: invalid name given");
4158     return NULL;
4159   }
4160 create_error:
4161   {
4162     /* create_session already warned */
4163     return NULL;
4164   }
4165 }
4166
4167 static void
4168 remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session)
4169 {
4170   if (session->recv_rtcp_sink_ghost) {
4171     gst_pad_set_active (session->recv_rtcp_sink_ghost, FALSE);
4172     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
4173         session->recv_rtcp_sink_ghost);
4174     session->recv_rtcp_sink_ghost = NULL;
4175   }
4176   if (session->sync_src) {
4177     /* releasing the request pad should also unref the sync pad */
4178     gst_object_unref (session->sync_src);
4179     session->sync_src = NULL;
4180   }
4181   if (session->recv_rtcp_sink) {
4182     gst_element_release_request_pad (session->session, session->recv_rtcp_sink);
4183     gst_object_unref (session->recv_rtcp_sink);
4184     session->recv_rtcp_sink = NULL;
4185   }
4186 }
4187
4188 static gboolean
4189 complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
4190 {
4191   gchar *gname;
4192   guint sessid = session->id;
4193   GstPad *send_rtp_src;
4194   GstElement *encoder;
4195   GstElementClass *klass;
4196   GstPadTemplate *templ;
4197   gboolean ret = FALSE;
4198
4199   /* get srcpad */
4200   send_rtp_src = gst_element_get_static_pad (session->session, "send_rtp_src");
4201
4202   if (send_rtp_src == NULL)
4203     goto no_srcpad;
4204
4205   GST_DEBUG_OBJECT (rtpbin, "getting RTP encoder");
4206   encoder = session_request_element (session, SIGNAL_REQUEST_RTP_ENCODER);
4207   if (encoder) {
4208     gchar *ename;
4209     GstPad *encsrc, *encsink;
4210     GstPadLinkReturn ret;
4211
4212     GST_DEBUG_OBJECT (rtpbin, "linking RTP encoder");
4213     ename = g_strdup_printf ("rtp_src_%u", sessid);
4214     encsrc = gst_element_get_static_pad (encoder, ename);
4215     g_free (ename);
4216
4217     if (encsrc == NULL)
4218       goto enc_src_failed;
4219
4220     ename = g_strdup_printf ("rtp_sink_%u", sessid);
4221     encsink = gst_element_get_static_pad (encoder, ename);
4222     g_free (ename);
4223     if (encsink == NULL)
4224       goto enc_sink_failed;
4225
4226     ret = gst_pad_link (send_rtp_src, encsink);
4227     gst_object_unref (encsink);
4228     gst_object_unref (send_rtp_src);
4229
4230     send_rtp_src = encsrc;
4231
4232     if (ret != GST_PAD_LINK_OK)
4233       goto enc_link_failed;
4234   } else {
4235     GST_DEBUG_OBJECT (rtpbin, "no RTP encoder given");
4236   }
4237
4238   /* ghost the new source pad */
4239   klass = GST_ELEMENT_GET_CLASS (rtpbin);
4240   gname = g_strdup_printf ("send_rtp_src_%u", sessid);
4241   templ = gst_element_class_get_pad_template (klass, "send_rtp_src_%u");
4242   session->send_rtp_src_ghost =
4243       gst_ghost_pad_new_from_template (gname, send_rtp_src, templ);
4244   gst_pad_set_active (session->send_rtp_src_ghost, TRUE);
4245   gst_pad_sticky_events_foreach (send_rtp_src, copy_sticky_events,
4246       session->send_rtp_src_ghost);
4247   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_src_ghost);
4248   g_free (gname);
4249
4250   ret = TRUE;
4251
4252 done:
4253   if (send_rtp_src)
4254     gst_object_unref (send_rtp_src);
4255
4256   return ret;
4257
4258   /* ERRORS */
4259 no_srcpad:
4260   {
4261     g_warning ("rtpbin: failed to get rtp source pad for session %u", sessid);
4262     goto done;
4263   }
4264 enc_src_failed:
4265   {
4266     g_warning ("rtpbin: failed to get %" GST_PTR_FORMAT
4267         " src pad for session %u", encoder, sessid);
4268     goto done;
4269   }
4270 enc_sink_failed:
4271   {
4272     g_warning ("rtpbin: failed to get %" GST_PTR_FORMAT
4273         " sink pad for session %u", encoder, sessid);
4274     goto done;
4275   }
4276 enc_link_failed:
4277   {
4278     g_warning ("rtpbin: failed to link %" GST_PTR_FORMAT " for session %u",
4279         encoder, sessid);
4280     goto done;
4281   }
4282 }
4283
4284 static gboolean
4285 setup_aux_sender_fold (const GValue * item, GValue * result, gpointer user_data)
4286 {
4287   GstPad *pad;
4288   gchar *name;
4289   guint sessid;
4290   GstRtpBinSession *session = user_data, *newsess;
4291   GstRtpBin *rtpbin = session->bin;
4292   GstPadLinkReturn ret;
4293
4294   pad = g_value_get_object (item);
4295   name = gst_pad_get_name (pad);
4296
4297   if (name == NULL || sscanf (name, "src_%u", &sessid) != 1)
4298     goto no_name;
4299
4300   g_free (name);
4301
4302   newsess = find_session_by_id (rtpbin, sessid);
4303   if (newsess == NULL) {
4304     /* create new session */
4305     newsess = create_session (rtpbin, sessid);
4306     if (newsess == NULL)
4307       goto create_error;
4308   } else if (newsess->send_rtp_sink != NULL)
4309     goto existing_session;
4310
4311   /* get send_rtp pad and store */
4312   newsess->send_rtp_sink =
4313       gst_element_get_request_pad (newsess->session, "send_rtp_sink");
4314   if (newsess->send_rtp_sink == NULL)
4315     goto pad_failed;
4316
4317   ret = gst_pad_link (pad, newsess->send_rtp_sink);
4318   if (ret != GST_PAD_LINK_OK)
4319     goto aux_link_failed;
4320
4321   if (!complete_session_src (rtpbin, newsess))
4322     goto session_src_failed;
4323
4324   return TRUE;
4325
4326   /* ERRORS */
4327 no_name:
4328   {
4329     GST_WARNING ("ignoring invalid pad name %s", GST_STR_NULL (name));
4330     g_free (name);
4331     return TRUE;
4332   }
4333 create_error:
4334   {
4335     /* create_session already warned */
4336     return FALSE;
4337   }
4338 existing_session:
4339   {
4340     g_warning ("rtpbin: session %u is already a sender", sessid);
4341     return FALSE;
4342   }
4343 pad_failed:
4344   {
4345     g_warning ("rtpbin: failed to get session pad for session %u", sessid);
4346     return FALSE;
4347   }
4348 aux_link_failed:
4349   {
4350     g_warning ("rtpbin: failed to link AUX for session %u", sessid);
4351     return FALSE;
4352   }
4353 session_src_failed:
4354   {
4355     g_warning ("rtpbin: failed to complete AUX for session %u", sessid);
4356     return FALSE;
4357   }
4358 }
4359
4360 static gboolean
4361 setup_aux_sender (GstRtpBin * rtpbin, GstRtpBinSession * session,
4362     GstElement * aux)
4363 {
4364   GstIterator *it;
4365   GValue result = { 0, };
4366   GstIteratorResult res;
4367
4368   it = gst_element_iterate_src_pads (aux);
4369   res = gst_iterator_fold (it, setup_aux_sender_fold, &result, session);
4370   gst_iterator_free (it);
4371
4372   return res == GST_ITERATOR_DONE;
4373 }
4374
4375 /* Create a pad for sending RTP for the session in @name. Must be called with
4376  * RTP_BIN_LOCK.
4377  */
4378 static GstPad *
4379 create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
4380 {
4381   gchar *pname;
4382   guint sessid;
4383   GstPad *send_rtp_sink;
4384   GstElement *aux;
4385   GstElement *encoder;
4386   GstElement *prev = NULL;
4387   GstRtpBinSession *session;
4388
4389   /* first get the session number */
4390   if (name == NULL || sscanf (name, "send_rtp_sink_%u", &sessid) != 1)
4391     goto no_name;
4392
4393   /* get or create session */
4394   session = find_session_by_id (rtpbin, sessid);
4395   if (!session) {
4396     /* create session now */
4397     session = create_session (rtpbin, sessid);
4398     if (session == NULL)
4399       goto create_error;
4400   }
4401
4402   /* check if pad was requested */
4403   if (session->send_rtp_sink_ghost != NULL)
4404     return session->send_rtp_sink_ghost;
4405
4406   /* check if we are already using this session as a sender */
4407   if (session->send_rtp_sink != NULL)
4408     goto existing_session;
4409
4410   encoder = session_request_element (session, SIGNAL_REQUEST_FEC_ENCODER);
4411
4412   if (encoder) {
4413     GST_DEBUG_OBJECT (rtpbin, "Linking FEC encoder");
4414
4415     send_rtp_sink = gst_element_get_static_pad (encoder, "sink");
4416
4417     if (!send_rtp_sink)
4418       goto enc_sink_failed;
4419
4420     prev = encoder;
4421   }
4422
4423   GST_DEBUG_OBJECT (rtpbin, "getting RTP AUX sender");
4424   aux = session_request_element (session, SIGNAL_REQUEST_AUX_SENDER);
4425   if (aux) {
4426     GstPad *sinkpad;
4427     GST_DEBUG_OBJECT (rtpbin, "linking AUX sender");
4428     if (!setup_aux_sender (rtpbin, session, aux))
4429       goto aux_session_failed;
4430
4431     pname = g_strdup_printf ("sink_%u", sessid);
4432     sinkpad = gst_element_get_static_pad (aux, pname);
4433     g_free (pname);
4434
4435     if (sinkpad == NULL)
4436       goto aux_sink_failed;
4437
4438     if (!prev) {
4439       send_rtp_sink = sinkpad;
4440     } else {
4441       GstPad *srcpad = gst_element_get_static_pad (prev, "src");
4442       GstPadLinkReturn ret;
4443
4444       ret = gst_pad_link (srcpad, sinkpad);
4445       gst_object_unref (srcpad);
4446       if (ret != GST_PAD_LINK_OK) {
4447         goto aux_link_failed;
4448       }
4449     }
4450     prev = aux;
4451   } else {
4452     /* get send_rtp pad and store */
4453     session->send_rtp_sink =
4454         gst_element_get_request_pad (session->session, "send_rtp_sink");
4455     if (session->send_rtp_sink == NULL)
4456       goto pad_failed;
4457
4458     if (!complete_session_src (rtpbin, session))
4459       goto session_src_failed;
4460
4461     if (!prev) {
4462       send_rtp_sink = gst_object_ref (session->send_rtp_sink);
4463     } else {
4464       GstPad *srcpad = gst_element_get_static_pad (prev, "src");
4465       GstPadLinkReturn ret;
4466
4467       ret = gst_pad_link (srcpad, session->send_rtp_sink);
4468       gst_object_unref (srcpad);
4469       if (ret != GST_PAD_LINK_OK)
4470         goto session_link_failed;
4471     }
4472   }
4473
4474   session->send_rtp_sink_ghost =
4475       gst_ghost_pad_new_from_template (name, send_rtp_sink, templ);
4476   gst_object_unref (send_rtp_sink);
4477   gst_pad_set_active (session->send_rtp_sink_ghost, TRUE);
4478   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_sink_ghost);
4479
4480   return session->send_rtp_sink_ghost;
4481
4482   /* ERRORS */
4483 no_name:
4484   {
4485     g_warning ("rtpbin: invalid name given");
4486     return NULL;
4487   }
4488 create_error:
4489   {
4490     /* create_session already warned */
4491     return NULL;
4492   }
4493 existing_session:
4494   {
4495     g_warning ("rtpbin: session %u is already in use", sessid);
4496     return NULL;
4497   }
4498 aux_session_failed:
4499   {
4500     g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
4501     return NULL;
4502   }
4503 aux_sink_failed:
4504   {
4505     g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
4506     return NULL;
4507   }
4508 aux_link_failed:
4509   {
4510     g_warning ("rtpbin: failed to link %" GST_PTR_FORMAT " for session %u",
4511         aux, sessid);
4512     return NULL;
4513   }
4514 pad_failed:
4515   {
4516     g_warning ("rtpbin: failed to get session pad for session %u", sessid);
4517     return NULL;
4518   }
4519 session_src_failed:
4520   {
4521     g_warning ("rtpbin: failed to setup source pads for session %u", sessid);
4522     return NULL;
4523   }
4524 session_link_failed:
4525   {
4526     g_warning ("rtpbin: failed to link %" GST_PTR_FORMAT " for session %u",
4527         session, sessid);
4528     return NULL;
4529   }
4530 enc_sink_failed:
4531   {
4532     g_warning ("rtpbin: failed to get %" GST_PTR_FORMAT
4533         " sink pad for session %u", encoder, sessid);
4534     return NULL;
4535   }
4536 }
4537
4538 static void
4539 remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
4540 {
4541   if (session->send_rtp_src_ghost) {
4542     gst_pad_set_active (session->send_rtp_src_ghost, FALSE);
4543     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
4544         session->send_rtp_src_ghost);
4545     session->send_rtp_src_ghost = NULL;
4546   }
4547   if (session->send_rtp_sink) {
4548     gst_element_release_request_pad (GST_ELEMENT_CAST (session->session),
4549         session->send_rtp_sink);
4550     gst_object_unref (session->send_rtp_sink);
4551     session->send_rtp_sink = NULL;
4552   }
4553   if (session->send_rtp_sink_ghost) {
4554     gst_pad_set_active (session->send_rtp_sink_ghost, FALSE);
4555     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
4556         session->send_rtp_sink_ghost);
4557     session->send_rtp_sink_ghost = NULL;
4558   }
4559 }
4560
4561 /* Create a pad for sending RTCP for the session in @name. Must be called with
4562  * RTP_BIN_LOCK.
4563  */
4564 static GstPad *
4565 create_send_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
4566     const gchar * name)
4567 {
4568   guint sessid;
4569   GstPad *encsrc;
4570   GstElement *encoder;
4571   GstRtpBinSession *session;
4572
4573   /* first get the session number */
4574   if (name == NULL || sscanf (name, "send_rtcp_src_%u", &sessid) != 1)
4575     goto no_name;
4576
4577   /* get or create session */
4578   session = find_session_by_id (rtpbin, sessid);
4579   if (!session) {
4580     GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
4581     /* create session now */
4582     session = create_session (rtpbin, sessid);
4583     if (session == NULL)
4584       goto create_error;
4585   }
4586
4587   /* check if pad was requested */
4588   if (session->send_rtcp_src_ghost != NULL)
4589     return session->send_rtcp_src_ghost;
4590
4591   /* get rtcp_src pad and store */
4592   session->send_rtcp_src =
4593       gst_element_get_request_pad (session->session, "send_rtcp_src");
4594   if (session->send_rtcp_src == NULL)
4595     goto pad_failed;
4596
4597   GST_DEBUG_OBJECT (rtpbin, "getting RTCP encoder");
4598   encoder = session_request_element (session, SIGNAL_REQUEST_RTCP_ENCODER);
4599   if (encoder) {
4600     gchar *ename;
4601     GstPad *encsink;
4602     GstPadLinkReturn ret;
4603
4604     GST_DEBUG_OBJECT (rtpbin, "linking RTCP encoder");
4605
4606     ename = g_strdup_printf ("rtcp_src_%u", sessid);
4607     encsrc = gst_element_get_static_pad (encoder, ename);
4608     g_free (ename);
4609     if (encsrc == NULL)
4610       goto enc_src_failed;
4611
4612     ename = g_strdup_printf ("rtcp_sink_%u", sessid);
4613     encsink = gst_element_get_static_pad (encoder, ename);
4614     g_free (ename);
4615     if (encsink == NULL)
4616       goto enc_sink_failed;
4617
4618     ret = gst_pad_link (session->send_rtcp_src, encsink);
4619     gst_object_unref (encsink);
4620
4621     if (ret != GST_PAD_LINK_OK)
4622       goto enc_link_failed;
4623   } else {
4624     GST_DEBUG_OBJECT (rtpbin, "no RTCP encoder given");
4625     encsrc = gst_object_ref (session->send_rtcp_src);
4626   }
4627
4628   session->send_rtcp_src_ghost =
4629       gst_ghost_pad_new_from_template (name, encsrc, templ);
4630   gst_object_unref (encsrc);
4631   gst_pad_set_active (session->send_rtcp_src_ghost, TRUE);
4632   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtcp_src_ghost);
4633
4634   return session->send_rtcp_src_ghost;
4635
4636   /* ERRORS */
4637 no_name:
4638   {
4639     g_warning ("rtpbin: invalid name given");
4640     return NULL;
4641   }
4642 create_error:
4643   {
4644     /* create_session already warned */
4645     return NULL;
4646   }
4647 pad_failed:
4648   {
4649     g_warning ("rtpbin: failed to get rtcp pad for session %u", sessid);
4650     return NULL;
4651   }
4652 enc_src_failed:
4653   {
4654     g_warning ("rtpbin: failed to get encoder src pad for session %u", sessid);
4655     return NULL;
4656   }
4657 enc_sink_failed:
4658   {
4659     g_warning ("rtpbin: failed to get encoder sink pad for session %u", sessid);
4660     gst_object_unref (encsrc);
4661     return NULL;
4662   }
4663 enc_link_failed:
4664   {
4665     g_warning ("rtpbin: failed to link rtcp encoder for session %u", sessid);
4666     gst_object_unref (encsrc);
4667     return NULL;
4668   }
4669 }
4670
4671 static void
4672 remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session)
4673 {
4674   if (session->send_rtcp_src_ghost) {
4675     gst_pad_set_active (session->send_rtcp_src_ghost, FALSE);
4676     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
4677         session->send_rtcp_src_ghost);
4678     session->send_rtcp_src_ghost = NULL;
4679   }
4680   if (session->send_rtcp_src) {
4681     gst_element_release_request_pad (session->session, session->send_rtcp_src);
4682     gst_object_unref (session->send_rtcp_src);
4683     session->send_rtcp_src = NULL;
4684   }
4685 }
4686
4687 /* If the requested name is NULL we should create a name with
4688  * the session number assuming we want the lowest posible session
4689  * with a free pad like the template */
4690 static gchar *
4691 gst_rtp_bin_get_free_pad_name (GstElement * element, GstPadTemplate * templ)
4692 {
4693   gboolean name_found = FALSE;
4694   gint session = 0;
4695   GstIterator *pad_it = NULL;
4696   gchar *pad_name = NULL;
4697   GValue data = { 0, };
4698
4699   GST_DEBUG_OBJECT (element, "find a free pad name for template");
4700   while (!name_found) {
4701     gboolean done = FALSE;
4702
4703     g_free (pad_name);
4704     pad_name = g_strdup_printf (templ->name_template, session++);
4705     pad_it = gst_element_iterate_pads (GST_ELEMENT (element));
4706     name_found = TRUE;
4707     while (!done) {
4708       switch (gst_iterator_next (pad_it, &data)) {
4709         case GST_ITERATOR_OK:
4710         {
4711           GstPad *pad;
4712           gchar *name;
4713
4714           pad = g_value_get_object (&data);
4715           name = gst_pad_get_name (pad);
4716
4717           if (strcmp (name, pad_name) == 0) {
4718             done = TRUE;
4719             name_found = FALSE;
4720           }
4721           g_free (name);
4722           g_value_reset (&data);
4723           break;
4724         }
4725         case GST_ITERATOR_ERROR:
4726         case GST_ITERATOR_RESYNC:
4727           /* restart iteration */
4728           done = TRUE;
4729           name_found = FALSE;
4730           session = 0;
4731           break;
4732         case GST_ITERATOR_DONE:
4733           done = TRUE;
4734           break;
4735       }
4736     }
4737     g_value_unset (&data);
4738     gst_iterator_free (pad_it);
4739   }
4740
4741   GST_DEBUG_OBJECT (element, "free pad name found: '%s'", pad_name);
4742   return pad_name;
4743 }
4744
4745 /*
4746  */
4747 static GstPad *
4748 gst_rtp_bin_request_new_pad (GstElement * element,
4749     GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
4750 {
4751   GstRtpBin *rtpbin;
4752   GstElementClass *klass;
4753   GstPad *result;
4754
4755   gchar *pad_name = NULL;
4756
4757   g_return_val_if_fail (templ != NULL, NULL);
4758   g_return_val_if_fail (GST_IS_RTP_BIN (element), NULL);
4759
4760   rtpbin = GST_RTP_BIN (element);
4761   klass = GST_ELEMENT_GET_CLASS (element);
4762
4763   GST_RTP_BIN_LOCK (rtpbin);
4764
4765   if (name == NULL) {
4766     /* use a free pad name */
4767     pad_name = gst_rtp_bin_get_free_pad_name (element, templ);
4768   } else {
4769     /* use the provided name */
4770     pad_name = g_strdup (name);
4771   }
4772
4773   GST_DEBUG_OBJECT (rtpbin, "Trying to request a pad with name %s", pad_name);
4774
4775   /* figure out the template */
4776   if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink_%u")) {
4777     result = create_recv_rtp (rtpbin, templ, pad_name);
4778   } else if (templ == gst_element_class_get_pad_template (klass,
4779           "recv_rtcp_sink_%u")) {
4780     result = create_recv_rtcp (rtpbin, templ, pad_name);
4781   } else if (templ == gst_element_class_get_pad_template (klass,
4782           "send_rtp_sink_%u")) {
4783     result = create_send_rtp (rtpbin, templ, pad_name);
4784   } else if (templ == gst_element_class_get_pad_template (klass,
4785           "send_rtcp_src_%u")) {
4786     result = create_send_rtcp (rtpbin, templ, pad_name);
4787   } else
4788     goto wrong_template;
4789
4790   g_free (pad_name);
4791   GST_RTP_BIN_UNLOCK (rtpbin);
4792
4793   return result;
4794
4795   /* ERRORS */
4796 wrong_template:
4797   {
4798     g_free (pad_name);
4799     GST_RTP_BIN_UNLOCK (rtpbin);
4800     g_warning ("rtpbin: this is not our template");
4801     return NULL;
4802   }
4803 }
4804
4805 static void
4806 gst_rtp_bin_release_pad (GstElement * element, GstPad * pad)
4807 {
4808   GstRtpBinSession *session;
4809   GstRtpBin *rtpbin;
4810
4811   g_return_if_fail (GST_IS_GHOST_PAD (pad));
4812   g_return_if_fail (GST_IS_RTP_BIN (element));
4813
4814   rtpbin = GST_RTP_BIN (element);
4815
4816   GST_RTP_BIN_LOCK (rtpbin);
4817   GST_DEBUG_OBJECT (rtpbin, "Trying to release pad %s:%s",
4818       GST_DEBUG_PAD_NAME (pad));
4819
4820   if (!(session = find_session_by_pad (rtpbin, pad)))
4821     goto unknown_pad;
4822
4823   if (session->recv_rtp_sink_ghost == pad) {
4824     remove_recv_rtp (rtpbin, session);
4825   } else if (session->recv_rtcp_sink_ghost == pad) {
4826     remove_recv_rtcp (rtpbin, session);
4827   } else if (session->send_rtp_sink_ghost == pad) {
4828     remove_send_rtp (rtpbin, session);
4829   } else if (session->send_rtcp_src_ghost == pad) {
4830     remove_rtcp (rtpbin, session);
4831   }
4832
4833   /* no more request pads, free the complete session */
4834   if (session->recv_rtp_sink_ghost == NULL
4835       && session->recv_rtcp_sink_ghost == NULL
4836       && session->send_rtp_sink_ghost == NULL
4837       && session->send_rtcp_src_ghost == NULL) {
4838     GST_DEBUG_OBJECT (rtpbin, "no more pads for session %p", session);
4839     rtpbin->sessions = g_slist_remove (rtpbin->sessions, session);
4840     free_session (session, rtpbin);
4841   }
4842   GST_RTP_BIN_UNLOCK (rtpbin);
4843
4844   return;
4845
4846   /* ERROR */
4847 unknown_pad:
4848   {
4849     GST_RTP_BIN_UNLOCK (rtpbin);
4850     g_warning ("rtpbin: %s:%s is not one of our request pads",
4851         GST_DEBUG_PAD_NAME (pad));
4852     return;
4853   }
4854 }