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