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