rtpbin: copy buffering stats
[platform/upstream/gstreamer.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., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /**
21  * SECTION:element-gstrtpbin
22  * @see_also: gstrtpjitterbuffer, gstrtpsession, gstrtpptdemux, gstrtpssrcdemux
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_\%d pad. The session
32  * number must be specified in the pad name.
33  * Data received on the recv_rtp_sink_\%d 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_\%d_\%d_\%d on
39  * gstrtpbin 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_\%d 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_\%d 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_\%d pad, which will
51  * automatically create a send_rtp_src_\%d 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_\%d 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  * <refsect2>
62  * <title>Example pipelines</title>
63  * |[
64  * gst-launch udpsrc port=5000 caps="application/x-rtp, ..." ! .recv_rtp_sink_0 \
65  *     gstrtpbin ! rtptheoradepay ! theoradec ! xvimagesink
66  * ]| Receive RTP data from port 5000 and send to the session 0 in gstrtpbin.
67  * |[
68  * gst-launch gstrtpbin name=rtpbin \
69  *         v4l2src ! ffmpegcolorspace ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \
70  *                   rtpbin.send_rtp_src_0 ! udpsink port=5000                            \
71  *                   rtpbin.send_rtcp_src_0 ! udpsink port=5001 sync=false async=false    \
72  *                   udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
73  *         audiotestsrc ! amrnbenc ! rtpamrpay ! rtpbin.send_rtp_sink_1                   \
74  *                   rtpbin.send_rtp_src_1 ! udpsink port=5002                            \
75  *                   rtpbin.send_rtcp_src_1 ! udpsink port=5003 sync=false async=false    \
76  *                   udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1
77  * ]| Encode and payload H263 video captured from a v4l2src. Encode and payload AMR
78  * audio generated from audiotestsrc. The video is sent to session 0 in rtpbin
79  * and the audio is sent to session 1. Video packets are sent on UDP port 5000
80  * and audio packets on port 5002. The video RTCP packets for session 0 are sent
81  * on port 5001 and the audio RTCP packets for session 0 are sent on port 5003.
82  * RTCP packets for session 0 are received on port 5005 and RTCP for session 1
83  * is received on port 5007. Since RTCP packets from the sender should be sent
84  * as soon as possible and do not participate in preroll, sync=false and
85  * async=false is configured on udpsink
86  * |[
87  * gst-launch -v gstrtpbin name=rtpbin                                          \
88  *     udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-1998" \
89  *             port=5000 ! rtpbin.recv_rtp_sink_0                                \
90  *         rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink                    \
91  *      udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
92  *      rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
93  *     udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1" \
94  *             port=5002 ! rtpbin.recv_rtp_sink_1                                \
95  *         rtpbin. ! rtpamrdepay ! amrnbdec ! alsasink                           \
96  *      udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
97  *      rtpbin.send_rtcp_src_1 ! udpsink port=5007 sync=false async=false
98  * ]| Receive H263 on port 5000, send it through rtpbin in session 0, depayload,
99  * decode and display the video.
100  * Receive AMR on port 5002, send it through rtpbin in session 1, depayload,
101  * decode and play the audio.
102  * Receive server RTCP packets for session 0 on port 5001 and RTCP packets for
103  * session 1 on port 5003. These packets will be used for session management and
104  * synchronisation.
105  * Send RTCP reports for session 0 on port 5005 and RTCP reports for session 1
106  * on port 5007.
107  * </refsect2>
108  *
109  * Last reviewed on 2007-08-30 (0.10.6)
110  */
111
112 #ifdef HAVE_CONFIG_H
113 #include "config.h"
114 #endif
115 #include <stdio.h>
116 #include <string.h>
117
118 #include <gst/rtp/gstrtpbuffer.h>
119 #include <gst/rtp/gstrtcpbuffer.h>
120
121 #include "gstrtpbin-marshal.h"
122 #include "gstrtpbin.h"
123 #include "rtpsession.h"
124 #include "gstrtpsession.h"
125 #include "gstrtpjitterbuffer.h"
126
127 GST_DEBUG_CATEGORY_STATIC (gst_rtp_bin_debug);
128 #define GST_CAT_DEFAULT gst_rtp_bin_debug
129
130 /* sink pads */
131 static GstStaticPadTemplate rtpbin_recv_rtp_sink_template =
132 GST_STATIC_PAD_TEMPLATE ("recv_rtp_sink_%d",
133     GST_PAD_SINK,
134     GST_PAD_REQUEST,
135     GST_STATIC_CAPS ("application/x-rtp")
136     );
137
138 static GstStaticPadTemplate rtpbin_recv_rtcp_sink_template =
139 GST_STATIC_PAD_TEMPLATE ("recv_rtcp_sink_%d",
140     GST_PAD_SINK,
141     GST_PAD_REQUEST,
142     GST_STATIC_CAPS ("application/x-rtcp")
143     );
144
145 static GstStaticPadTemplate rtpbin_send_rtp_sink_template =
146 GST_STATIC_PAD_TEMPLATE ("send_rtp_sink_%d",
147     GST_PAD_SINK,
148     GST_PAD_REQUEST,
149     GST_STATIC_CAPS ("application/x-rtp")
150     );
151
152 /* src pads */
153 static GstStaticPadTemplate rtpbin_recv_rtp_src_template =
154 GST_STATIC_PAD_TEMPLATE ("recv_rtp_src_%d_%d_%d",
155     GST_PAD_SRC,
156     GST_PAD_SOMETIMES,
157     GST_STATIC_CAPS ("application/x-rtp")
158     );
159
160 static GstStaticPadTemplate rtpbin_send_rtcp_src_template =
161 GST_STATIC_PAD_TEMPLATE ("send_rtcp_src_%d",
162     GST_PAD_SRC,
163     GST_PAD_REQUEST,
164     GST_STATIC_CAPS ("application/x-rtcp")
165     );
166
167 static GstStaticPadTemplate rtpbin_send_rtp_src_template =
168 GST_STATIC_PAD_TEMPLATE ("send_rtp_src_%d",
169     GST_PAD_SRC,
170     GST_PAD_SOMETIMES,
171     GST_STATIC_CAPS ("application/x-rtp")
172     );
173
174 #define GST_RTP_BIN_GET_PRIVATE(obj)  \
175    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTP_BIN, GstRtpBinPrivate))
176
177 #define GST_RTP_BIN_LOCK(bin)   g_mutex_lock ((bin)->priv->bin_lock)
178 #define GST_RTP_BIN_UNLOCK(bin) g_mutex_unlock ((bin)->priv->bin_lock)
179
180 /* lock to protect dynamic callbacks, like pad-added and new ssrc. */
181 #define GST_RTP_BIN_DYN_LOCK(bin)    g_mutex_lock ((bin)->priv->dyn_lock)
182 #define GST_RTP_BIN_DYN_UNLOCK(bin)  g_mutex_unlock ((bin)->priv->dyn_lock)
183
184 /* lock for shutdown */
185 #define GST_RTP_BIN_SHUTDOWN_LOCK(bin,label)     \
186 G_STMT_START {                                   \
187   if (g_atomic_int_get (&bin->priv->shutdown))   \
188     goto label;                                  \
189   GST_RTP_BIN_DYN_LOCK (bin);                    \
190   if (g_atomic_int_get (&bin->priv->shutdown)) { \
191     GST_RTP_BIN_DYN_UNLOCK (bin);                \
192     goto label;                                  \
193   }                                              \
194 } G_STMT_END
195
196 /* unlock for shutdown */
197 #define GST_RTP_BIN_SHUTDOWN_UNLOCK(bin)         \
198   GST_RTP_BIN_DYN_UNLOCK (bin);                  \
199
200 struct _GstRtpBinPrivate
201 {
202   GMutex *bin_lock;
203
204   /* lock protecting dynamic adding/removing */
205   GMutex *dyn_lock;
206
207   /* if we are shutting down or not */
208   gint shutdown;
209
210   gboolean autoremove;
211 };
212
213 /* signals and args */
214 enum
215 {
216   SIGNAL_REQUEST_PT_MAP,
217   SIGNAL_PAYLOAD_TYPE_CHANGE,
218   SIGNAL_CLEAR_PT_MAP,
219   SIGNAL_RESET_SYNC,
220   SIGNAL_GET_INTERNAL_SESSION,
221
222   SIGNAL_ON_NEW_SSRC,
223   SIGNAL_ON_SSRC_COLLISION,
224   SIGNAL_ON_SSRC_VALIDATED,
225   SIGNAL_ON_SSRC_ACTIVE,
226   SIGNAL_ON_SSRC_SDES,
227   SIGNAL_ON_BYE_SSRC,
228   SIGNAL_ON_BYE_TIMEOUT,
229   SIGNAL_ON_TIMEOUT,
230   SIGNAL_ON_SENDER_TIMEOUT,
231   SIGNAL_ON_NPT_STOP,
232   LAST_SIGNAL
233 };
234
235 #define DEFAULT_LATENCY_MS           200
236 #define DEFAULT_SDES                 NULL
237 #define DEFAULT_DO_LOST              FALSE
238 #define DEFAULT_IGNORE_PT            FALSE
239 #define DEFAULT_NTP_SYNC             FALSE
240 #define DEFAULT_AUTOREMOVE           FALSE
241 #define DEFAULT_BUFFER_MODE          RTP_JITTER_BUFFER_MODE_SLAVE
242 #define DEFAULT_USE_PIPELINE_CLOCK   FALSE
243
244 enum
245 {
246   PROP_0,
247   PROP_LATENCY,
248   PROP_SDES,
249   PROP_DO_LOST,
250   PROP_IGNORE_PT,
251   PROP_NTP_SYNC,
252   PROP_AUTOREMOVE,
253   PROP_BUFFER_MODE,
254   PROP_USE_PIPELINE_CLOCK,
255   PROP_LAST
256 };
257
258 /* helper objects */
259 typedef struct _GstRtpBinSession GstRtpBinSession;
260 typedef struct _GstRtpBinStream GstRtpBinStream;
261 typedef struct _GstRtpBinClient GstRtpBinClient;
262
263 static guint gst_rtp_bin_signals[LAST_SIGNAL] = { 0 };
264
265 static GstCaps *pt_map_requested (GstElement * element, guint pt,
266     GstRtpBinSession * session);
267 static void payload_type_change (GstElement * element, guint pt,
268     GstRtpBinSession * session);
269 static void free_client (GstRtpBinClient * client, GstRtpBin * bin);
270 static void free_stream (GstRtpBinStream * stream);
271
272 /* Manages the RTP stream for one SSRC.
273  *
274  * We pipe the stream (comming from the SSRC demuxer) into a jitterbuffer.
275  * If we see an SDES RTCP packet that links multiple SSRCs together based on a
276  * common CNAME, we create a GstRtpBinClient structure to group the SSRCs
277  * together (see below).
278  */
279 struct _GstRtpBinStream
280 {
281   /* the SSRC of this stream */
282   guint32 ssrc;
283
284   /* parent bin */
285   GstRtpBin *bin;
286
287   /* the session this SSRC belongs to */
288   GstRtpBinSession *session;
289
290   /* the jitterbuffer of the SSRC */
291   GstElement *buffer;
292   gulong buffer_handlesync_sig;
293   gulong buffer_ptreq_sig;
294   gulong buffer_ntpstop_sig;
295   gint percent;
296
297   /* the PT demuxer of the SSRC */
298   GstElement *demux;
299   gulong demux_newpad_sig;
300   gulong demux_padremoved_sig;
301   gulong demux_ptreq_sig;
302   gulong demux_ptchange_sig;
303
304   /* if we have calculated a valid rt_delta for this stream */
305   gboolean have_sync;
306   /* mapping to local RTP and NTP time */
307   gint64 rt_delta;
308 };
309
310 #define GST_RTP_SESSION_LOCK(sess)   g_mutex_lock ((sess)->lock)
311 #define GST_RTP_SESSION_UNLOCK(sess) g_mutex_unlock ((sess)->lock)
312
313 /* Manages the receiving end of the packets.
314  *
315  * There is one such structure for each RTP session (audio/video/...).
316  * We get the RTP/RTCP packets and stuff them into the session manager. From
317  * there they are pushed into an SSRC demuxer that splits the stream based on
318  * SSRC. Each of the SSRC streams go into their own jitterbuffer (managed with
319  * the GstRtpBinStream above).
320  */
321 struct _GstRtpBinSession
322 {
323   /* session id */
324   gint id;
325   /* the parent bin */
326   GstRtpBin *bin;
327   /* the session element */
328   GstElement *session;
329   /* the SSRC demuxer */
330   GstElement *demux;
331   gulong demux_newpad_sig;
332   gulong demux_padremoved_sig;
333
334   GMutex *lock;
335
336   /* list of GstRtpBinStream */
337   GSList *streams;
338
339   /* mapping of payload type to caps */
340   GHashTable *ptmap;
341
342   /* the pads of the session */
343   GstPad *recv_rtp_sink;
344   GstPad *recv_rtp_sink_ghost;
345   GstPad *recv_rtp_src;
346   GstPad *recv_rtcp_sink;
347   GstPad *recv_rtcp_sink_ghost;
348   GstPad *sync_src;
349   GstPad *send_rtp_sink;
350   GstPad *send_rtp_sink_ghost;
351   GstPad *send_rtp_src;
352   GstPad *send_rtp_src_ghost;
353   GstPad *send_rtcp_src;
354   GstPad *send_rtcp_src_ghost;
355 };
356
357 /* Manages the RTP streams that come from one client and should therefore be
358  * synchronized.
359  */
360 struct _GstRtpBinClient
361 {
362   /* the common CNAME for the streams */
363   gchar *cname;
364   guint cname_len;
365
366   /* the streams */
367   guint nstreams;
368   GSList *streams;
369 };
370
371 /* find a session with the given id. Must be called with RTP_BIN_LOCK */
372 static GstRtpBinSession *
373 find_session_by_id (GstRtpBin * rtpbin, gint id)
374 {
375   GSList *walk;
376
377   for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) {
378     GstRtpBinSession *sess = (GstRtpBinSession *) walk->data;
379
380     if (sess->id == id)
381       return sess;
382   }
383   return NULL;
384 }
385
386 /* find a session with the given request pad. Must be called with RTP_BIN_LOCK */
387 static GstRtpBinSession *
388 find_session_by_pad (GstRtpBin * rtpbin, GstPad * pad)
389 {
390   GSList *walk;
391
392   for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) {
393     GstRtpBinSession *sess = (GstRtpBinSession *) walk->data;
394
395     if ((sess->recv_rtp_sink_ghost == pad) ||
396         (sess->recv_rtcp_sink_ghost == pad) ||
397         (sess->send_rtp_sink_ghost == pad)
398         || (sess->send_rtcp_src_ghost == pad))
399       return sess;
400   }
401   return NULL;
402 }
403
404 static void
405 on_new_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
406 {
407   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC], 0,
408       sess->id, ssrc);
409 }
410
411 static void
412 on_ssrc_collision (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
413 {
414   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION], 0,
415       sess->id, ssrc);
416 }
417
418 static void
419 on_ssrc_validated (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
420 {
421   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED], 0,
422       sess->id, ssrc);
423 }
424
425 static void
426 on_ssrc_active (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
427 {
428   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE], 0,
429       sess->id, ssrc);
430 }
431
432 static void
433 on_ssrc_sdes (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
434 {
435   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES], 0,
436       sess->id, ssrc);
437 }
438
439 static void
440 on_bye_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
441 {
442   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC], 0,
443       sess->id, ssrc);
444 }
445
446 static void
447 on_bye_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
448 {
449   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT], 0,
450       sess->id, ssrc);
451
452   if (sess->bin->priv->autoremove)
453     g_signal_emit_by_name (sess->demux, "clear-ssrc", ssrc, NULL);
454 }
455
456 static void
457 on_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
458 {
459   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT], 0,
460       sess->id, ssrc);
461
462   if (sess->bin->priv->autoremove)
463     g_signal_emit_by_name (sess->demux, "clear-ssrc", ssrc, NULL);
464 }
465
466 static void
467 on_sender_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
468 {
469   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT], 0,
470       sess->id, ssrc);
471 }
472
473 static void
474 on_npt_stop (GstElement * jbuf, GstRtpBinStream * stream)
475 {
476   g_signal_emit (stream->bin, gst_rtp_bin_signals[SIGNAL_ON_NPT_STOP], 0,
477       stream->session->id, stream->ssrc);
478 }
479
480 /* must be called with the SESSION lock */
481 static GstRtpBinStream *
482 find_stream_by_ssrc (GstRtpBinSession * session, guint32 ssrc)
483 {
484   GSList *walk;
485
486   for (walk = session->streams; walk; walk = g_slist_next (walk)) {
487     GstRtpBinStream *stream = (GstRtpBinStream *) walk->data;
488
489     if (stream->ssrc == ssrc)
490       return stream;
491   }
492   return NULL;
493 }
494
495 static void
496 ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad,
497     GstRtpBinSession * session)
498 {
499   GstRtpBinStream *stream = NULL;
500
501   GST_RTP_SESSION_LOCK (session);
502   if ((stream = find_stream_by_ssrc (session, ssrc)))
503     session->streams = g_slist_remove (session->streams, stream);
504   GST_RTP_SESSION_UNLOCK (session);
505
506   if (stream)
507     free_stream (stream);
508 }
509
510 /* create a session with the given id.  Must be called with RTP_BIN_LOCK */
511 static GstRtpBinSession *
512 create_session (GstRtpBin * rtpbin, gint id)
513 {
514   GstRtpBinSession *sess;
515   GstElement *session, *demux;
516   GstState target;
517
518   if (!(session = gst_element_factory_make ("gstrtpsession", NULL)))
519     goto no_session;
520
521   if (!(demux = gst_element_factory_make ("gstrtpssrcdemux", NULL)))
522     goto no_demux;
523
524   sess = g_new0 (GstRtpBinSession, 1);
525   sess->lock = g_mutex_new ();
526   sess->id = id;
527   sess->bin = rtpbin;
528   sess->session = session;
529   sess->demux = demux;
530   sess->ptmap = g_hash_table_new_full (NULL, NULL, NULL,
531       (GDestroyNotify) gst_caps_unref);
532   rtpbin->sessions = g_slist_prepend (rtpbin->sessions, sess);
533
534   /* configure SDES items */
535   GST_OBJECT_LOCK (rtpbin);
536   g_object_set (session, "sdes", rtpbin->sdes, "use-pipeline-clock",
537       rtpbin->use_pipeline_clock, NULL);
538   GST_OBJECT_UNLOCK (rtpbin);
539
540   /* provide clock_rate to the session manager when needed */
541   g_signal_connect (session, "request-pt-map",
542       (GCallback) pt_map_requested, sess);
543
544   g_signal_connect (sess->session, "on-new-ssrc",
545       (GCallback) on_new_ssrc, sess);
546   g_signal_connect (sess->session, "on-ssrc-collision",
547       (GCallback) on_ssrc_collision, sess);
548   g_signal_connect (sess->session, "on-ssrc-validated",
549       (GCallback) on_ssrc_validated, sess);
550   g_signal_connect (sess->session, "on-ssrc-active",
551       (GCallback) on_ssrc_active, sess);
552   g_signal_connect (sess->session, "on-ssrc-sdes",
553       (GCallback) on_ssrc_sdes, sess);
554   g_signal_connect (sess->session, "on-bye-ssrc",
555       (GCallback) on_bye_ssrc, sess);
556   g_signal_connect (sess->session, "on-bye-timeout",
557       (GCallback) on_bye_timeout, sess);
558   g_signal_connect (sess->session, "on-timeout", (GCallback) on_timeout, sess);
559   g_signal_connect (sess->session, "on-sender-timeout",
560       (GCallback) on_sender_timeout, sess);
561
562   gst_bin_add (GST_BIN_CAST (rtpbin), session);
563   gst_bin_add (GST_BIN_CAST (rtpbin), demux);
564
565   GST_OBJECT_LOCK (rtpbin);
566   target = GST_STATE_TARGET (rtpbin);
567   GST_OBJECT_UNLOCK (rtpbin);
568
569   /* change state only to what's needed */
570   gst_element_set_state (demux, target);
571   gst_element_set_state (session, target);
572
573   return sess;
574
575   /* ERRORS */
576 no_session:
577   {
578     g_warning ("gstrtpbin: could not create gstrtpsession element");
579     return NULL;
580   }
581 no_demux:
582   {
583     gst_object_unref (session);
584     g_warning ("gstrtpbin: could not create gstrtpssrcdemux element");
585     return NULL;
586   }
587 }
588
589 static void
590 free_session (GstRtpBinSession * sess, GstRtpBin * bin)
591 {
592   GSList *client_walk;
593
594   GST_DEBUG_OBJECT (bin, "freeing session %p", sess);
595
596   gst_element_set_locked_state (sess->demux, TRUE);
597   gst_element_set_locked_state (sess->session, TRUE);
598
599   gst_element_set_state (sess->demux, GST_STATE_NULL);
600   gst_element_set_state (sess->session, GST_STATE_NULL);
601
602   if (sess->recv_rtp_sink != NULL) {
603     gst_element_release_request_pad (sess->session, sess->recv_rtp_sink);
604     gst_object_unref (sess->recv_rtp_sink);
605   }
606   if (sess->recv_rtp_src != NULL)
607     gst_object_unref (sess->recv_rtp_src);
608   if (sess->recv_rtcp_sink != NULL) {
609     gst_element_release_request_pad (sess->session, sess->recv_rtcp_sink);
610     gst_object_unref (sess->recv_rtcp_sink);
611   }
612   if (sess->sync_src != NULL)
613     gst_object_unref (sess->sync_src);
614   if (sess->send_rtp_sink != NULL) {
615     gst_element_release_request_pad (sess->session, sess->send_rtp_sink);
616     gst_object_unref (sess->send_rtp_sink);
617   }
618   if (sess->send_rtp_src != NULL)
619     gst_object_unref (sess->send_rtp_src);
620   if (sess->send_rtcp_src != NULL) {
621     gst_element_release_request_pad (sess->session, sess->send_rtcp_src);
622     gst_object_unref (sess->send_rtcp_src);
623   }
624
625   gst_bin_remove (GST_BIN_CAST (bin), sess->session);
626   gst_bin_remove (GST_BIN_CAST (bin), sess->demux);
627
628   /* remove any references in bin->clients to the streams in sess->streams */
629   client_walk = bin->clients;
630   while (client_walk) {
631     GSList *client_node = client_walk;
632     GstRtpBinClient *client = (GstRtpBinClient *) client_node->data;
633     GSList *stream_walk = client->streams;
634
635     while (stream_walk) {
636       GSList *stream_node = stream_walk;
637       GstRtpBinStream *stream = (GstRtpBinStream *) stream_node->data;
638       GSList *inner_walk;
639
640       stream_walk = g_slist_next (stream_walk);
641
642       for (inner_walk = sess->streams; inner_walk;
643           inner_walk = g_slist_next (inner_walk)) {
644         if ((GstRtpBinStream *) inner_walk->data == stream) {
645           client->streams = g_slist_delete_link (client->streams, stream_node);
646           --client->nstreams;
647           break;
648         }
649       }
650     }
651     client_walk = g_slist_next (client_walk);
652
653     g_assert ((client->streams && client->nstreams > 0) || (!client->streams
654             && client->streams == 0));
655     if (client->nstreams == 0) {
656       free_client (client, bin);
657       bin->clients = g_slist_delete_link (bin->clients, client_node);
658     }
659   }
660
661   g_slist_foreach (sess->streams, (GFunc) free_stream, NULL);
662   g_slist_free (sess->streams);
663
664   g_mutex_free (sess->lock);
665   g_hash_table_destroy (sess->ptmap);
666
667   g_free (sess);
668 }
669
670 /* get the payload type caps for the specific payload @pt in @session */
671 static GstCaps *
672 get_pt_map (GstRtpBinSession * session, guint pt)
673 {
674   GstCaps *caps = NULL;
675   GstRtpBin *bin;
676   GValue ret = { 0 };
677   GValue args[3] = { {0}, {0}, {0} };
678
679   GST_DEBUG ("searching pt %d in cache", pt);
680
681   GST_RTP_SESSION_LOCK (session);
682
683   /* first look in the cache */
684   caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt));
685   if (caps) {
686     gst_caps_ref (caps);
687     goto done;
688   }
689
690   bin = session->bin;
691
692   GST_DEBUG ("emiting signal for pt %d in session %d", pt, session->id);
693
694   /* not in cache, send signal to request caps */
695   g_value_init (&args[0], GST_TYPE_ELEMENT);
696   g_value_set_object (&args[0], bin);
697   g_value_init (&args[1], G_TYPE_UINT);
698   g_value_set_uint (&args[1], session->id);
699   g_value_init (&args[2], G_TYPE_UINT);
700   g_value_set_uint (&args[2], pt);
701
702   g_value_init (&ret, GST_TYPE_CAPS);
703   g_value_set_boxed (&ret, NULL);
704
705   GST_RTP_SESSION_UNLOCK (session);
706
707   g_signal_emitv (args, gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP], 0, &ret);
708
709   GST_RTP_SESSION_LOCK (session);
710
711   g_value_unset (&args[0]);
712   g_value_unset (&args[1]);
713   g_value_unset (&args[2]);
714
715   /* look in the cache again because we let the lock go */
716   caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt));
717   if (caps) {
718     gst_caps_ref (caps);
719     g_value_unset (&ret);
720     goto done;
721   }
722
723   caps = (GstCaps *) g_value_dup_boxed (&ret);
724   g_value_unset (&ret);
725   if (!caps)
726     goto no_caps;
727
728   GST_DEBUG ("caching pt %d as %" GST_PTR_FORMAT, pt, caps);
729
730   /* store in cache, take additional ref */
731   g_hash_table_insert (session->ptmap, GINT_TO_POINTER (pt),
732       gst_caps_ref (caps));
733
734 done:
735   GST_RTP_SESSION_UNLOCK (session);
736
737   return caps;
738
739   /* ERRORS */
740 no_caps:
741   {
742     GST_RTP_SESSION_UNLOCK (session);
743     GST_DEBUG ("no pt map could be obtained");
744     return NULL;
745   }
746 }
747
748 static gboolean
749 return_true (gpointer key, gpointer value, gpointer user_data)
750 {
751   return TRUE;
752 }
753
754 static void
755 gst_rtp_bin_reset_sync (GstRtpBin * rtpbin)
756 {
757   GSList *clients, *streams;
758
759   GST_DEBUG_OBJECT (rtpbin, "Reset sync on all clients");
760
761   GST_RTP_BIN_LOCK (rtpbin);
762   for (clients = rtpbin->clients; clients; clients = g_slist_next (clients)) {
763     GstRtpBinClient *client = (GstRtpBinClient *) clients->data;
764
765     /* reset sync on all streams for this client */
766     for (streams = client->streams; streams; streams = g_slist_next (streams)) {
767       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
768
769       /* make use require a new SR packet for this stream before we attempt new
770        * lip-sync */
771       stream->have_sync = FALSE;
772       stream->rt_delta = 0;
773     }
774   }
775   GST_RTP_BIN_UNLOCK (rtpbin);
776 }
777
778 static void
779 gst_rtp_bin_clear_pt_map (GstRtpBin * bin)
780 {
781   GSList *sessions, *streams;
782
783   GST_RTP_BIN_LOCK (bin);
784   GST_DEBUG_OBJECT (bin, "clearing pt map");
785   for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
786     GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
787
788     GST_DEBUG_OBJECT (bin, "clearing session %p", session);
789     g_signal_emit_by_name (session->session, "clear-pt-map", NULL);
790
791     GST_RTP_SESSION_LOCK (session);
792     g_hash_table_foreach_remove (session->ptmap, return_true, NULL);
793
794     for (streams = session->streams; streams; streams = g_slist_next (streams)) {
795       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
796
797       GST_DEBUG_OBJECT (bin, "clearing stream %p", stream);
798       g_signal_emit_by_name (stream->buffer, "clear-pt-map", NULL);
799       if (stream->demux)
800         g_signal_emit_by_name (stream->demux, "clear-pt-map", NULL);
801     }
802     GST_RTP_SESSION_UNLOCK (session);
803   }
804   GST_RTP_BIN_UNLOCK (bin);
805
806   /* reset sync too */
807   gst_rtp_bin_reset_sync (bin);
808 }
809
810 static RTPSession *
811 gst_rtp_bin_get_internal_session (GstRtpBin * bin, guint session_id)
812 {
813   RTPSession *internal_session = NULL;
814   GstRtpBinSession *session;
815
816   GST_RTP_BIN_LOCK (bin);
817   GST_DEBUG_OBJECT (bin, "retrieving internal RTPSession object, index: %d",
818       session_id);
819   session = find_session_by_id (bin, (gint) session_id);
820   if (session) {
821     g_object_get (session->session, "internal-session", &internal_session,
822         NULL);
823   }
824   GST_RTP_BIN_UNLOCK (bin);
825
826   return internal_session;
827 }
828
829 static void
830 gst_rtp_bin_propagate_property_to_jitterbuffer (GstRtpBin * bin,
831     const gchar * name, const GValue * value)
832 {
833   GSList *sessions, *streams;
834
835   GST_RTP_BIN_LOCK (bin);
836   for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
837     GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
838
839     GST_RTP_SESSION_LOCK (session);
840     for (streams = session->streams; streams; streams = g_slist_next (streams)) {
841       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
842
843       g_object_set_property (G_OBJECT (stream->buffer), name, value);
844     }
845     GST_RTP_SESSION_UNLOCK (session);
846   }
847   GST_RTP_BIN_UNLOCK (bin);
848 }
849
850 /* get a client with the given SDES name. Must be called with RTP_BIN_LOCK */
851 static GstRtpBinClient *
852 get_client (GstRtpBin * bin, guint8 len, guint8 * data, gboolean * created)
853 {
854   GstRtpBinClient *result = NULL;
855   GSList *walk;
856
857   for (walk = bin->clients; walk; walk = g_slist_next (walk)) {
858     GstRtpBinClient *client = (GstRtpBinClient *) walk->data;
859
860     if (len != client->cname_len)
861       continue;
862
863     if (!strncmp ((gchar *) data, client->cname, client->cname_len)) {
864       GST_DEBUG_OBJECT (bin, "found existing client %p with CNAME %s", client,
865           client->cname);
866       result = client;
867       break;
868     }
869   }
870
871   /* nothing found, create one */
872   if (result == NULL) {
873     result = g_new0 (GstRtpBinClient, 1);
874     result->cname = g_strndup ((gchar *) data, len);
875     result->cname_len = len;
876     bin->clients = g_slist_prepend (bin->clients, result);
877     GST_DEBUG_OBJECT (bin, "created new client %p with CNAME %s", result,
878         result->cname);
879   }
880   return result;
881 }
882
883 static void
884 free_client (GstRtpBinClient * client, GstRtpBin * bin)
885 {
886   GST_DEBUG_OBJECT (bin, "freeing client %p", client);
887   g_slist_free (client->streams);
888   g_free (client->cname);
889   g_free (client);
890 }
891
892 static void
893 get_current_times (GstRtpBin * bin, GstClockTime * running_time,
894     guint64 * ntpnstime)
895 {
896   guint64 ntpns;
897   GstClock *clock;
898   GstClockTime base_time, rt, clock_time;
899
900   GST_OBJECT_LOCK (bin);
901   if ((clock = GST_ELEMENT_CLOCK (bin))) {
902     base_time = GST_ELEMENT_CAST (bin)->base_time;
903     gst_object_ref (clock);
904     GST_OBJECT_UNLOCK (bin);
905
906     clock_time = gst_clock_get_time (clock);
907
908     if (bin->use_pipeline_clock) {
909       ntpns = clock_time;
910     } else {
911       GTimeVal current;
912
913       /* get current NTP time */
914       g_get_current_time (&current);
915       ntpns = GST_TIMEVAL_TO_TIME (current);
916     }
917
918     /* add constant to convert from 1970 based time to 1900 based time */
919     ntpns += (2208988800LL * GST_SECOND);
920
921     /* get current clock time and convert to running time */
922     rt = clock_time - base_time;
923
924     gst_object_unref (clock);
925   } else {
926     GST_OBJECT_UNLOCK (bin);
927     rt = -1;
928     ntpns = -1;
929   }
930   if (running_time)
931     *running_time = rt;
932   if (ntpnstime)
933     *ntpnstime = ntpns;
934 }
935
936 static void
937 stream_set_ts_offset (GstRtpBin * bin, GstRtpBinStream * stream,
938     gint64 ts_offset)
939 {
940   gint64 prev_ts_offset;
941
942   g_object_get (stream->buffer, "ts-offset", &prev_ts_offset, NULL);
943
944   /* delta changed, see how much */
945   if (prev_ts_offset != ts_offset) {
946     gint64 diff;
947
948     diff = prev_ts_offset - ts_offset;
949
950     GST_DEBUG_OBJECT (bin,
951         "ts-offset %" G_GINT64_FORMAT ", prev %" G_GINT64_FORMAT
952         ", diff: %" G_GINT64_FORMAT, ts_offset, prev_ts_offset, diff);
953
954     /* only change diff when it changed more than 4 milliseconds. This
955      * compensates for rounding errors in NTP to RTP timestamp
956      * conversions */
957     if (ABS (diff) > 4 * GST_MSECOND) {
958       if (ABS (diff) < (3 * GST_SECOND)) {
959         g_object_set (stream->buffer, "ts-offset", ts_offset, NULL);
960       } else {
961         GST_WARNING_OBJECT (bin, "offset unusually large, ignoring");
962       }
963     } else {
964       GST_DEBUG_OBJECT (bin, "offset too small, ignoring");
965     }
966   }
967   GST_DEBUG_OBJECT (bin, "stream SSRC %08x, delta %" G_GINT64_FORMAT,
968       stream->ssrc, ts_offset);
969 }
970
971 /* associate a stream to the given CNAME. This will make sure all streams for
972  * that CNAME are synchronized together.
973  * Must be called with GST_RTP_BIN_LOCK */
974 static void
975 gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
976     guint8 * data, guint64 ntptime, guint64 last_extrtptime,
977     guint64 base_rtptime, guint64 base_time, guint clock_rate)
978 {
979   GstRtpBinClient *client;
980   gboolean created;
981   GSList *walk;
982   guint64 local_rt;
983   guint64 local_rtp;
984   GstClockTime running_time;
985   guint64 ntpnstime;
986   gint64 ntpdiff, rtdiff;
987   guint64 last_unix;
988
989   /* first find or create the CNAME */
990   client = get_client (bin, len, data, &created);
991
992   /* find stream in the client */
993   for (walk = client->streams; walk; walk = g_slist_next (walk)) {
994     GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
995
996     if (ostream == stream)
997       break;
998   }
999   /* not found, add it to the list */
1000   if (walk == NULL) {
1001     GST_DEBUG_OBJECT (bin,
1002         "new association of SSRC %08x with client %p with CNAME %s",
1003         stream->ssrc, client, client->cname);
1004     client->streams = g_slist_prepend (client->streams, stream);
1005     client->nstreams++;
1006   } else {
1007     GST_DEBUG_OBJECT (bin,
1008         "found association of SSRC %08x with client %p with CNAME %s",
1009         stream->ssrc, client, client->cname);
1010   }
1011
1012   /* Take the extended rtptime we found in the SR packet and map it to the
1013    * local rtptime. The local rtp time is used to construct timestamps on the
1014    * buffers so we will calculate what running_time corresponds to the RTP
1015    * timestamp in the SR packet. */
1016   local_rtp = last_extrtptime - base_rtptime;
1017
1018   GST_DEBUG_OBJECT (bin,
1019       "base %" G_GUINT64_FORMAT ", extrtptime %" G_GUINT64_FORMAT
1020       ", local RTP %" G_GUINT64_FORMAT ", clock-rate %d", base_rtptime,
1021       last_extrtptime, local_rtp, clock_rate);
1022
1023   /* calculate local RTP time in gstreamer timestamp, we essentially perform the
1024    * same conversion that a jitterbuffer would use to convert an rtp timestamp
1025    * into a corresponding gstreamer timestamp. Note that the base_time also
1026    * contains the drift between sender and receiver. */
1027   local_rt = gst_util_uint64_scale_int (local_rtp, GST_SECOND, clock_rate);
1028   local_rt += base_time;
1029
1030   /* convert ntptime to unix time since 1900 */
1031   last_unix = gst_util_uint64_scale (ntptime, GST_SECOND,
1032       (G_GINT64_CONSTANT (1) << 32));
1033
1034   stream->have_sync = TRUE;
1035
1036   GST_DEBUG_OBJECT (bin,
1037       "local UNIX %" G_GUINT64_FORMAT ", remote UNIX %" G_GUINT64_FORMAT,
1038       local_rt, last_unix);
1039
1040   /* recalc inter stream playout offset, but only if there is more than one
1041    * stream or we're doing NTP sync. */
1042   if (bin->ntp_sync) {
1043     /* For NTP sync we need to first get a snapshot of running_time and NTP
1044      * time. We know at what running_time we play a certain RTP time, we also
1045      * calculated when we would play the RTP time in the SR packet. Now we need
1046      * to know how the running_time and the NTP time relate to eachother. */
1047     get_current_times (bin, &running_time, &ntpnstime);
1048
1049     /* see how far away the NTP time is. This is the difference between the
1050      * current NTP time and the NTP time in the last SR packet. */
1051     ntpdiff = ntpnstime - last_unix;
1052     /* see how far away the running_time is. This is the difference between the
1053      * current running_time and the running_time of the RTP timestamp in the
1054      * last SR packet. */
1055     rtdiff = running_time - local_rt;
1056
1057     GST_DEBUG_OBJECT (bin,
1058         "NTP time %" G_GUINT64_FORMAT ", last unix %" G_GUINT64_FORMAT,
1059         ntpnstime, last_unix);
1060     GST_DEBUG_OBJECT (bin,
1061         "NTP diff %" G_GINT64_FORMAT ", RT diff %" G_GINT64_FORMAT, ntpdiff,
1062         rtdiff);
1063
1064     /* combine to get the final diff to apply to the running_time */
1065     stream->rt_delta = rtdiff - ntpdiff;
1066
1067     stream_set_ts_offset (bin, stream, stream->rt_delta);
1068   } else if (client->nstreams > 1) {
1069     gint64 min;
1070
1071     /* calculate delta between server and receiver. last_unix is created by
1072      * converting the ntptime in the last SR packet to a gstreamer timestamp. This
1073      * delta expresses the difference to our timeline and the server timeline. The
1074      * difference in itself doesn't mean much but we can combine the delta of
1075      * multiple streams to create a stream specific offset. */
1076     stream->rt_delta = last_unix - local_rt;
1077
1078     /* calculate the min of all deltas, ignoring streams that did not yet have a
1079      * valid rt_delta because we did not yet receive an SR packet for those
1080      * streams.
1081      * We calculate the mininum because we would like to only apply positive
1082      * offsets to streams, delaying their playback instead of trying to speed up
1083      * other streams (which might be imposible when we have to create negative
1084      * latencies).
1085      * The stream that has the smallest diff is selected as the reference stream,
1086      * all other streams will have a positive offset to this difference. */
1087     min = G_MAXINT64;
1088     for (walk = client->streams; walk; walk = g_slist_next (walk)) {
1089       GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
1090
1091       if (!ostream->have_sync)
1092         continue;
1093
1094       if (ostream->rt_delta < min)
1095         min = ostream->rt_delta;
1096     }
1097
1098     GST_DEBUG_OBJECT (bin, "client %p min delta %" G_GINT64_FORMAT, client,
1099         min);
1100
1101     /* calculate offsets for each stream */
1102     for (walk = client->streams; walk; walk = g_slist_next (walk)) {
1103       GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
1104       gint64 ts_offset;
1105
1106       /* ignore streams for which we didn't receive an SR packet yet, we
1107        * can't synchronize them yet. We can however sync other streams just
1108        * fine. */
1109       if (!ostream->have_sync)
1110         continue;
1111
1112       /* calculate offset to our reference stream, this should always give a
1113        * positive number. */
1114       ts_offset = ostream->rt_delta - min;
1115
1116       stream_set_ts_offset (bin, ostream, ts_offset);
1117     }
1118   }
1119   return;
1120 }
1121
1122 #define GST_RTCP_BUFFER_FOR_PACKETS(b,buffer,packet) \
1123   for ((b) = gst_rtcp_buffer_get_first_packet ((buffer), (packet)); (b); \
1124           (b) = gst_rtcp_packet_move_to_next ((packet)))
1125
1126 #define GST_RTCP_SDES_FOR_ITEMS(b,packet) \
1127   for ((b) = gst_rtcp_packet_sdes_first_item ((packet)); (b); \
1128           (b) = gst_rtcp_packet_sdes_next_item ((packet)))
1129
1130 #define GST_RTCP_SDES_FOR_ENTRIES(b,packet) \
1131   for ((b) = gst_rtcp_packet_sdes_first_entry ((packet)); (b); \
1132           (b) = gst_rtcp_packet_sdes_next_entry ((packet)))
1133
1134 static void
1135 gst_rtp_bin_handle_sync (GstElement * jitterbuffer, GstStructure * s,
1136     GstRtpBinStream * stream)
1137 {
1138   GstRtpBin *bin;
1139   GstRTCPPacket packet;
1140   guint32 ssrc;
1141   guint64 ntptime;
1142   gboolean have_sr, have_sdes;
1143   gboolean more;
1144   guint64 base_rtptime;
1145   guint64 base_time;
1146   guint clock_rate;
1147   guint64 extrtptime;
1148   GstBuffer *buffer;
1149
1150   bin = stream->bin;
1151
1152   GST_DEBUG_OBJECT (bin, "sync handler called");
1153
1154   /* get the last relation between the rtp timestamps and the gstreamer
1155    * timestamps. We get this info directly from the jitterbuffer which
1156    * constructs gstreamer timestamps from rtp timestamps and so it know exactly
1157    * what the current situation is. */
1158   base_rtptime =
1159       g_value_get_uint64 (gst_structure_get_value (s, "base-rtptime"));
1160   base_time = g_value_get_uint64 (gst_structure_get_value (s, "base-time"));
1161   clock_rate = g_value_get_uint (gst_structure_get_value (s, "clock-rate"));
1162   extrtptime =
1163       g_value_get_uint64 (gst_structure_get_value (s, "sr-ext-rtptime"));
1164   buffer = gst_value_get_buffer (gst_structure_get_value (s, "sr-buffer"));
1165
1166   have_sr = FALSE;
1167   have_sdes = FALSE;
1168   GST_RTCP_BUFFER_FOR_PACKETS (more, buffer, &packet) {
1169     /* first packet must be SR or RR or else the validate would have failed */
1170     switch (gst_rtcp_packet_get_type (&packet)) {
1171       case GST_RTCP_TYPE_SR:
1172         /* only parse first. There is only supposed to be one SR in the packet
1173          * but we will deal with malformed packets gracefully */
1174         if (have_sr)
1175           break;
1176         /* get NTP and RTP times */
1177         gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, &ntptime, NULL,
1178             NULL, NULL);
1179
1180         GST_DEBUG_OBJECT (bin, "received sync packet from SSRC %08x", ssrc);
1181         /* ignore SR that is not ours */
1182         if (ssrc != stream->ssrc)
1183           continue;
1184
1185         have_sr = TRUE;
1186         break;
1187       case GST_RTCP_TYPE_SDES:
1188       {
1189         gboolean more_items, more_entries;
1190
1191         /* only deal with first SDES, there is only supposed to be one SDES in
1192          * the RTCP packet but we deal with bad packets gracefully. Also bail
1193          * out if we have not seen an SR item yet. */
1194         if (have_sdes || !have_sr)
1195           break;
1196
1197         GST_RTCP_SDES_FOR_ITEMS (more_items, &packet) {
1198           /* skip items that are not about the SSRC of the sender */
1199           if (gst_rtcp_packet_sdes_get_ssrc (&packet) != ssrc)
1200             continue;
1201
1202           /* find the CNAME entry */
1203           GST_RTCP_SDES_FOR_ENTRIES (more_entries, &packet) {
1204             GstRTCPSDESType type;
1205             guint8 len;
1206             guint8 *data;
1207
1208             gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data);
1209
1210             if (type == GST_RTCP_SDES_CNAME) {
1211               GST_RTP_BIN_LOCK (bin);
1212               /* associate the stream to CNAME */
1213               gst_rtp_bin_associate (bin, stream, len, data,
1214                   ntptime, extrtptime, base_rtptime, base_time, clock_rate);
1215               GST_RTP_BIN_UNLOCK (bin);
1216             }
1217           }
1218         }
1219         have_sdes = TRUE;
1220         break;
1221       }
1222       default:
1223         /* we can ignore these packets */
1224         break;
1225     }
1226   }
1227 }
1228
1229 /* create a new stream with @ssrc in @session. Must be called with
1230  * RTP_SESSION_LOCK. */
1231 static GstRtpBinStream *
1232 create_stream (GstRtpBinSession * session, guint32 ssrc)
1233 {
1234   GstElement *buffer, *demux = NULL;
1235   GstRtpBinStream *stream;
1236   GstRtpBin *rtpbin;
1237   GstState target;
1238
1239   rtpbin = session->bin;
1240
1241   if (!(buffer = gst_element_factory_make ("gstrtpjitterbuffer", NULL)))
1242     goto no_jitterbuffer;
1243
1244   if (!rtpbin->ignore_pt)
1245     if (!(demux = gst_element_factory_make ("gstrtpptdemux", NULL)))
1246       goto no_demux;
1247
1248
1249   stream = g_new0 (GstRtpBinStream, 1);
1250   stream->ssrc = ssrc;
1251   stream->bin = rtpbin;
1252   stream->session = session;
1253   stream->buffer = buffer;
1254   stream->demux = demux;
1255
1256   stream->have_sync = FALSE;
1257   stream->rt_delta = 0;
1258   stream->percent = 100;
1259   session->streams = g_slist_prepend (session->streams, stream);
1260
1261   /* provide clock_rate to the jitterbuffer when needed */
1262   stream->buffer_ptreq_sig = g_signal_connect (buffer, "request-pt-map",
1263       (GCallback) pt_map_requested, session);
1264   stream->buffer_ntpstop_sig = g_signal_connect (buffer, "on-npt-stop",
1265       (GCallback) on_npt_stop, stream);
1266
1267   g_object_set_data (G_OBJECT (buffer), "GstRTPBin.session", session);
1268   g_object_set_data (G_OBJECT (buffer), "GstRTPBin.stream", stream);
1269
1270   /* configure latency and packet lost */
1271   g_object_set (buffer, "latency", rtpbin->latency_ms, NULL);
1272   g_object_set (buffer, "do-lost", rtpbin->do_lost, NULL);
1273   g_object_set (buffer, "mode", rtpbin->buffer_mode, NULL);
1274
1275   if (!rtpbin->ignore_pt)
1276     gst_bin_add (GST_BIN_CAST (rtpbin), demux);
1277   gst_bin_add (GST_BIN_CAST (rtpbin), buffer);
1278
1279   /* link stuff */
1280   if (demux)
1281     gst_element_link (buffer, demux);
1282
1283   if (rtpbin->buffering) {
1284     guint64 last_out;
1285
1286     GST_INFO_OBJECT (rtpbin,
1287         "bin is buffering, set jitterbuffer as not active");
1288     g_signal_emit_by_name (buffer, "set-active", FALSE, (gint64) 0, &last_out);
1289   }
1290
1291
1292   GST_OBJECT_LOCK (rtpbin);
1293   target = GST_STATE_TARGET (rtpbin);
1294   GST_OBJECT_UNLOCK (rtpbin);
1295
1296   /* from sink to source */
1297   if (demux)
1298     gst_element_set_state (demux, target);
1299
1300   gst_element_set_state (buffer, target);
1301
1302   return stream;
1303
1304   /* ERRORS */
1305 no_jitterbuffer:
1306   {
1307     g_warning ("gstrtpbin: could not create gstrtpjitterbuffer element");
1308     return NULL;
1309   }
1310 no_demux:
1311   {
1312     gst_object_unref (buffer);
1313     g_warning ("gstrtpbin: could not create gstrtpptdemux element");
1314     return NULL;
1315   }
1316 }
1317
1318 static void
1319 free_stream (GstRtpBinStream * stream)
1320 {
1321   GstRtpBinSession *session;
1322
1323   session = stream->session;
1324
1325   if (stream->demux) {
1326     g_signal_handler_disconnect (stream->demux, stream->demux_newpad_sig);
1327     g_signal_handler_disconnect (stream->demux, stream->demux_ptreq_sig);
1328     g_signal_handler_disconnect (stream->demux, stream->demux_ptchange_sig);
1329   }
1330   g_signal_handler_disconnect (stream->buffer, stream->buffer_handlesync_sig);
1331   g_signal_handler_disconnect (stream->buffer, stream->buffer_ptreq_sig);
1332   g_signal_handler_disconnect (stream->buffer, stream->buffer_ntpstop_sig);
1333
1334   gst_element_set_locked_state (stream->demux, TRUE);
1335   gst_element_set_locked_state (stream->buffer, TRUE);
1336
1337   gst_element_set_state (stream->demux, GST_STATE_NULL);
1338   gst_element_set_state (stream->buffer, GST_STATE_NULL);
1339
1340   /* now remove this signal, we need this while going to NULL because it to
1341    * do some cleanups */
1342   if (stream->demux)
1343     g_signal_handler_disconnect (stream->demux, stream->demux_padremoved_sig);
1344
1345   gst_bin_remove (GST_BIN_CAST (session->bin), stream->buffer);
1346   if (stream->demux)
1347     gst_bin_remove (GST_BIN_CAST (session->bin), stream->demux);
1348
1349   g_free (stream);
1350 }
1351
1352 /* GObject vmethods */
1353 static void gst_rtp_bin_dispose (GObject * object);
1354 static void gst_rtp_bin_finalize (GObject * object);
1355 static void gst_rtp_bin_set_property (GObject * object, guint prop_id,
1356     const GValue * value, GParamSpec * pspec);
1357 static void gst_rtp_bin_get_property (GObject * object, guint prop_id,
1358     GValue * value, GParamSpec * pspec);
1359
1360 /* GstElement vmethods */
1361 static GstStateChangeReturn gst_rtp_bin_change_state (GstElement * element,
1362     GstStateChange transition);
1363 static GstPad *gst_rtp_bin_request_new_pad (GstElement * element,
1364     GstPadTemplate * templ, const gchar * name);
1365 static void gst_rtp_bin_release_pad (GstElement * element, GstPad * pad);
1366 static void gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message);
1367
1368 GST_BOILERPLATE (GstRtpBin, gst_rtp_bin, GstBin, GST_TYPE_BIN);
1369
1370 static void
1371 gst_rtp_bin_base_init (gpointer klass)
1372 {
1373   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
1374
1375   /* sink pads */
1376   gst_element_class_add_pad_template (element_class,
1377       gst_static_pad_template_get (&rtpbin_recv_rtp_sink_template));
1378   gst_element_class_add_pad_template (element_class,
1379       gst_static_pad_template_get (&rtpbin_recv_rtcp_sink_template));
1380   gst_element_class_add_pad_template (element_class,
1381       gst_static_pad_template_get (&rtpbin_send_rtp_sink_template));
1382
1383   /* src pads */
1384   gst_element_class_add_pad_template (element_class,
1385       gst_static_pad_template_get (&rtpbin_recv_rtp_src_template));
1386   gst_element_class_add_pad_template (element_class,
1387       gst_static_pad_template_get (&rtpbin_send_rtcp_src_template));
1388   gst_element_class_add_pad_template (element_class,
1389       gst_static_pad_template_get (&rtpbin_send_rtp_src_template));
1390
1391   gst_element_class_set_details_simple (element_class, "RTP Bin",
1392       "Filter/Network/RTP",
1393       "Real-Time Transport Protocol bin",
1394       "Wim Taymans <wim.taymans@gmail.com>");
1395 }
1396
1397 static void
1398 gst_rtp_bin_class_init (GstRtpBinClass * klass)
1399 {
1400   GObjectClass *gobject_class;
1401   GstElementClass *gstelement_class;
1402   GstBinClass *gstbin_class;
1403
1404   gobject_class = (GObjectClass *) klass;
1405   gstelement_class = (GstElementClass *) klass;
1406   gstbin_class = (GstBinClass *) klass;
1407
1408   g_type_class_add_private (klass, sizeof (GstRtpBinPrivate));
1409
1410   gobject_class->dispose = gst_rtp_bin_dispose;
1411   gobject_class->finalize = gst_rtp_bin_finalize;
1412   gobject_class->set_property = gst_rtp_bin_set_property;
1413   gobject_class->get_property = gst_rtp_bin_get_property;
1414
1415   g_object_class_install_property (gobject_class, PROP_LATENCY,
1416       g_param_spec_uint ("latency", "Buffer latency in ms",
1417           "Default amount of ms to buffer in the jitterbuffers", 0,
1418           G_MAXUINT, DEFAULT_LATENCY_MS,
1419           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1420
1421   /**
1422    * GstRtpBin::request-pt-map:
1423    * @rtpbin: the object which received the signal
1424    * @session: the session
1425    * @pt: the pt
1426    *
1427    * Request the payload type as #GstCaps for @pt in @session.
1428    */
1429   gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP] =
1430       g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass),
1431       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, request_pt_map),
1432       NULL, NULL, gst_rtp_bin_marshal_BOXED__UINT_UINT, GST_TYPE_CAPS, 2,
1433       G_TYPE_UINT, G_TYPE_UINT);
1434
1435     /**
1436    * GstRtpBin::payload-type-change:
1437    * @rtpbin: the object which received the signal
1438    * @session: the session
1439    * @pt: the pt
1440    *
1441    * Signal that the current payload type changed to @pt in @session.
1442    *
1443    * Since: 0.10.17
1444    */
1445   gst_rtp_bin_signals[SIGNAL_PAYLOAD_TYPE_CHANGE] =
1446       g_signal_new ("payload-type-change", G_TYPE_FROM_CLASS (klass),
1447       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, payload_type_change),
1448       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1449       G_TYPE_UINT, G_TYPE_UINT);
1450
1451   /**
1452    * GstRtpBin::clear-pt-map:
1453    * @rtpbin: the object which received the signal
1454    *
1455    * Clear all previously cached pt-mapping obtained with
1456    * #GstRtpBin::request-pt-map.
1457    */
1458   gst_rtp_bin_signals[SIGNAL_CLEAR_PT_MAP] =
1459       g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass),
1460       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
1461           clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
1462       0, G_TYPE_NONE);
1463
1464   /**
1465    * GstRtpBin::reset-sync:
1466    * @rtpbin: the object which received the signal
1467    *
1468    * Reset all currently configured lip-sync parameters and require new SR
1469    * packets for all streams before lip-sync is attempted again.
1470    */
1471   gst_rtp_bin_signals[SIGNAL_RESET_SYNC] =
1472       g_signal_new ("reset-sync", G_TYPE_FROM_CLASS (klass),
1473       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
1474           reset_sync), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
1475       0, G_TYPE_NONE);
1476
1477   /**
1478    * GstRtpBin::get-internal-session:
1479    * @rtpbin: the object which received the signal
1480    * @id: the session id
1481    *
1482    * Request the internal RTPSession object as #GObject in session @id.
1483    */
1484   gst_rtp_bin_signals[SIGNAL_GET_INTERNAL_SESSION] =
1485       g_signal_new ("get-internal-session", G_TYPE_FROM_CLASS (klass),
1486       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
1487           get_internal_session), NULL, NULL, gst_rtp_bin_marshal_OBJECT__UINT,
1488       RTP_TYPE_SESSION, 1, G_TYPE_UINT);
1489
1490   /**
1491    * GstRtpBin::on-new-ssrc:
1492    * @rtpbin: the object which received the signal
1493    * @session: the session
1494    * @ssrc: the SSRC
1495    *
1496    * Notify of a new SSRC that entered @session.
1497    */
1498   gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC] =
1499       g_signal_new ("on-new-ssrc", G_TYPE_FROM_CLASS (klass),
1500       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_new_ssrc),
1501       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1502       G_TYPE_UINT, G_TYPE_UINT);
1503   /**
1504    * GstRtpBin::on-ssrc-collision:
1505    * @rtpbin: the object which received the signal
1506    * @session: the session
1507    * @ssrc: the SSRC
1508    *
1509    * Notify when we have an SSRC collision
1510    */
1511   gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION] =
1512       g_signal_new ("on-ssrc-collision", G_TYPE_FROM_CLASS (klass),
1513       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_collision),
1514       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1515       G_TYPE_UINT, G_TYPE_UINT);
1516   /**
1517    * GstRtpBin::on-ssrc-validated:
1518    * @rtpbin: the object which received the signal
1519    * @session: the session
1520    * @ssrc: the SSRC
1521    *
1522    * Notify of a new SSRC that became validated.
1523    */
1524   gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED] =
1525       g_signal_new ("on-ssrc-validated", G_TYPE_FROM_CLASS (klass),
1526       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_validated),
1527       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1528       G_TYPE_UINT, G_TYPE_UINT);
1529   /**
1530    * GstRtpBin::on-ssrc-active:
1531    * @rtpbin: the object which received the signal
1532    * @session: the session
1533    * @ssrc: the SSRC
1534    *
1535    * Notify of a SSRC that is active, i.e., sending RTCP.
1536    */
1537   gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE] =
1538       g_signal_new ("on-ssrc-active", G_TYPE_FROM_CLASS (klass),
1539       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_active),
1540       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1541       G_TYPE_UINT, G_TYPE_UINT);
1542   /**
1543    * GstRtpBin::on-ssrc-sdes:
1544    * @rtpbin: the object which received the signal
1545    * @session: the session
1546    * @ssrc: the SSRC
1547    *
1548    * Notify of a SSRC that is active, i.e., sending RTCP.
1549    */
1550   gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES] =
1551       g_signal_new ("on-ssrc-sdes", G_TYPE_FROM_CLASS (klass),
1552       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_sdes),
1553       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1554       G_TYPE_UINT, G_TYPE_UINT);
1555
1556   /**
1557    * GstRtpBin::on-bye-ssrc:
1558    * @rtpbin: the object which received the signal
1559    * @session: the session
1560    * @ssrc: the SSRC
1561    *
1562    * Notify of an SSRC that became inactive because of a BYE packet.
1563    */
1564   gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC] =
1565       g_signal_new ("on-bye-ssrc", G_TYPE_FROM_CLASS (klass),
1566       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_ssrc),
1567       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1568       G_TYPE_UINT, G_TYPE_UINT);
1569   /**
1570    * GstRtpBin::on-bye-timeout:
1571    * @rtpbin: the object which received the signal
1572    * @session: the session
1573    * @ssrc: the SSRC
1574    *
1575    * Notify of an SSRC that has timed out because of BYE
1576    */
1577   gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT] =
1578       g_signal_new ("on-bye-timeout", G_TYPE_FROM_CLASS (klass),
1579       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_timeout),
1580       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1581       G_TYPE_UINT, G_TYPE_UINT);
1582   /**
1583    * GstRtpBin::on-timeout:
1584    * @rtpbin: the object which received the signal
1585    * @session: the session
1586    * @ssrc: the SSRC
1587    *
1588    * Notify of an SSRC that has timed out
1589    */
1590   gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT] =
1591       g_signal_new ("on-timeout", G_TYPE_FROM_CLASS (klass),
1592       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_timeout),
1593       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1594       G_TYPE_UINT, G_TYPE_UINT);
1595   /**
1596    * GstRtpBin::on-sender-timeout:
1597    * @rtpbin: the object which received the signal
1598    * @session: the session
1599    * @ssrc: the SSRC
1600    *
1601    * Notify of a sender SSRC that has timed out and became a receiver
1602    */
1603   gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT] =
1604       g_signal_new ("on-sender-timeout", G_TYPE_FROM_CLASS (klass),
1605       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_sender_timeout),
1606       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1607       G_TYPE_UINT, G_TYPE_UINT);
1608
1609   /**
1610    * GstRtpBin::on-npt-stop:
1611    * @rtpbin: the object which received the signal
1612    * @session: the session
1613    * @ssrc: the SSRC
1614    *
1615    * Notify that SSRC sender has sent data up to the configured NPT stop time.
1616    */
1617   gst_rtp_bin_signals[SIGNAL_ON_NPT_STOP] =
1618       g_signal_new ("on-npt-stop", G_TYPE_FROM_CLASS (klass),
1619       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_npt_stop),
1620       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1621       G_TYPE_UINT, G_TYPE_UINT);
1622
1623   g_object_class_install_property (gobject_class, PROP_SDES,
1624       g_param_spec_boxed ("sdes", "SDES",
1625           "The SDES items of this session",
1626           GST_TYPE_STRUCTURE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1627
1628   g_object_class_install_property (gobject_class, PROP_DO_LOST,
1629       g_param_spec_boolean ("do-lost", "Do Lost",
1630           "Send an event downstream when a packet is lost", DEFAULT_DO_LOST,
1631           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1632
1633   g_object_class_install_property (gobject_class, PROP_AUTOREMOVE,
1634       g_param_spec_boolean ("autoremove", "Auto Remove",
1635           "Automatically remove timed out sources", DEFAULT_AUTOREMOVE,
1636           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1637
1638   g_object_class_install_property (gobject_class, PROP_IGNORE_PT,
1639       g_param_spec_boolean ("ignore-pt", "Ignore PT",
1640           "Do not demultiplex based on PT values", DEFAULT_IGNORE_PT,
1641           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1642
1643   g_object_class_install_property (gobject_class, PROP_USE_PIPELINE_CLOCK,
1644       g_param_spec_boolean ("use-pipeline-clock", "Use pipeline clock",
1645           "Use the pipeline clock to set the NTP time in the RTCP SR messages",
1646           DEFAULT_USE_PIPELINE_CLOCK,
1647           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1648   /**
1649    * GstRtpBin::buffer-mode:
1650    *
1651    * Control the buffering and timestamping mode used by the jitterbuffer.
1652    *
1653    * Since: 0.10.17
1654    */
1655   g_object_class_install_property (gobject_class, PROP_BUFFER_MODE,
1656       g_param_spec_enum ("buffer-mode", "Buffer Mode",
1657           "Control the buffering algorithm in use", RTP_TYPE_JITTER_BUFFER_MODE,
1658           DEFAULT_BUFFER_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1659   /**
1660    * GstRtpBin::ntp-sync:
1661    *
1662    * Synchronize received streams to the NTP clock. When the NTP clock is shared
1663    * between the receivers and the senders (such as when using ntpd) this option
1664    * can be used to synchronize receivers on multiple machines.
1665    *
1666    * Since: 0.10.21
1667    */
1668   g_object_class_install_property (gobject_class, PROP_NTP_SYNC,
1669       g_param_spec_boolean ("ntp-sync", "Sync on NTP clock",
1670           "Synchronize received streams to the NTP clock", DEFAULT_NTP_SYNC,
1671           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1672
1673   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
1674   gstelement_class->request_new_pad =
1675       GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
1676   gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_release_pad);
1677
1678   gstbin_class->handle_message = GST_DEBUG_FUNCPTR (gst_rtp_bin_handle_message);
1679
1680   klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map);
1681   klass->reset_sync = GST_DEBUG_FUNCPTR (gst_rtp_bin_reset_sync);
1682   klass->get_internal_session =
1683       GST_DEBUG_FUNCPTR (gst_rtp_bin_get_internal_session);
1684
1685   GST_DEBUG_CATEGORY_INIT (gst_rtp_bin_debug, "rtpbin", 0, "RTP bin");
1686 }
1687
1688 static void
1689 gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass)
1690 {
1691   gchar *str;
1692
1693   rtpbin->priv = GST_RTP_BIN_GET_PRIVATE (rtpbin);
1694   rtpbin->priv->bin_lock = g_mutex_new ();
1695   rtpbin->priv->dyn_lock = g_mutex_new ();
1696
1697   rtpbin->latency_ms = DEFAULT_LATENCY_MS;
1698   rtpbin->latency_ns = DEFAULT_LATENCY_MS * GST_MSECOND;
1699   rtpbin->do_lost = DEFAULT_DO_LOST;
1700   rtpbin->ignore_pt = DEFAULT_IGNORE_PT;
1701   rtpbin->ntp_sync = DEFAULT_NTP_SYNC;
1702   rtpbin->priv->autoremove = DEFAULT_AUTOREMOVE;
1703   rtpbin->buffer_mode = DEFAULT_BUFFER_MODE;
1704   rtpbin->use_pipeline_clock = DEFAULT_USE_PIPELINE_CLOCK;
1705
1706   /* some default SDES entries */
1707   str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ());
1708   rtpbin->sdes = gst_structure_new ("application/x-rtp-source-sdes",
1709       "cname", G_TYPE_STRING, str,
1710       "name", G_TYPE_STRING, g_get_real_name (),
1711       "tool", G_TYPE_STRING, "GStreamer", NULL);
1712   g_free (str);
1713 }
1714
1715 static void
1716 gst_rtp_bin_dispose (GObject * object)
1717 {
1718   GstRtpBin *rtpbin;
1719
1720   rtpbin = GST_RTP_BIN (object);
1721
1722   GST_DEBUG_OBJECT (object, "freeing sessions");
1723   g_slist_foreach (rtpbin->sessions, (GFunc) free_session, rtpbin);
1724   g_slist_free (rtpbin->sessions);
1725   rtpbin->sessions = NULL;
1726   GST_DEBUG_OBJECT (object, "freeing clients");
1727   g_slist_foreach (rtpbin->clients, (GFunc) free_client, rtpbin);
1728   g_slist_free (rtpbin->clients);
1729   rtpbin->clients = NULL;
1730
1731   G_OBJECT_CLASS (parent_class)->dispose (object);
1732 }
1733
1734 static void
1735 gst_rtp_bin_finalize (GObject * object)
1736 {
1737   GstRtpBin *rtpbin;
1738
1739   rtpbin = GST_RTP_BIN (object);
1740
1741   if (rtpbin->sdes)
1742     gst_structure_free (rtpbin->sdes);
1743
1744   g_mutex_free (rtpbin->priv->bin_lock);
1745   g_mutex_free (rtpbin->priv->dyn_lock);
1746
1747   G_OBJECT_CLASS (parent_class)->finalize (object);
1748 }
1749
1750
1751 static void
1752 gst_rtp_bin_set_sdes_struct (GstRtpBin * bin, const GstStructure * sdes)
1753 {
1754   GSList *item;
1755
1756   if (sdes == NULL)
1757     return;
1758
1759   GST_RTP_BIN_LOCK (bin);
1760
1761   GST_OBJECT_LOCK (bin);
1762   if (bin->sdes)
1763     gst_structure_free (bin->sdes);
1764   bin->sdes = gst_structure_copy (sdes);
1765
1766   /* store in all sessions */
1767   for (item = bin->sessions; item; item = g_slist_next (item))
1768     g_object_set (item->data, "sdes", sdes, NULL);
1769   GST_OBJECT_UNLOCK (bin);
1770
1771   GST_RTP_BIN_UNLOCK (bin);
1772 }
1773
1774 static GstStructure *
1775 gst_rtp_bin_get_sdes_struct (GstRtpBin * bin)
1776 {
1777   GstStructure *result;
1778
1779   GST_OBJECT_LOCK (bin);
1780   result = gst_structure_copy (bin->sdes);
1781   GST_OBJECT_UNLOCK (bin);
1782
1783   return result;
1784 }
1785
1786 static void
1787 gst_rtp_bin_set_property (GObject * object, guint prop_id,
1788     const GValue * value, GParamSpec * pspec)
1789 {
1790   GstRtpBin *rtpbin;
1791
1792   rtpbin = GST_RTP_BIN (object);
1793
1794   switch (prop_id) {
1795     case PROP_LATENCY:
1796       GST_RTP_BIN_LOCK (rtpbin);
1797       rtpbin->latency_ms = g_value_get_uint (value);
1798       rtpbin->latency_ns = rtpbin->latency_ms * GST_MSECOND;
1799       GST_RTP_BIN_UNLOCK (rtpbin);
1800       /* propagate the property down to the jitterbuffer */
1801       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "latency", value);
1802       break;
1803     case PROP_SDES:
1804       gst_rtp_bin_set_sdes_struct (rtpbin, g_value_get_boxed (value));
1805       break;
1806     case PROP_DO_LOST:
1807       GST_RTP_BIN_LOCK (rtpbin);
1808       rtpbin->do_lost = g_value_get_boolean (value);
1809       GST_RTP_BIN_UNLOCK (rtpbin);
1810       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "do-lost", value);
1811       break;
1812     case PROP_NTP_SYNC:
1813       rtpbin->ntp_sync = g_value_get_boolean (value);
1814       break;
1815     case PROP_IGNORE_PT:
1816       rtpbin->ignore_pt = g_value_get_boolean (value);
1817       break;
1818     case PROP_AUTOREMOVE:
1819       rtpbin->priv->autoremove = g_value_get_boolean (value);
1820       break;
1821     case PROP_USE_PIPELINE_CLOCK:
1822     {
1823       GSList *sessions;
1824       GST_RTP_BIN_LOCK (rtpbin);
1825       rtpbin->use_pipeline_clock = g_value_get_boolean (value);
1826       for (sessions = rtpbin->sessions; sessions;
1827           sessions = g_slist_next (sessions)) {
1828         GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
1829
1830         g_object_set (G_OBJECT (session->session),
1831             "use-pipeline-clock", rtpbin->use_pipeline_clock, NULL);
1832       }
1833       GST_RTP_BIN_UNLOCK (rtpbin);
1834     }
1835       break;
1836     case PROP_BUFFER_MODE:
1837       GST_RTP_BIN_LOCK (rtpbin);
1838       rtpbin->buffer_mode = g_value_get_enum (value);
1839       GST_RTP_BIN_UNLOCK (rtpbin);
1840       /* propagate the property down to the jitterbuffer */
1841       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "mode", value);
1842       break;
1843     default:
1844       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1845       break;
1846   }
1847 }
1848
1849 static void
1850 gst_rtp_bin_get_property (GObject * object, guint prop_id,
1851     GValue * value, GParamSpec * pspec)
1852 {
1853   GstRtpBin *rtpbin;
1854
1855   rtpbin = GST_RTP_BIN (object);
1856
1857   switch (prop_id) {
1858     case PROP_LATENCY:
1859       GST_RTP_BIN_LOCK (rtpbin);
1860       g_value_set_uint (value, rtpbin->latency_ms);
1861       GST_RTP_BIN_UNLOCK (rtpbin);
1862       break;
1863     case PROP_SDES:
1864       g_value_take_boxed (value, gst_rtp_bin_get_sdes_struct (rtpbin));
1865       break;
1866     case PROP_DO_LOST:
1867       GST_RTP_BIN_LOCK (rtpbin);
1868       g_value_set_boolean (value, rtpbin->do_lost);
1869       GST_RTP_BIN_UNLOCK (rtpbin);
1870       break;
1871     case PROP_IGNORE_PT:
1872       g_value_set_boolean (value, rtpbin->ignore_pt);
1873       break;
1874     case PROP_NTP_SYNC:
1875       g_value_set_boolean (value, rtpbin->ntp_sync);
1876       break;
1877     case PROP_AUTOREMOVE:
1878       g_value_set_boolean (value, rtpbin->priv->autoremove);
1879       break;
1880     case PROP_BUFFER_MODE:
1881       g_value_set_enum (value, rtpbin->buffer_mode);
1882       break;
1883     case PROP_USE_PIPELINE_CLOCK:
1884       g_value_set_boolean (value, rtpbin->use_pipeline_clock);
1885       break;
1886     default:
1887       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1888       break;
1889   }
1890 }
1891
1892 static void
1893 gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
1894 {
1895   GstRtpBin *rtpbin;
1896
1897   rtpbin = GST_RTP_BIN (bin);
1898
1899   switch (GST_MESSAGE_TYPE (message)) {
1900     case GST_MESSAGE_ELEMENT:
1901     {
1902       const GstStructure *s = gst_message_get_structure (message);
1903
1904       /* we change the structure name and add the session ID to it */
1905       if (gst_structure_has_name (s, "application/x-rtp-source-sdes")) {
1906         GstRtpBinSession *sess;
1907
1908         /* find the session we set it as object data */
1909         sess = g_object_get_data (G_OBJECT (GST_MESSAGE_SRC (message)),
1910             "GstRTPBin.session");
1911
1912         if (G_LIKELY (sess)) {
1913           message = gst_message_make_writable (message);
1914           s = gst_message_get_structure (message);
1915           gst_structure_set ((GstStructure *) s, "session", G_TYPE_UINT,
1916               sess->id, NULL);
1917         }
1918       }
1919       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
1920       break;
1921     }
1922     case GST_MESSAGE_BUFFERING:
1923     {
1924       gint percent;
1925       gint min_percent = 100;
1926       GSList *sessions, *streams;
1927       GstRtpBinStream *stream;
1928       gboolean change = FALSE, active = FALSE;
1929       GstClockTime min_out_time;
1930       GstBufferingMode mode;
1931       gint avg_in, avg_out;
1932       gint64 buffering_left;
1933
1934       gst_message_parse_buffering (message, &percent);
1935       gst_message_parse_buffering_stats (message, &mode, &avg_in, &avg_out,
1936           &buffering_left);
1937
1938       stream =
1939           g_object_get_data (G_OBJECT (GST_MESSAGE_SRC (message)),
1940           "GstRTPBin.stream");
1941
1942       GST_DEBUG_OBJECT (bin, "got percent %d from stream %p", percent, stream);
1943
1944       /* get the stream */
1945       if (G_LIKELY (stream)) {
1946         GST_RTP_BIN_LOCK (rtpbin);
1947         /* fill in the percent */
1948         stream->percent = percent;
1949
1950         /* calculate the min value for all streams */
1951         for (sessions = rtpbin->sessions; sessions;
1952             sessions = g_slist_next (sessions)) {
1953           GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
1954
1955           GST_RTP_SESSION_LOCK (session);
1956           if (session->streams) {
1957             for (streams = session->streams; streams;
1958                 streams = g_slist_next (streams)) {
1959               GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
1960
1961               GST_DEBUG_OBJECT (bin, "stream %p percent %d", stream,
1962                   stream->percent);
1963
1964               /* find min percent */
1965               if (min_percent > stream->percent)
1966                 min_percent = stream->percent;
1967             }
1968           } else {
1969             GST_INFO_OBJECT (bin,
1970                 "session has no streams, setting min_percent to 0");
1971             min_percent = 0;
1972           }
1973           GST_RTP_SESSION_UNLOCK (session);
1974         }
1975         GST_DEBUG_OBJECT (bin, "min percent %d", min_percent);
1976
1977         if (rtpbin->buffering) {
1978           if (min_percent == 100) {
1979             rtpbin->buffering = FALSE;
1980             active = TRUE;
1981             change = TRUE;
1982           }
1983         } else {
1984           if (min_percent < 100) {
1985             /* pause the streams */
1986             rtpbin->buffering = TRUE;
1987             active = FALSE;
1988             change = TRUE;
1989           }
1990         }
1991         GST_RTP_BIN_UNLOCK (rtpbin);
1992
1993         gst_message_unref (message);
1994
1995         /* make a new buffering message with the min value */
1996         message =
1997             gst_message_new_buffering (GST_OBJECT_CAST (bin), min_percent);
1998         gst_message_set_buffering_stats (message, mode, avg_in, avg_out,
1999             buffering_left);
2000
2001         if (G_UNLIKELY (change)) {
2002           GstClock *clock;
2003           guint64 running_time = 0;
2004           guint64 offset = 0;
2005
2006           /* figure out the running time when we have a clock */
2007           if (G_LIKELY ((clock =
2008                       gst_element_get_clock (GST_ELEMENT_CAST (bin))))) {
2009             guint64 now, base_time;
2010
2011             now = gst_clock_get_time (clock);
2012             base_time = gst_element_get_base_time (GST_ELEMENT_CAST (bin));
2013             running_time = now - base_time;
2014           }
2015           GST_DEBUG_OBJECT (bin,
2016               "running time now %" GST_TIME_FORMAT,
2017               GST_TIME_ARGS (running_time));
2018
2019           GST_RTP_BIN_LOCK (rtpbin);
2020
2021           /* when we reactivate, calculate the offsets so that all streams have
2022            * an output time that is at least as big as the running_time */
2023           offset = 0;
2024           if (active) {
2025             if (running_time > rtpbin->buffer_start) {
2026               offset = running_time - rtpbin->buffer_start;
2027               if (offset >= rtpbin->latency_ns)
2028                 offset -= rtpbin->latency_ns;
2029               else
2030                 offset = 0;
2031             }
2032           }
2033
2034           /* pause all streams */
2035           min_out_time = -1;
2036           for (sessions = rtpbin->sessions; sessions;
2037               sessions = g_slist_next (sessions)) {
2038             GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
2039
2040             GST_RTP_SESSION_LOCK (session);
2041             for (streams = session->streams; streams;
2042                 streams = g_slist_next (streams)) {
2043               GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
2044               GstElement *element = stream->buffer;
2045               guint64 last_out;
2046
2047               g_signal_emit_by_name (element, "set-active", active, offset,
2048                   &last_out);
2049
2050               if (!active) {
2051                 g_object_get (element, "percent", &stream->percent, NULL);
2052
2053                 if (last_out == -1)
2054                   last_out = 0;
2055                 if (min_out_time == -1 || last_out < min_out_time)
2056                   min_out_time = last_out;
2057               }
2058
2059               GST_DEBUG_OBJECT (bin,
2060                   "setting %p to %d, offset %" GST_TIME_FORMAT ", last %"
2061                   GST_TIME_FORMAT ", percent %d", element, active,
2062                   GST_TIME_ARGS (offset), GST_TIME_ARGS (last_out),
2063                   stream->percent);
2064             }
2065             GST_RTP_SESSION_UNLOCK (session);
2066           }
2067           GST_DEBUG_OBJECT (bin,
2068               "min out time %" GST_TIME_FORMAT, GST_TIME_ARGS (min_out_time));
2069
2070           /* the buffer_start is the min out time of all paused jitterbuffers */
2071           if (!active)
2072             rtpbin->buffer_start = min_out_time;
2073
2074           GST_RTP_BIN_UNLOCK (rtpbin);
2075         }
2076       }
2077       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
2078       break;
2079     }
2080     default:
2081     {
2082       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
2083       break;
2084     }
2085   }
2086 }
2087
2088 static GstStateChangeReturn
2089 gst_rtp_bin_change_state (GstElement * element, GstStateChange transition)
2090 {
2091   GstStateChangeReturn res;
2092   GstRtpBin *rtpbin;
2093   GstRtpBinPrivate *priv;
2094
2095   rtpbin = GST_RTP_BIN (element);
2096   priv = rtpbin->priv;
2097
2098   switch (transition) {
2099     case GST_STATE_CHANGE_NULL_TO_READY:
2100       break;
2101     case GST_STATE_CHANGE_READY_TO_PAUSED:
2102       GST_LOG_OBJECT (rtpbin, "clearing shutdown flag");
2103       g_atomic_int_set (&priv->shutdown, 0);
2104       break;
2105     case GST_STATE_CHANGE_PAUSED_TO_READY:
2106       GST_LOG_OBJECT (rtpbin, "setting shutdown flag");
2107       g_atomic_int_set (&priv->shutdown, 1);
2108       /* wait for all callbacks to end by taking the lock. No new callbacks will
2109        * be able to happen as we set the shutdown flag. */
2110       GST_RTP_BIN_DYN_LOCK (rtpbin);
2111       GST_LOG_OBJECT (rtpbin, "dynamic lock taken, we can continue shutdown");
2112       GST_RTP_BIN_DYN_UNLOCK (rtpbin);
2113       break;
2114     default:
2115       break;
2116   }
2117
2118   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2119
2120   switch (transition) {
2121     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2122       break;
2123     case GST_STATE_CHANGE_PAUSED_TO_READY:
2124       break;
2125     case GST_STATE_CHANGE_READY_TO_NULL:
2126       break;
2127     default:
2128       break;
2129   }
2130   return res;
2131 }
2132
2133 /* a new pad (SSRC) was created in @session. This signal is emited from the
2134  * payload demuxer. */
2135 static void
2136 new_payload_found (GstElement * element, guint pt, GstPad * pad,
2137     GstRtpBinStream * stream)
2138 {
2139   GstRtpBin *rtpbin;
2140   GstElementClass *klass;
2141   GstPadTemplate *templ;
2142   gchar *padname;
2143   GstPad *gpad;
2144
2145   rtpbin = stream->bin;
2146
2147   GST_DEBUG ("new payload pad %d", pt);
2148
2149   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
2150
2151   /* ghost the pad to the parent */
2152   klass = GST_ELEMENT_GET_CLASS (rtpbin);
2153   templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%d_%d_%d");
2154   padname = g_strdup_printf ("recv_rtp_src_%d_%u_%d",
2155       stream->session->id, stream->ssrc, pt);
2156   gpad = gst_ghost_pad_new_from_template (padname, pad, templ);
2157   g_free (padname);
2158   g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", gpad);
2159
2160   gst_pad_set_caps (gpad, GST_PAD_CAPS (pad));
2161   gst_pad_set_active (gpad, TRUE);
2162   GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
2163
2164   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad);
2165
2166   return;
2167
2168 shutdown:
2169   {
2170     GST_DEBUG ("ignoring, we are shutting down");
2171     return;
2172   }
2173 }
2174
2175 static void
2176 payload_pad_removed (GstElement * element, GstPad * pad,
2177     GstRtpBinStream * stream)
2178 {
2179   GstRtpBin *rtpbin;
2180   GstPad *gpad;
2181
2182   rtpbin = stream->bin;
2183
2184   GST_DEBUG ("payload pad removed");
2185
2186   GST_RTP_BIN_DYN_LOCK (rtpbin);
2187   if ((gpad = g_object_get_data (G_OBJECT (pad), "GstRTPBin.ghostpad"))) {
2188     g_object_set_data (G_OBJECT (pad), "GstRTPBin.ghostpad", NULL);
2189
2190     gst_pad_set_active (gpad, FALSE);
2191     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin), gpad);
2192   }
2193   GST_RTP_BIN_DYN_UNLOCK (rtpbin);
2194 }
2195
2196 static GstCaps *
2197 pt_map_requested (GstElement * element, guint pt, GstRtpBinSession * session)
2198 {
2199   GstRtpBin *rtpbin;
2200   GstCaps *caps;
2201
2202   rtpbin = session->bin;
2203
2204   GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %d in session %d", pt,
2205       session->id);
2206
2207   caps = get_pt_map (session, pt);
2208   if (!caps)
2209     goto no_caps;
2210
2211   return caps;
2212
2213   /* ERRORS */
2214 no_caps:
2215   {
2216     GST_DEBUG_OBJECT (rtpbin, "could not get caps");
2217     return NULL;
2218   }
2219 }
2220
2221 static void
2222 payload_type_change (GstElement * element, guint pt, GstRtpBinSession * session)
2223 {
2224   GST_DEBUG_OBJECT (session->bin,
2225       "emiting signal for pt type changed to %d in session %d", pt,
2226       session->id);
2227
2228   g_signal_emit (session->bin, gst_rtp_bin_signals[SIGNAL_PAYLOAD_TYPE_CHANGE],
2229       0, session->id, pt);
2230 }
2231
2232 /* emited when caps changed for the session */
2233 static void
2234 caps_changed (GstPad * pad, GParamSpec * pspec, GstRtpBinSession * session)
2235 {
2236   GstRtpBin *bin;
2237   GstCaps *caps;
2238   gint payload;
2239   const GstStructure *s;
2240
2241   bin = session->bin;
2242
2243   g_object_get (pad, "caps", &caps, NULL);
2244
2245   if (caps == NULL)
2246     return;
2247
2248   GST_DEBUG_OBJECT (bin, "got caps %" GST_PTR_FORMAT, caps);
2249
2250   s = gst_caps_get_structure (caps, 0);
2251
2252   /* get payload, finish when it's not there */
2253   if (!gst_structure_get_int (s, "payload", &payload))
2254     return;
2255
2256   GST_RTP_SESSION_LOCK (session);
2257   GST_DEBUG_OBJECT (bin, "insert caps for payload %d", payload);
2258   g_hash_table_insert (session->ptmap, GINT_TO_POINTER (payload), caps);
2259   GST_RTP_SESSION_UNLOCK (session);
2260 }
2261
2262 /* a new pad (SSRC) was created in @session */
2263 static void
2264 new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
2265     GstRtpBinSession * session)
2266 {
2267   GstRtpBin *rtpbin;
2268   GstRtpBinStream *stream;
2269   GstPad *sinkpad, *srcpad;
2270   gchar *padname;
2271
2272   rtpbin = session->bin;
2273
2274   GST_DEBUG_OBJECT (rtpbin, "new SSRC pad %08x, %s:%s", ssrc,
2275       GST_DEBUG_PAD_NAME (pad));
2276
2277   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
2278
2279   GST_RTP_SESSION_LOCK (session);
2280
2281   /* create new stream */
2282   stream = create_stream (session, ssrc);
2283   if (!stream)
2284     goto no_stream;
2285
2286   /* get pad and link */
2287   GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTP");
2288   padname = g_strdup_printf ("src_%d", ssrc);
2289   srcpad = gst_element_get_static_pad (element, padname);
2290   g_free (padname);
2291   sinkpad = gst_element_get_static_pad (stream->buffer, "sink");
2292   gst_pad_link (srcpad, sinkpad);
2293   gst_object_unref (sinkpad);
2294   gst_object_unref (srcpad);
2295
2296   GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer RTCP");
2297   padname = g_strdup_printf ("rtcp_src_%d", ssrc);
2298   srcpad = gst_element_get_static_pad (element, padname);
2299   g_free (padname);
2300   sinkpad = gst_element_get_request_pad (stream->buffer, "sink_rtcp");
2301   gst_pad_link (srcpad, sinkpad);
2302   gst_object_unref (sinkpad);
2303   gst_object_unref (srcpad);
2304
2305   /* connect to the RTCP sync signal from the jitterbuffer */
2306   GST_DEBUG_OBJECT (rtpbin, "connecting sync signal");
2307   stream->buffer_handlesync_sig = g_signal_connect (stream->buffer,
2308       "handle-sync", (GCallback) gst_rtp_bin_handle_sync, stream);
2309
2310   if (stream->demux) {
2311     /* connect to the new-pad signal of the payload demuxer, this will expose the
2312      * new pad by ghosting it. */
2313     stream->demux_newpad_sig = g_signal_connect (stream->demux,
2314         "new-payload-type", (GCallback) new_payload_found, stream);
2315     stream->demux_padremoved_sig = g_signal_connect (stream->demux,
2316         "pad-removed", (GCallback) payload_pad_removed, stream);
2317
2318     /* connect to the request-pt-map signal. This signal will be emited by the
2319      * demuxer so that it can apply a proper caps on the buffers for the
2320      * depayloaders. */
2321     stream->demux_ptreq_sig = g_signal_connect (stream->demux,
2322         "request-pt-map", (GCallback) pt_map_requested, session);
2323     /* connect to the  signal so it can be forwarded. */
2324     stream->demux_ptchange_sig = g_signal_connect (stream->demux,
2325         "payload-type-change", (GCallback) payload_type_change, session);
2326   } else {
2327     /* add gstrtpjitterbuffer src pad to pads */
2328     GstElementClass *klass;
2329     GstPadTemplate *templ;
2330     gchar *padname;
2331     GstPad *gpad, *pad;
2332
2333     pad = gst_element_get_static_pad (stream->buffer, "src");
2334
2335     /* ghost the pad to the parent */
2336     klass = GST_ELEMENT_GET_CLASS (rtpbin);
2337     templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%d_%d_%d");
2338     padname = g_strdup_printf ("recv_rtp_src_%d_%u_%d",
2339         stream->session->id, stream->ssrc, 255);
2340     gpad = gst_ghost_pad_new_from_template (padname, pad, templ);
2341     g_free (padname);
2342
2343     gst_pad_set_caps (gpad, GST_PAD_CAPS (pad));
2344     gst_pad_set_active (gpad, TRUE);
2345     gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad);
2346
2347     gst_object_unref (pad);
2348   }
2349
2350   GST_RTP_SESSION_UNLOCK (session);
2351   GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
2352
2353   return;
2354
2355   /* ERRORS */
2356 shutdown:
2357   {
2358     GST_DEBUG_OBJECT (rtpbin, "we are shutting down");
2359     return;
2360   }
2361 no_stream:
2362   {
2363     GST_RTP_SESSION_UNLOCK (session);
2364     GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
2365     GST_DEBUG_OBJECT (rtpbin, "could not create stream");
2366     return;
2367   }
2368 }
2369
2370 /* Create a pad for receiving RTP for the session in @name. Must be called with
2371  * RTP_BIN_LOCK.
2372  */
2373 static GstPad *
2374 create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
2375 {
2376   GstPad *sinkdpad;
2377   guint sessid;
2378   GstRtpBinSession *session;
2379   GstPadLinkReturn lres;
2380
2381   /* first get the session number */
2382   if (name == NULL || sscanf (name, "recv_rtp_sink_%d", &sessid) != 1)
2383     goto no_name;
2384
2385   GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
2386
2387   /* get or create session */
2388   session = find_session_by_id (rtpbin, sessid);
2389   if (!session) {
2390     GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
2391     /* create session now */
2392     session = create_session (rtpbin, sessid);
2393     if (session == NULL)
2394       goto create_error;
2395   }
2396
2397   /* check if pad was requested */
2398   if (session->recv_rtp_sink_ghost != NULL)
2399     return session->recv_rtp_sink_ghost;
2400
2401   GST_DEBUG_OBJECT (rtpbin, "getting RTP sink pad");
2402   /* get recv_rtp pad and store */
2403   session->recv_rtp_sink =
2404       gst_element_get_request_pad (session->session, "recv_rtp_sink");
2405   if (session->recv_rtp_sink == NULL)
2406     goto pad_failed;
2407
2408   g_signal_connect (session->recv_rtp_sink, "notify::caps",
2409       (GCallback) caps_changed, session);
2410
2411   GST_DEBUG_OBJECT (rtpbin, "getting RTP src pad");
2412   /* get srcpad, link to SSRCDemux */
2413   session->recv_rtp_src =
2414       gst_element_get_static_pad (session->session, "recv_rtp_src");
2415   if (session->recv_rtp_src == NULL)
2416     goto pad_failed;
2417
2418   GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTP sink pad");
2419   sinkdpad = gst_element_get_static_pad (session->demux, "sink");
2420   GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
2421   lres = gst_pad_link (session->recv_rtp_src, sinkdpad);
2422   gst_object_unref (sinkdpad);
2423   if (lres != GST_PAD_LINK_OK)
2424     goto link_failed;
2425
2426   /* connect to the new-ssrc-pad signal of the SSRC demuxer */
2427   session->demux_newpad_sig = g_signal_connect (session->demux,
2428       "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session);
2429   session->demux_padremoved_sig = g_signal_connect (session->demux,
2430       "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session);
2431
2432   GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
2433   session->recv_rtp_sink_ghost =
2434       gst_ghost_pad_new_from_template (name, session->recv_rtp_sink, templ);
2435   gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
2436   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
2437
2438   return session->recv_rtp_sink_ghost;
2439
2440   /* ERRORS */
2441 no_name:
2442   {
2443     g_warning ("gstrtpbin: invalid name given");
2444     return NULL;
2445   }
2446 create_error:
2447   {
2448     /* create_session already warned */
2449     return NULL;
2450   }
2451 pad_failed:
2452   {
2453     g_warning ("gstrtpbin: failed to get session pad");
2454     return NULL;
2455   }
2456 link_failed:
2457   {
2458     g_warning ("gstrtpbin: failed to link pads");
2459     return NULL;
2460   }
2461 }
2462
2463 static void
2464 remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
2465 {
2466   if (session->demux_newpad_sig) {
2467     g_signal_handler_disconnect (session->demux, session->demux_newpad_sig);
2468     session->demux_newpad_sig = 0;
2469   }
2470   if (session->demux_padremoved_sig) {
2471     g_signal_handler_disconnect (session->demux, session->demux_padremoved_sig);
2472     session->demux_padremoved_sig = 0;
2473   }
2474   if (session->recv_rtp_src) {
2475     gst_object_unref (session->recv_rtp_src);
2476     session->recv_rtp_src = NULL;
2477   }
2478   if (session->recv_rtp_sink) {
2479     gst_element_release_request_pad (session->session, session->recv_rtp_sink);
2480     gst_object_unref (session->recv_rtp_sink);
2481     session->recv_rtp_sink = NULL;
2482   }
2483   if (session->recv_rtp_sink_ghost) {
2484     gst_pad_set_active (session->recv_rtp_sink_ghost, FALSE);
2485     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
2486         session->recv_rtp_sink_ghost);
2487     session->recv_rtp_sink_ghost = NULL;
2488   }
2489 }
2490
2491 /* Create a pad for receiving RTCP for the session in @name. Must be called with
2492  * RTP_BIN_LOCK.
2493  */
2494 static GstPad *
2495 create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
2496     const gchar * name)
2497 {
2498   guint sessid;
2499   GstRtpBinSession *session;
2500   GstPad *sinkdpad;
2501   GstPadLinkReturn lres;
2502
2503   /* first get the session number */
2504   if (name == NULL || sscanf (name, "recv_rtcp_sink_%d", &sessid) != 1)
2505     goto no_name;
2506
2507   GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
2508
2509   /* get or create the session */
2510   session = find_session_by_id (rtpbin, sessid);
2511   if (!session) {
2512     GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
2513     /* create session now */
2514     session = create_session (rtpbin, sessid);
2515     if (session == NULL)
2516       goto create_error;
2517   }
2518
2519   /* check if pad was requested */
2520   if (session->recv_rtcp_sink_ghost != NULL)
2521     return session->recv_rtcp_sink_ghost;
2522
2523   /* get recv_rtp pad and store */
2524   GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad");
2525   session->recv_rtcp_sink =
2526       gst_element_get_request_pad (session->session, "recv_rtcp_sink");
2527   if (session->recv_rtcp_sink == NULL)
2528     goto pad_failed;
2529
2530   /* get srcpad, link to SSRCDemux */
2531   GST_DEBUG_OBJECT (rtpbin, "getting sync src pad");
2532   session->sync_src = gst_element_get_static_pad (session->session, "sync_src");
2533   if (session->sync_src == NULL)
2534     goto pad_failed;
2535
2536   GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTCP sink pad");
2537   sinkdpad = gst_element_get_static_pad (session->demux, "rtcp_sink");
2538   lres = gst_pad_link (session->sync_src, sinkdpad);
2539   gst_object_unref (sinkdpad);
2540   if (lres != GST_PAD_LINK_OK)
2541     goto link_failed;
2542
2543   session->recv_rtcp_sink_ghost =
2544       gst_ghost_pad_new_from_template (name, session->recv_rtcp_sink, templ);
2545   gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE);
2546   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin),
2547       session->recv_rtcp_sink_ghost);
2548
2549   return session->recv_rtcp_sink_ghost;
2550
2551   /* ERRORS */
2552 no_name:
2553   {
2554     g_warning ("gstrtpbin: invalid name given");
2555     return NULL;
2556   }
2557 create_error:
2558   {
2559     /* create_session already warned */
2560     return NULL;
2561   }
2562 pad_failed:
2563   {
2564     g_warning ("gstrtpbin: failed to get session pad");
2565     return NULL;
2566   }
2567 link_failed:
2568   {
2569     g_warning ("gstrtpbin: failed to link pads");
2570     return NULL;
2571   }
2572 }
2573
2574 static void
2575 remove_recv_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session)
2576 {
2577   if (session->recv_rtcp_sink_ghost) {
2578     gst_pad_set_active (session->recv_rtcp_sink_ghost, FALSE);
2579     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
2580         session->recv_rtcp_sink_ghost);
2581     session->recv_rtcp_sink_ghost = NULL;
2582   }
2583   if (session->sync_src) {
2584     /* releasing the request pad should also unref the sync pad */
2585     gst_object_unref (session->sync_src);
2586     session->sync_src = NULL;
2587   }
2588   if (session->recv_rtcp_sink) {
2589     gst_element_release_request_pad (session->session, session->recv_rtcp_sink);
2590     gst_object_unref (session->recv_rtcp_sink);
2591     session->recv_rtcp_sink = NULL;
2592   }
2593 }
2594
2595 /* Create a pad for sending RTP for the session in @name. Must be called with
2596  * RTP_BIN_LOCK.
2597  */
2598 static GstPad *
2599 create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
2600 {
2601   gchar *gname;
2602   guint sessid;
2603   GstRtpBinSession *session;
2604   GstElementClass *klass;
2605
2606   /* first get the session number */
2607   if (name == NULL || sscanf (name, "send_rtp_sink_%d", &sessid) != 1)
2608     goto no_name;
2609
2610   /* get or create session */
2611   session = find_session_by_id (rtpbin, sessid);
2612   if (!session) {
2613     /* create session now */
2614     session = create_session (rtpbin, sessid);
2615     if (session == NULL)
2616       goto create_error;
2617   }
2618
2619   /* check if pad was requested */
2620   if (session->send_rtp_sink_ghost != NULL)
2621     return session->send_rtp_sink_ghost;
2622
2623   /* get send_rtp pad and store */
2624   session->send_rtp_sink =
2625       gst_element_get_request_pad (session->session, "send_rtp_sink");
2626   if (session->send_rtp_sink == NULL)
2627     goto pad_failed;
2628
2629   session->send_rtp_sink_ghost =
2630       gst_ghost_pad_new_from_template (name, session->send_rtp_sink, templ);
2631   gst_pad_set_active (session->send_rtp_sink_ghost, TRUE);
2632   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_sink_ghost);
2633
2634   /* get srcpad */
2635   session->send_rtp_src =
2636       gst_element_get_static_pad (session->session, "send_rtp_src");
2637   if (session->send_rtp_src == NULL)
2638     goto no_srcpad;
2639
2640   /* ghost the new source pad */
2641   klass = GST_ELEMENT_GET_CLASS (rtpbin);
2642   gname = g_strdup_printf ("send_rtp_src_%d", sessid);
2643   templ = gst_element_class_get_pad_template (klass, "send_rtp_src_%d");
2644   session->send_rtp_src_ghost =
2645       gst_ghost_pad_new_from_template (gname, session->send_rtp_src, templ);
2646   gst_pad_set_active (session->send_rtp_src_ghost, TRUE);
2647   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtp_src_ghost);
2648   g_free (gname);
2649
2650   return session->send_rtp_sink_ghost;
2651
2652   /* ERRORS */
2653 no_name:
2654   {
2655     g_warning ("gstrtpbin: invalid name given");
2656     return NULL;
2657   }
2658 create_error:
2659   {
2660     /* create_session already warned */
2661     return NULL;
2662   }
2663 pad_failed:
2664   {
2665     g_warning ("gstrtpbin: failed to get session pad for session %d", sessid);
2666     return NULL;
2667   }
2668 no_srcpad:
2669   {
2670     g_warning ("gstrtpbin: failed to get rtp source pad for session %d",
2671         sessid);
2672     return NULL;
2673   }
2674 }
2675
2676 static void
2677 remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
2678 {
2679   if (session->send_rtp_src_ghost) {
2680     gst_pad_set_active (session->send_rtp_src_ghost, FALSE);
2681     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
2682         session->send_rtp_src_ghost);
2683     session->send_rtp_src_ghost = NULL;
2684   }
2685   if (session->send_rtp_src) {
2686     gst_object_unref (session->send_rtp_src);
2687     session->send_rtp_src = NULL;
2688   }
2689   if (session->send_rtp_sink) {
2690     gst_element_release_request_pad (GST_ELEMENT_CAST (session->session),
2691         session->send_rtp_sink);
2692     gst_object_unref (session->send_rtp_sink);
2693     session->send_rtp_sink = NULL;
2694   }
2695   if (session->send_rtp_sink_ghost) {
2696     gst_pad_set_active (session->send_rtp_sink_ghost, FALSE);
2697     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
2698         session->send_rtp_sink_ghost);
2699     session->send_rtp_sink_ghost = NULL;
2700   }
2701 }
2702
2703 /* Create a pad for sending RTCP for the session in @name. Must be called with
2704  * RTP_BIN_LOCK.
2705  */
2706 static GstPad *
2707 create_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
2708 {
2709   guint sessid;
2710   GstRtpBinSession *session;
2711
2712   /* first get the session number */
2713   if (name == NULL || sscanf (name, "send_rtcp_src_%d", &sessid) != 1)
2714     goto no_name;
2715
2716   /* get or create session */
2717   session = find_session_by_id (rtpbin, sessid);
2718   if (!session)
2719     goto no_session;
2720
2721   /* check if pad was requested */
2722   if (session->send_rtcp_src_ghost != NULL)
2723     return session->send_rtcp_src_ghost;
2724
2725   /* get rtcp_src pad and store */
2726   session->send_rtcp_src =
2727       gst_element_get_request_pad (session->session, "send_rtcp_src");
2728   if (session->send_rtcp_src == NULL)
2729     goto pad_failed;
2730
2731   session->send_rtcp_src_ghost =
2732       gst_ghost_pad_new_from_template (name, session->send_rtcp_src, templ);
2733   gst_pad_set_active (session->send_rtcp_src_ghost, TRUE);
2734   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->send_rtcp_src_ghost);
2735
2736   return session->send_rtcp_src_ghost;
2737
2738   /* ERRORS */
2739 no_name:
2740   {
2741     g_warning ("gstrtpbin: invalid name given");
2742     return NULL;
2743   }
2744 no_session:
2745   {
2746     g_warning ("gstrtpbin: session with id %d does not exist", sessid);
2747     return NULL;
2748   }
2749 pad_failed:
2750   {
2751     g_warning ("gstrtpbin: failed to get rtcp pad for session %d", sessid);
2752     return NULL;
2753   }
2754 }
2755
2756 static void
2757 remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session)
2758 {
2759   if (session->send_rtcp_src_ghost) {
2760     gst_pad_set_active (session->send_rtcp_src_ghost, FALSE);
2761     gst_element_remove_pad (GST_ELEMENT_CAST (rtpbin),
2762         session->send_rtcp_src_ghost);
2763     session->send_rtcp_src_ghost = NULL;
2764   }
2765   if (session->send_rtcp_src) {
2766     gst_element_release_request_pad (session->session, session->send_rtcp_src);
2767     gst_object_unref (session->send_rtcp_src);
2768     session->send_rtcp_src = NULL;
2769   }
2770 }
2771
2772 /* If the requested name is NULL we should create a name with
2773  * the session number assuming we want the lowest posible session
2774  * with a free pad like the template */
2775 static gchar *
2776 gst_rtp_bin_get_free_pad_name (GstElement * element, GstPadTemplate * templ)
2777 {
2778   gboolean name_found = FALSE;
2779   gint session = 0;
2780   GstIterator *pad_it = NULL;
2781   gchar *pad_name = NULL;
2782
2783   GST_DEBUG_OBJECT (element, "find a free pad name for template");
2784   while (!name_found) {
2785     gboolean done = FALSE;
2786     g_free (pad_name);
2787     pad_name = g_strdup_printf (templ->name_template, session++);
2788     pad_it = gst_element_iterate_pads (GST_ELEMENT (element));
2789     name_found = TRUE;
2790     while (!done) {
2791       gpointer data;
2792
2793       switch (gst_iterator_next (pad_it, &data)) {
2794         case GST_ITERATOR_OK:
2795         {
2796           GstPad *pad;
2797           gchar *name;
2798
2799           pad = GST_PAD_CAST (data);
2800           name = gst_pad_get_name (pad);
2801
2802           if (strcmp (name, pad_name) == 0) {
2803             done = TRUE;
2804             name_found = FALSE;
2805           }
2806           g_free (name);
2807           gst_object_unref (pad);
2808           break;
2809         }
2810         case GST_ITERATOR_ERROR:
2811         case GST_ITERATOR_RESYNC:
2812           /* restart iteration */
2813           done = TRUE;
2814           name_found = FALSE;
2815           session = 0;
2816           break;
2817         case GST_ITERATOR_DONE:
2818           done = TRUE;
2819           break;
2820       }
2821     }
2822     gst_iterator_free (pad_it);
2823   }
2824
2825   GST_DEBUG_OBJECT (element, "free pad name found: '%s'", pad_name);
2826   return pad_name;
2827 }
2828
2829 /*
2830  */
2831 static GstPad *
2832 gst_rtp_bin_request_new_pad (GstElement * element,
2833     GstPadTemplate * templ, const gchar * name)
2834 {
2835   GstRtpBin *rtpbin;
2836   GstElementClass *klass;
2837   GstPad *result;
2838
2839   gchar *pad_name = NULL;
2840
2841   g_return_val_if_fail (templ != NULL, NULL);
2842   g_return_val_if_fail (GST_IS_RTP_BIN (element), NULL);
2843
2844   rtpbin = GST_RTP_BIN (element);
2845   klass = GST_ELEMENT_GET_CLASS (element);
2846
2847   GST_RTP_BIN_LOCK (rtpbin);
2848
2849   if (name == NULL) {
2850     /* use a free pad name */
2851     pad_name = gst_rtp_bin_get_free_pad_name (element, templ);
2852   } else {
2853     /* use the provided name */
2854     pad_name = g_strdup (name);
2855   }
2856
2857   GST_DEBUG_OBJECT (rtpbin, "Trying to request a pad with name %s", pad_name);
2858
2859   /* figure out the template */
2860   if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink_%d")) {
2861     result = create_recv_rtp (rtpbin, templ, pad_name);
2862   } else if (templ == gst_element_class_get_pad_template (klass,
2863           "recv_rtcp_sink_%d")) {
2864     result = create_recv_rtcp (rtpbin, templ, pad_name);
2865   } else if (templ == gst_element_class_get_pad_template (klass,
2866           "send_rtp_sink_%d")) {
2867     result = create_send_rtp (rtpbin, templ, pad_name);
2868   } else if (templ == gst_element_class_get_pad_template (klass,
2869           "send_rtcp_src_%d")) {
2870     result = create_rtcp (rtpbin, templ, pad_name);
2871   } else
2872     goto wrong_template;
2873
2874   g_free (pad_name);
2875   GST_RTP_BIN_UNLOCK (rtpbin);
2876
2877   return result;
2878
2879   /* ERRORS */
2880 wrong_template:
2881   {
2882     g_free (pad_name);
2883     GST_RTP_BIN_UNLOCK (rtpbin);
2884     g_warning ("gstrtpbin: this is not our template");
2885     return NULL;
2886   }
2887 }
2888
2889 static void
2890 gst_rtp_bin_release_pad (GstElement * element, GstPad * pad)
2891 {
2892   GstRtpBinSession *session;
2893   GstRtpBin *rtpbin;
2894
2895   g_return_if_fail (GST_IS_GHOST_PAD (pad));
2896   g_return_if_fail (GST_IS_RTP_BIN (element));
2897
2898   rtpbin = GST_RTP_BIN (element);
2899
2900   GST_RTP_BIN_LOCK (rtpbin);
2901   GST_DEBUG_OBJECT (rtpbin, "Trying to release pad %s:%s",
2902       GST_DEBUG_PAD_NAME (pad));
2903
2904   if (!(session = find_session_by_pad (rtpbin, pad)))
2905     goto unknown_pad;
2906
2907   if (session->recv_rtp_sink_ghost == pad) {
2908     remove_recv_rtp (rtpbin, session);
2909   } else if (session->recv_rtcp_sink_ghost == pad) {
2910     remove_recv_rtcp (rtpbin, session);
2911   } else if (session->send_rtp_sink_ghost == pad) {
2912     remove_send_rtp (rtpbin, session);
2913   } else if (session->send_rtcp_src_ghost == pad) {
2914     remove_rtcp (rtpbin, session);
2915   }
2916
2917   /* no more request pads, free the complete session */
2918   if (session->recv_rtp_sink_ghost == NULL
2919       && session->recv_rtcp_sink_ghost == NULL
2920       && session->send_rtp_sink_ghost == NULL
2921       && session->send_rtcp_src_ghost == NULL) {
2922     GST_DEBUG_OBJECT (rtpbin, "no more pads for session %p", session);
2923     rtpbin->sessions = g_slist_remove (rtpbin->sessions, session);
2924     free_session (session, rtpbin);
2925   }
2926   GST_RTP_BIN_UNLOCK (rtpbin);
2927
2928   return;
2929
2930   /* ERROR */
2931 unknown_pad:
2932   {
2933     GST_RTP_BIN_UNLOCK (rtpbin);
2934     g_warning ("gstrtpbin: %s:%s is not one of our request pads",
2935         GST_DEBUG_PAD_NAME (pad));
2936     return;
2937   }
2938 }