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