gst/rtpmanager/gstrtpbin.*: Add signal to notify listeners when a sender becomes...
[platform/upstream/gst-plugins-good.git] / gst / rtpmanager / gstrtpbin.c
1 /* GStreamer
2  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 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  * #GstRtpsSrcDemux element. The #GstRtpsSrcDemux element will demux the packets based
38  * on the payload type and will create a unique pad recv_rtp_src_%%d_%%d_%%d on
39  * gstrtpbin with the session number, SSRC and payload type respectively as the pad
40  * name.
41  * 
42  * To also use #GstRtpBin as an RTCP receiver, request a recv_rtcp_sink_%%d pad. The
43  * session number must be specified in the pad name.
44  * 
45  * If you want the session manager to generate and send RTCP packets, request
46  * the send_rtcp_src_%%d pad with the session number in the pad name. Packet pushed
47  * on this pad contain SR/RR RTCP reports that should be sent to all participants
48  * in the session.
49  * 
50  * To use #GstRtpBin as a sender, request a send_rtp_sink_%%d pad, which will
51  * automatically create a send_rtp_src_%%d pad. If the session number is not provided,
52  * the pad from the lowest available session will be returned. The session manager will modify the
53  * SSRC in the RTP packets to its own SSRC and wil forward the packets on the
54  * send_rtp_src_%%d pad after updating its internal state.
55  * 
56  * The session manager needs the clock-rate of the payload types it is handling
57  * and will signal the #GstRtpSession::request-pt-map signal when it needs such a
58  * mapping. One can clear the cached values with the #GstRtpSession::clear-pt-map
59  * signal.
60  * 
61  * <refsect2>
62  * <title>Example pipelines</title>
63  * |[
64  * gst-launch udpsrc port=5000 caps="application/x-rtp, ..." ! .recv_rtp_sink_0 \
65  *     gstrtpbin ! rtptheoradepay ! theoradec ! xvimagesink
66  * ]| Receive RTP data from port 5000 and send to the session 0 in gstrtpbin.
67  * |[
68  * gst-launch gstrtpbin name=rtpbin \
69  *         v4l2src ! ffmpegcolorspace ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \
70  *                   rtpbin.send_rtp_src_0 ! udpsink port=5000                            \
71  *                   rtpbin.send_rtcp_src_0 ! udpsink port=5001 sync=false async=false    \
72  *                   udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
73  *         audiotestsrc ! amrnbenc ! rtpamrpay ! rtpbin.send_rtp_sink_1                   \
74  *                   rtpbin.send_rtp_src_1 ! udpsink port=5002                            \
75  *                   rtpbin.send_rtcp_src_1 ! udpsink port=5003 sync=false async=false    \
76  *                   udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1
77  * ]| Encode and payload H263 video captured from a v4l2src. Encode and payload AMR
78  * audio generated from audiotestsrc. The video is sent to session 0 in rtpbin
79  * and the audio is sent to session 1. Video packets are sent on UDP port 5000
80  * and audio packets on port 5002. The video RTCP packets for session 0 are sent
81  * on port 5001 and the audio RTCP packets for session 0 are sent on port 5003.
82  * RTCP packets for session 0 are received on port 5005 and RTCP for session 1
83  * is received on port 5007. Since RTCP packets from the sender should be sent
84  * as soon as possible and do not participate in preroll, sync=false and 
85  * async=false is configured on udpsink
86  * |[
87  * gst-launch -v gstrtpbin name=rtpbin                                          \
88  *     udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-1998" \
89  *             port=5000 ! rtpbin.recv_rtp_sink_0                                \
90  *         rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink                    \
91  *      udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
92  *      rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
93  *     udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1" \
94  *             port=5002 ! rtpbin.recv_rtp_sink_1                                \
95  *         rtpbin. ! rtpamrdepay ! amrnbdec ! alsasink                           \
96  *      udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
97  *      rtpbin.send_rtcp_src_1 ! udpsink port=5007 sync=false async=false
98  * ]| Receive H263 on port 5000, send it through rtpbin in session 0, depayload,
99  * decode and display the video.
100  * Receive AMR on port 5002, send it through rtpbin in session 1, depayload,
101  * decode and play the audio.
102  * Receive server RTCP packets for session 0 on port 5001 and RTCP packets for
103  * session 1 on port 5003. These packets will be used for session management and
104  * synchronisation.
105  * Send RTCP reports for session 0 on port 5005 and RTCP reports for session 1
106  * on port 5007.
107  * </refsect2>
108  *
109  * Last reviewed on 2007-08-30 (0.10.6)
110  */
111
112 #ifdef HAVE_CONFIG_H
113 #include "config.h"
114 #endif
115 #include <string.h>
116
117 #include <gst/rtp/gstrtpbuffer.h>
118 #include <gst/rtp/gstrtcpbuffer.h>
119
120 #include "gstrtpbin-marshal.h"
121 #include "gstrtpbin.h"
122 #include "gstrtpsession.h"
123 #include "gstrtpjitterbuffer.h"
124
125 GST_DEBUG_CATEGORY_STATIC (gst_rtp_bin_debug);
126 #define GST_CAT_DEFAULT gst_rtp_bin_debug
127
128 /* elementfactory information */
129 static const GstElementDetails rtpbin_details = GST_ELEMENT_DETAILS ("RTP Bin",
130     "Filter/Network/RTP",
131     "Implement an RTP bin",
132     "Wim Taymans <wim.taymans@gmail.com>");
133
134 /* sink pads */
135 static GstStaticPadTemplate rtpbin_recv_rtp_sink_template =
136 GST_STATIC_PAD_TEMPLATE ("recv_rtp_sink_%d",
137     GST_PAD_SINK,
138     GST_PAD_REQUEST,
139     GST_STATIC_CAPS ("application/x-rtp")
140     );
141
142 static GstStaticPadTemplate rtpbin_recv_rtcp_sink_template =
143 GST_STATIC_PAD_TEMPLATE ("recv_rtcp_sink_%d",
144     GST_PAD_SINK,
145     GST_PAD_REQUEST,
146     GST_STATIC_CAPS ("application/x-rtcp")
147     );
148
149 static GstStaticPadTemplate rtpbin_send_rtp_sink_template =
150 GST_STATIC_PAD_TEMPLATE ("send_rtp_sink_%d",
151     GST_PAD_SINK,
152     GST_PAD_REQUEST,
153     GST_STATIC_CAPS ("application/x-rtp")
154     );
155
156 /* src pads */
157 static GstStaticPadTemplate rtpbin_recv_rtp_src_template =
158 GST_STATIC_PAD_TEMPLATE ("recv_rtp_src_%d_%d_%d",
159     GST_PAD_SRC,
160     GST_PAD_SOMETIMES,
161     GST_STATIC_CAPS ("application/x-rtp")
162     );
163
164 static GstStaticPadTemplate rtpbin_send_rtcp_src_template =
165 GST_STATIC_PAD_TEMPLATE ("send_rtcp_src_%d",
166     GST_PAD_SRC,
167     GST_PAD_REQUEST,
168     GST_STATIC_CAPS ("application/x-rtcp")
169     );
170
171 static GstStaticPadTemplate rtpbin_send_rtp_src_template =
172 GST_STATIC_PAD_TEMPLATE ("send_rtp_src_%d",
173     GST_PAD_SRC,
174     GST_PAD_SOMETIMES,
175     GST_STATIC_CAPS ("application/x-rtp")
176     );
177
178 /* padtemplate for the internal pad */
179 static GstStaticPadTemplate rtpbin_sync_sink_template =
180 GST_STATIC_PAD_TEMPLATE ("sink_%d",
181     GST_PAD_SINK,
182     GST_PAD_SOMETIMES,
183     GST_STATIC_CAPS ("application/x-rtcp")
184     );
185
186 #define GST_RTP_BIN_GET_PRIVATE(obj)  \
187    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTP_BIN, GstRtpBinPrivate))
188
189 #define GST_RTP_BIN_LOCK(bin)   g_mutex_lock ((bin)->priv->bin_lock)
190 #define GST_RTP_BIN_UNLOCK(bin) g_mutex_unlock ((bin)->priv->bin_lock)
191
192 /* lock to protect dynamic callbacks, like pad-added and new ssrc. */
193 #define GST_RTP_BIN_DYN_LOCK(bin)    g_mutex_lock ((bin)->priv->dyn_lock)
194 #define GST_RTP_BIN_DYN_UNLOCK(bin)  g_mutex_unlock ((bin)->priv->dyn_lock)
195
196 /* lock for shutdown */
197 #define GST_RTP_BIN_SHUTDOWN_LOCK(bin,label)     \
198 G_STMT_START {                                   \
199   if (g_atomic_int_get (&bin->priv->shutdown))   \
200     goto label;                                  \
201   GST_RTP_BIN_DYN_LOCK (bin);                    \
202   if (g_atomic_int_get (&bin->priv->shutdown)) { \
203     GST_RTP_BIN_DYN_UNLOCK (bin);                \
204     goto label;                                  \
205   }                                              \
206 } G_STMT_END
207
208 /* unlock for shutdown */
209 #define GST_RTP_BIN_SHUTDOWN_UNLOCK(bin)         \
210   GST_RTP_BIN_DYN_UNLOCK (bin);                  \
211
212 struct _GstRtpBinPrivate
213 {
214   GMutex *bin_lock;
215
216   /* lock protecting dynamic adding/removing */
217   GMutex *dyn_lock;
218
219   /* the time when we went to playing */
220   GstClockTime ntp_ns_base;
221
222   /* if we are shutting down or not */
223   gint shutdown;
224 };
225
226 /* signals and args */
227 enum
228 {
229   SIGNAL_REQUEST_PT_MAP,
230   SIGNAL_CLEAR_PT_MAP,
231
232   SIGNAL_ON_NEW_SSRC,
233   SIGNAL_ON_SSRC_COLLISION,
234   SIGNAL_ON_SSRC_VALIDATED,
235   SIGNAL_ON_SSRC_ACTIVE,
236   SIGNAL_ON_SSRC_SDES,
237   SIGNAL_ON_BYE_SSRC,
238   SIGNAL_ON_BYE_TIMEOUT,
239   SIGNAL_ON_TIMEOUT,
240   SIGNAL_ON_SENDER_TIMEOUT,
241   LAST_SIGNAL
242 };
243
244 #define DEFAULT_LATENCY_MS           200
245 #define DEFAULT_SDES_CNAME           NULL
246 #define DEFAULT_SDES_NAME            NULL
247 #define DEFAULT_SDES_EMAIL           NULL
248 #define DEFAULT_SDES_PHONE           NULL
249 #define DEFAULT_SDES_LOCATION        NULL
250 #define DEFAULT_SDES_TOOL            NULL
251 #define DEFAULT_SDES_NOTE            NULL
252 #define DEFAULT_DO_LOST              FALSE
253
254 enum
255 {
256   PROP_0,
257   PROP_LATENCY,
258   PROP_SDES_CNAME,
259   PROP_SDES_NAME,
260   PROP_SDES_EMAIL,
261   PROP_SDES_PHONE,
262   PROP_SDES_LOCATION,
263   PROP_SDES_TOOL,
264   PROP_SDES_NOTE,
265   PROP_DO_LOST,
266   PROP_LAST
267 };
268
269 /* helper objects */
270 typedef struct _GstRtpBinSession GstRtpBinSession;
271 typedef struct _GstRtpBinStream GstRtpBinStream;
272 typedef struct _GstRtpBinClient GstRtpBinClient;
273
274 static guint gst_rtp_bin_signals[LAST_SIGNAL] = { 0 };
275
276 static GstCaps *pt_map_requested (GstElement * element, guint pt,
277     GstRtpBinSession * session);
278 static const gchar *sdes_type_to_name (GstRTCPSDESType type);
279 static void gst_rtp_bin_set_sdes_string (GstRtpBin * bin,
280     GstRTCPSDESType type, const gchar * data);
281
282 static void free_stream (GstRtpBinStream * stream);
283
284 /* Manages the RTP stream for one SSRC.
285  *
286  * We pipe the stream (comming from the SSRC demuxer) into a jitterbuffer.
287  * If we see an SDES RTCP packet that links multiple SSRCs together based on a
288  * common CNAME, we create a GstRtpBinClient structure to group the SSRCs
289  * together (see below).
290  */
291 struct _GstRtpBinStream
292 {
293   /* the SSRC of this stream */
294   guint32 ssrc;
295
296   /* parent bin */
297   GstRtpBin *bin;
298
299   /* the session this SSRC belongs to */
300   GstRtpBinSession *session;
301
302   /* the jitterbuffer of the SSRC */
303   GstElement *buffer;
304
305   /* the PT demuxer of the SSRC */
306   GstElement *demux;
307   gulong demux_newpad_sig;
308   gulong demux_ptreq_sig;
309   gulong demux_pt_change_sig;
310
311   /* the internal pad we use to get RTCP sync messages */
312   GstPad *sync_pad;
313   gboolean have_sync;
314   guint64 last_unix;
315   guint64 last_extrtptime;
316
317   /* mapping to local RTP and NTP time */
318   guint64 local_rtp;
319   guint64 local_unix;
320   gint64 unix_delta;
321
322   /* for lip-sync */
323   guint64 last_clock_base;
324   guint64 clock_base;
325   guint64 clock_base_time;
326   gint clock_rate;
327   gint64 ts_offset;
328   gint last_pt;
329 };
330
331 #define GST_RTP_SESSION_LOCK(sess)   g_mutex_lock ((sess)->lock)
332 #define GST_RTP_SESSION_UNLOCK(sess) g_mutex_unlock ((sess)->lock)
333
334 /* Manages the receiving end of the packets.
335  *
336  * There is one such structure for each RTP session (audio/video/...).
337  * We get the RTP/RTCP packets and stuff them into the session manager. From
338  * there they are pushed into an SSRC demuxer that splits the stream based on
339  * SSRC. Each of the SSRC streams go into their own jitterbuffer (managed with
340  * the GstRtpBinStream above).
341  */
342 struct _GstRtpBinSession
343 {
344   /* session id */
345   gint id;
346   /* the parent bin */
347   GstRtpBin *bin;
348   /* the session element */
349   GstElement *session;
350   /* the SSRC demuxer */
351   GstElement *demux;
352   gulong demux_newpad_sig;
353
354   GMutex *lock;
355
356   /* list of GstRtpBinStream */
357   GSList *streams;
358
359   /* mapping of payload type to caps */
360   GHashTable *ptmap;
361
362   /* the pads of the session */
363   GstPad *recv_rtp_sink;
364   GstPad *recv_rtp_src;
365   GstPad *recv_rtcp_sink;
366   GstPad *sync_src;
367   GstPad *send_rtp_sink;
368   GstPad *send_rtp_src;
369   GstPad *send_rtcp_src;
370 };
371
372 /* Manages the RTP streams that come from one client and should therefore be
373  * synchronized.
374  */
375 struct _GstRtpBinClient
376 {
377   /* the common CNAME for the streams */
378   gchar *cname;
379   guint cname_len;
380
381   /* the streams */
382   guint nstreams;
383   GSList *streams;
384
385   gint64 min_delta;
386 };
387
388 /* find a session with the given id. Must be called with RTP_BIN_LOCK */
389 static GstRtpBinSession *
390 find_session_by_id (GstRtpBin * rtpbin, gint id)
391 {
392   GSList *walk;
393
394   for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) {
395     GstRtpBinSession *sess = (GstRtpBinSession *) walk->data;
396
397     if (sess->id == id)
398       return sess;
399   }
400   return NULL;
401 }
402
403 static void
404 on_new_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
405 {
406   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC], 0,
407       sess->id, ssrc);
408 }
409
410 static void
411 on_ssrc_collision (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
412 {
413   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION], 0,
414       sess->id, ssrc);
415 }
416
417 static void
418 on_ssrc_validated (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
419 {
420   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED], 0,
421       sess->id, ssrc);
422 }
423
424 static void
425 on_ssrc_active (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
426 {
427   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE], 0,
428       sess->id, ssrc);
429 }
430
431 static void
432 on_ssrc_sdes (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
433 {
434   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES], 0,
435       sess->id, ssrc);
436 }
437
438 static void
439 on_bye_ssrc (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
440 {
441   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC], 0,
442       sess->id, ssrc);
443 }
444
445 static void
446 on_bye_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
447 {
448   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT], 0,
449       sess->id, ssrc);
450 }
451
452 static void
453 on_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
454 {
455   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT], 0,
456       sess->id, ssrc);
457 }
458
459 static void
460 on_sender_timeout (GstElement * session, guint32 ssrc, GstRtpBinSession * sess)
461 {
462   g_signal_emit (sess->bin, gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT], 0,
463       sess->id, ssrc);
464 }
465
466 /* create a session with the given id.  Must be called with RTP_BIN_LOCK */
467 static GstRtpBinSession *
468 create_session (GstRtpBin * rtpbin, gint id)
469 {
470   GstRtpBinSession *sess;
471   GstElement *session, *demux;
472   gint i;
473
474   if (!(session = gst_element_factory_make ("gstrtpsession", NULL)))
475     goto no_session;
476
477   if (!(demux = gst_element_factory_make ("gstrtpssrcdemux", NULL)))
478     goto no_demux;
479
480   sess = g_new0 (GstRtpBinSession, 1);
481   sess->lock = g_mutex_new ();
482   sess->id = id;
483   sess->bin = rtpbin;
484   sess->session = session;
485   sess->demux = demux;
486   sess->ptmap = g_hash_table_new_full (NULL, NULL, NULL,
487       (GDestroyNotify) gst_caps_unref);
488   rtpbin->sessions = g_slist_prepend (rtpbin->sessions, sess);
489
490   /* set NTP base or new session */
491   g_object_set (session, "ntp-ns-base", rtpbin->priv->ntp_ns_base, NULL);
492   /* configure SDES items */
493   GST_OBJECT_LOCK (rtpbin);
494   for (i = GST_RTCP_SDES_CNAME; i < GST_RTCP_SDES_PRIV; i++) {
495     g_object_set (session, sdes_type_to_name (i), rtpbin->sdes[i], NULL);
496   }
497   GST_OBJECT_UNLOCK (rtpbin);
498
499   /* provide clock_rate to the session manager when needed */
500   g_signal_connect (session, "request-pt-map",
501       (GCallback) pt_map_requested, sess);
502
503   g_signal_connect (sess->session, "on-new-ssrc",
504       (GCallback) on_new_ssrc, sess);
505   g_signal_connect (sess->session, "on-ssrc-collision",
506       (GCallback) on_ssrc_collision, sess);
507   g_signal_connect (sess->session, "on-ssrc-validated",
508       (GCallback) on_ssrc_validated, sess);
509   g_signal_connect (sess->session, "on-ssrc-active",
510       (GCallback) on_ssrc_active, sess);
511   g_signal_connect (sess->session, "on-ssrc-sdes",
512       (GCallback) on_ssrc_sdes, sess);
513   g_signal_connect (sess->session, "on-bye-ssrc",
514       (GCallback) on_bye_ssrc, sess);
515   g_signal_connect (sess->session, "on-bye-timeout",
516       (GCallback) on_bye_timeout, sess);
517   g_signal_connect (sess->session, "on-timeout", (GCallback) on_timeout, sess);
518   g_signal_connect (sess->session, "on-sender-timeout",
519       (GCallback) on_sender_timeout, sess);
520
521   /* FIXME, change state only to what's needed */
522   gst_bin_add (GST_BIN_CAST (rtpbin), session);
523   gst_element_set_state (session, GST_STATE_PLAYING);
524   gst_bin_add (GST_BIN_CAST (rtpbin), demux);
525   gst_element_set_state (demux, GST_STATE_PLAYING);
526
527   return sess;
528
529   /* ERRORS */
530 no_session:
531   {
532     g_warning ("gstrtpbin: could not create gstrtpsession element");
533     return NULL;
534   }
535 no_demux:
536   {
537     gst_object_unref (session);
538     g_warning ("gstrtpbin: could not create gstrtpssrcdemux element");
539     return NULL;
540   }
541 }
542
543 static void
544 free_session (GstRtpBinSession * sess)
545 {
546   GstRtpBin *bin;
547
548   bin = sess->bin;
549
550   gst_element_set_state (sess->session, GST_STATE_NULL);
551   gst_element_set_state (sess->demux, GST_STATE_NULL);
552
553   if (sess->recv_rtp_sink != NULL)
554     gst_element_release_request_pad (sess->session, sess->recv_rtp_sink);
555   if (sess->recv_rtp_src != NULL)
556     gst_object_unref (sess->recv_rtp_src);
557   if (sess->recv_rtcp_sink != NULL)
558     gst_element_release_request_pad (sess->session, sess->recv_rtcp_sink);
559   if (sess->sync_src != NULL)
560     gst_object_unref (sess->sync_src);
561   if (sess->send_rtp_sink != NULL)
562     gst_element_release_request_pad (sess->session, sess->send_rtp_sink);
563   if (sess->send_rtp_src != NULL)
564     gst_object_unref (sess->send_rtp_src);
565   if (sess->send_rtcp_src != NULL)
566     gst_element_release_request_pad (sess->session, sess->send_rtcp_src);
567
568   gst_bin_remove (GST_BIN_CAST (bin), sess->session);
569   gst_bin_remove (GST_BIN_CAST (bin), sess->demux);
570
571   g_slist_foreach (sess->streams, (GFunc) free_stream, NULL);
572   g_slist_free (sess->streams);
573
574   g_mutex_free (sess->lock);
575   g_hash_table_destroy (sess->ptmap);
576
577   bin->sessions = g_slist_remove (bin->sessions, sess);
578
579   g_free (sess);
580 }
581
582 #if 0
583 static GstRtpBinStream *
584 find_stream_by_ssrc (GstRtpBinSession * session, guint32 ssrc)
585 {
586   GSList *walk;
587
588   for (walk = session->streams; walk; walk = g_slist_next (walk)) {
589     GstRtpBinStream *stream = (GstRtpBinStream *) walk->data;
590
591     if (stream->ssrc == ssrc)
592       return stream;
593   }
594   return NULL;
595 }
596 #endif
597
598 /* get the payload type caps for the specific payload @pt in @session */
599 static GstCaps *
600 get_pt_map (GstRtpBinSession * session, guint pt)
601 {
602   GstCaps *caps = NULL;
603   GstRtpBin *bin;
604   GValue ret = { 0 };
605   GValue args[3] = { {0}, {0}, {0} };
606
607   GST_DEBUG ("searching pt %d in cache", pt);
608
609   GST_RTP_SESSION_LOCK (session);
610
611   /* first look in the cache */
612   caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt));
613   if (caps) {
614     gst_caps_ref (caps);
615     goto done;
616   }
617
618   bin = session->bin;
619
620   GST_DEBUG ("emiting signal for pt %d in session %d", pt, session->id);
621
622   /* not in cache, send signal to request caps */
623   g_value_init (&args[0], GST_TYPE_ELEMENT);
624   g_value_set_object (&args[0], bin);
625   g_value_init (&args[1], G_TYPE_UINT);
626   g_value_set_uint (&args[1], session->id);
627   g_value_init (&args[2], G_TYPE_UINT);
628   g_value_set_uint (&args[2], pt);
629
630   g_value_init (&ret, GST_TYPE_CAPS);
631   g_value_set_boxed (&ret, NULL);
632
633   GST_RTP_SESSION_UNLOCK (session);
634
635   g_signal_emitv (args, gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP], 0, &ret);
636
637   GST_RTP_SESSION_LOCK (session);
638
639   g_value_unset (&args[0]);
640   g_value_unset (&args[1]);
641   g_value_unset (&args[2]);
642
643   /* look in the cache again because we let the lock go */
644   caps = g_hash_table_lookup (session->ptmap, GINT_TO_POINTER (pt));
645   if (caps) {
646     gst_caps_ref (caps);
647     g_value_unset (&ret);
648     goto done;
649   }
650
651   caps = (GstCaps *) g_value_dup_boxed (&ret);
652   g_value_unset (&ret);
653   if (!caps)
654     goto no_caps;
655
656   GST_DEBUG ("caching pt %d as %" GST_PTR_FORMAT, pt, caps);
657
658   /* store in cache, take additional ref */
659   g_hash_table_insert (session->ptmap, GINT_TO_POINTER (pt),
660       gst_caps_ref (caps));
661
662 done:
663   GST_RTP_SESSION_UNLOCK (session);
664
665   return caps;
666
667   /* ERRORS */
668 no_caps:
669   {
670     GST_RTP_SESSION_UNLOCK (session);
671     GST_DEBUG ("no pt map could be obtained");
672     return NULL;
673   }
674 }
675
676 static gboolean
677 return_true (gpointer key, gpointer value, gpointer user_data)
678 {
679   return TRUE;
680 }
681
682 static void
683 gst_rtp_bin_clear_pt_map (GstRtpBin * bin)
684 {
685   GSList *sessions, *streams;
686
687   GST_RTP_BIN_LOCK (bin);
688   GST_DEBUG_OBJECT (bin, "clearing pt map");
689   for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
690     GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
691
692     GST_DEBUG_OBJECT (bin, "clearing session %p", session);
693     g_signal_emit_by_name (session->session, "clear-pt-map", NULL);
694
695     GST_RTP_SESSION_LOCK (session);
696     g_hash_table_foreach_remove (session->ptmap, return_true, NULL);
697
698     for (streams = session->streams; streams; streams = g_slist_next (streams)) {
699       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
700
701       GST_DEBUG_OBJECT (bin, "clearing stream %p", stream);
702       g_signal_emit_by_name (stream->buffer, "clear-pt-map", NULL);
703       g_signal_emit_by_name (stream->demux, "clear-pt-map", NULL);
704     }
705     GST_RTP_SESSION_UNLOCK (session);
706   }
707   GST_RTP_BIN_UNLOCK (bin);
708 }
709
710 static void
711 gst_rtp_bin_propagate_property_to_jitterbuffer (GstRtpBin * bin,
712     const gchar * name, const GValue * value)
713 {
714   GSList *sessions, *streams;
715
716   GST_RTP_BIN_LOCK (bin);
717   for (sessions = bin->sessions; sessions; sessions = g_slist_next (sessions)) {
718     GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
719
720     GST_RTP_SESSION_LOCK (session);
721     for (streams = session->streams; streams; streams = g_slist_next (streams)) {
722       GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
723
724       g_object_set_property (G_OBJECT (stream->buffer), name, value);
725     }
726     GST_RTP_SESSION_UNLOCK (session);
727   }
728   GST_RTP_BIN_UNLOCK (bin);
729 }
730
731 /* get a client with the given SDES name. Must be called with RTP_BIN_LOCK */
732 static GstRtpBinClient *
733 get_client (GstRtpBin * bin, guint8 len, guint8 * data, gboolean * created)
734 {
735   GstRtpBinClient *result = NULL;
736   GSList *walk;
737
738   for (walk = bin->clients; walk; walk = g_slist_next (walk)) {
739     GstRtpBinClient *client = (GstRtpBinClient *) walk->data;
740
741     if (len != client->cname_len)
742       continue;
743
744     if (!strncmp ((gchar *) data, client->cname, client->cname_len)) {
745       GST_DEBUG_OBJECT (bin, "found existing client %p with CNAME %s", client,
746           client->cname);
747       result = client;
748       break;
749     }
750   }
751
752   /* nothing found, create one */
753   if (result == NULL) {
754     result = g_new0 (GstRtpBinClient, 1);
755     result->cname = g_strndup ((gchar *) data, len);
756     result->cname_len = len;
757     result->min_delta = G_MAXINT64;
758     bin->clients = g_slist_prepend (bin->clients, result);
759     GST_DEBUG_OBJECT (bin, "created new client %p with CNAME %s", result,
760         result->cname);
761   }
762   return result;
763 }
764
765 static void
766 free_client (GstRtpBinClient * client)
767 {
768   g_slist_free (client->streams);
769   g_free (client->cname);
770   g_free (client);
771 }
772
773 /* associate a stream to the given CNAME. This will make sure all streams for
774  * that CNAME are synchronized together. */
775 static void
776 gst_rtp_bin_associate (GstRtpBin * bin, GstRtpBinStream * stream, guint8 len,
777     guint8 * data)
778 {
779   GstRtpBinClient *client;
780   gboolean created;
781   GSList *walk;
782
783   /* first find or create the CNAME */
784   GST_RTP_BIN_LOCK (bin);
785   client = get_client (bin, len, data, &created);
786
787   /* find stream in the client */
788   for (walk = client->streams; walk; walk = g_slist_next (walk)) {
789     GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
790
791     if (ostream == stream)
792       break;
793   }
794   /* not found, add it to the list */
795   if (walk == NULL) {
796     GST_DEBUG_OBJECT (bin,
797         "new association of SSRC %08x with client %p with CNAME %s",
798         stream->ssrc, client, client->cname);
799     client->streams = g_slist_prepend (client->streams, stream);
800     client->nstreams++;
801   } else {
802     GST_DEBUG_OBJECT (bin,
803         "found association of SSRC %08x with client %p with CNAME %s",
804         stream->ssrc, client, client->cname);
805   }
806
807   /* we can only continue if we know the local clock-base and clock-rate */
808   if (stream->clock_base == -1)
809     goto no_clock_base;
810
811   if (stream->clock_rate <= 0) {
812     gint pt = -1;
813     GstCaps *caps = NULL;
814     GstStructure *s = NULL;
815
816     GST_RTP_SESSION_LOCK (stream->session);
817     pt = stream->last_pt;
818     GST_RTP_SESSION_UNLOCK (stream->session);
819
820     if (pt < 0)
821       goto no_clock_rate;
822
823     caps = get_pt_map (stream->session, pt);
824     if (!caps)
825       goto no_clock_rate;
826
827     s = gst_caps_get_structure (caps, 0);
828     gst_structure_get_int (s, "clock-rate", &stream->clock_rate);
829     gst_caps_unref (caps);
830
831     if (stream->clock_rate <= 0)
832       goto no_clock_rate;
833   }
834
835   /* map last RTP time to local timeline using our clock-base */
836   stream->local_rtp = stream->last_extrtptime - stream->clock_base;
837
838   GST_DEBUG_OBJECT (bin,
839       "base %" G_GUINT64_FORMAT ", extrtptime %" G_GUINT64_FORMAT
840       ", local RTP %" G_GUINT64_FORMAT ", clock-rate %d", stream->clock_base,
841       stream->last_extrtptime, stream->local_rtp, stream->clock_rate);
842
843   /* calculate local NTP time in gstreamer timestamp */
844   stream->local_unix =
845       gst_util_uint64_scale_int (stream->local_rtp, GST_SECOND,
846       stream->clock_rate);
847   stream->local_unix += stream->clock_base_time;
848   /* calculate delta between server and receiver */
849   stream->unix_delta = stream->last_unix - stream->local_unix;
850
851   GST_DEBUG_OBJECT (bin,
852       "local UNIX %" G_GUINT64_FORMAT ", remote UNIX %" G_GUINT64_FORMAT
853       ", delta %" G_GINT64_FORMAT, stream->local_unix, stream->last_unix,
854       stream->unix_delta);
855
856   /* recalc inter stream playout offset, but only if there are more than one
857    * stream. */
858   if (client->nstreams > 1) {
859     gint64 min;
860
861     /* calculate the min of all deltas */
862     min = G_MAXINT64;
863     for (walk = client->streams; walk; walk = g_slist_next (walk)) {
864       GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
865
866       if (ostream->unix_delta && ostream->unix_delta < min)
867         min = ostream->unix_delta;
868     }
869
870     GST_DEBUG_OBJECT (bin, "client %p min delta %" G_GINT64_FORMAT, client,
871         min);
872
873     /* calculate offsets for each stream */
874     for (walk = client->streams; walk; walk = g_slist_next (walk)) {
875       GstRtpBinStream *ostream = (GstRtpBinStream *) walk->data;
876       gint64 prev_ts_offset;
877
878       ostream->ts_offset = ostream->unix_delta - min;
879
880       g_object_get (ostream->buffer, "ts-offset", &prev_ts_offset, NULL);
881
882       /* delta changed, see how much */
883       if (prev_ts_offset != ostream->ts_offset) {
884         gint64 diff;
885
886         if (prev_ts_offset > ostream->ts_offset)
887           diff = prev_ts_offset - ostream->ts_offset;
888         else
889           diff = ostream->ts_offset - prev_ts_offset;
890
891         GST_DEBUG_OBJECT (bin,
892             "ts-offset %" G_GUINT64_FORMAT ", prev %" G_GUINT64_FORMAT
893             ", diff: %" G_GINT64_FORMAT, ostream->ts_offset, prev_ts_offset,
894             diff);
895
896         /* only change diff when it changed more than 4 milliseconds. This
897          * compensates for rounding errors in NTP to RTP timestamp
898          * conversions */
899         if (diff > 4 * GST_MSECOND && diff < (3 * GST_SECOND)) {
900           g_object_set (ostream->buffer, "ts-offset", ostream->ts_offset, NULL);
901         }
902       }
903       GST_DEBUG_OBJECT (bin, "stream SSRC %08x, delta %" G_GINT64_FORMAT,
904           ostream->ssrc, ostream->ts_offset);
905     }
906   }
907   GST_RTP_BIN_UNLOCK (bin);
908   return;
909
910 no_clock_base:
911   {
912     GST_WARNING_OBJECT (bin, "we have no clock-base");
913     GST_RTP_BIN_UNLOCK (bin);
914     return;
915   }
916 no_clock_rate:
917   {
918     GST_WARNING_OBJECT (bin, "we have no clock-rate");
919     GST_RTP_BIN_UNLOCK (bin);
920     return;
921   }
922 }
923
924 #define GST_RTCP_BUFFER_FOR_PACKETS(b,buffer,packet) \
925   for ((b) = gst_rtcp_buffer_get_first_packet ((buffer), (packet)); (b); \
926           (b) = gst_rtcp_packet_move_to_next ((packet)))
927
928 #define GST_RTCP_SDES_FOR_ITEMS(b,packet) \
929   for ((b) = gst_rtcp_packet_sdes_first_item ((packet)); (b); \
930           (b) = gst_rtcp_packet_sdes_next_item ((packet)))
931
932 #define GST_RTCP_SDES_FOR_ENTRIES(b,packet) \
933   for ((b) = gst_rtcp_packet_sdes_first_entry ((packet)); (b); \
934           (b) = gst_rtcp_packet_sdes_next_entry ((packet)))
935
936 static GstFlowReturn
937 gst_rtp_bin_sync_chain (GstPad * pad, GstBuffer * buffer)
938 {
939   GstFlowReturn ret = GST_FLOW_OK;
940   GstRtpBinStream *stream;
941   GstRtpBin *bin;
942   GstRTCPPacket packet;
943   guint32 ssrc;
944   guint64 ntptime;
945   guint32 rtptime;
946   gboolean have_sr, have_sdes;
947   gboolean more;
948   guint64 clock_base;
949   guint64 clock_base_time;
950
951   stream = gst_pad_get_element_private (pad);
952   bin = stream->bin;
953
954   GST_DEBUG_OBJECT (bin, "received sync packet");
955
956   if (!gst_rtcp_buffer_validate (buffer))
957     goto invalid_rtcp;
958
959   /* get the last relation between the rtp timestamps and the gstreamer
960    * timestamps. We get this info directly from the jitterbuffer which
961    * constructs gstreamer timestamps from rtp timestamps */
962   gst_rtp_jitter_buffer_get_sync (GST_RTP_JITTER_BUFFER (stream->buffer),
963       &clock_base, &clock_base_time);
964
965   /* clock base changes when there is a huge gap in the timestamps or seqnum.
966    * When this happens we don't want to calculate the extended timestamp based
967    * on the previous one but reset the calculation. */
968   if (stream->last_clock_base != clock_base) {
969     stream->last_extrtptime = -1;
970     stream->last_clock_base = clock_base;
971   }
972
973   have_sr = FALSE;
974   have_sdes = FALSE;
975   GST_RTCP_BUFFER_FOR_PACKETS (more, buffer, &packet) {
976     /* first packet must be SR or RR or else the validate would have failed */
977     switch (gst_rtcp_packet_get_type (&packet)) {
978       case GST_RTCP_TYPE_SR:
979         /* only parse first. There is only supposed to be one SR in the packet
980          * but we will deal with malformed packets gracefully */
981         if (have_sr)
982           break;
983         /* get NTP and RTP times */
984         gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, &ntptime, &rtptime,
985             NULL, NULL);
986
987         GST_DEBUG_OBJECT (bin, "received sync packet from SSRC %08x", ssrc);
988         /* ignore SR that is not ours */
989         if (ssrc != stream->ssrc)
990           continue;
991
992         have_sr = TRUE;
993
994         /* store values in the stream */
995         stream->have_sync = TRUE;
996         stream->last_unix = gst_rtcp_ntp_to_unix (ntptime);
997         /* use extended timestamp */
998         gst_rtp_buffer_ext_timestamp (&stream->last_extrtptime, rtptime);
999         break;
1000       case GST_RTCP_TYPE_SDES:
1001       {
1002         gboolean more_items, more_entries;
1003
1004         /* only deal with first SDES, there is only supposed to be one SDES in
1005          * the RTCP packet but we deal with bad packets gracefully. Also bail
1006          * out if we have not seen an SR item yet. */
1007         if (have_sdes || !have_sr)
1008           break;
1009
1010         GST_RTCP_SDES_FOR_ITEMS (more_items, &packet) {
1011           /* skip items that are not about the SSRC of the sender */
1012           if (gst_rtcp_packet_sdes_get_ssrc (&packet) != ssrc)
1013             continue;
1014
1015           /* find the CNAME entry */
1016           GST_RTCP_SDES_FOR_ENTRIES (more_entries, &packet) {
1017             GstRTCPSDESType type;
1018             guint8 len;
1019             guint8 *data;
1020
1021             gst_rtcp_packet_sdes_get_entry (&packet, &type, &len, &data);
1022
1023             if (type == GST_RTCP_SDES_CNAME) {
1024               stream->clock_base = clock_base;
1025               stream->clock_base_time = clock_base_time;
1026               /* associate the stream to CNAME */
1027               gst_rtp_bin_associate (bin, stream, len, data);
1028             }
1029           }
1030         }
1031         have_sdes = TRUE;
1032         break;
1033       }
1034       default:
1035         /* we can ignore these packets */
1036         break;
1037     }
1038   }
1039
1040   gst_buffer_unref (buffer);
1041
1042   return ret;
1043
1044   /* ERRORS */
1045 invalid_rtcp:
1046   {
1047     /* this is fatal and should be filtered earlier */
1048     GST_ELEMENT_ERROR (bin, STREAM, DECODE, (NULL),
1049         ("invalid RTCP packet received"));
1050     gst_buffer_unref (buffer);
1051     return GST_FLOW_ERROR;
1052   }
1053 }
1054
1055 /* create a new stream with @ssrc in @session. Must be called with
1056  * RTP_SESSION_LOCK. */
1057 static GstRtpBinStream *
1058 create_stream (GstRtpBinSession * session, guint32 ssrc)
1059 {
1060   GstElement *buffer, *demux;
1061   GstRtpBinStream *stream;
1062   GstPadTemplate *templ;
1063   gchar *padname;
1064
1065   if (!(buffer = gst_element_factory_make ("gstrtpjitterbuffer", NULL)))
1066     goto no_jitterbuffer;
1067
1068   if (!(demux = gst_element_factory_make ("gstrtpptdemux", NULL)))
1069     goto no_demux;
1070
1071   stream = g_new0 (GstRtpBinStream, 1);
1072   stream->ssrc = ssrc;
1073   stream->bin = session->bin;
1074   stream->session = session;
1075   stream->buffer = buffer;
1076   stream->demux = demux;
1077   stream->last_extrtptime = -1;
1078   stream->last_pt = -1;
1079   stream->have_sync = FALSE;
1080   session->streams = g_slist_prepend (session->streams, stream);
1081
1082   /* make an internal sinkpad for RTCP sync packets. Take ownership of the
1083    * pad. We will link this pad later. */
1084   padname = g_strdup_printf ("sync_%d", ssrc);
1085   templ = gst_static_pad_template_get (&rtpbin_sync_sink_template);
1086   stream->sync_pad = gst_pad_new_from_template (templ, padname);
1087   gst_object_unref (templ);
1088   g_free (padname);
1089   gst_object_ref (stream->sync_pad);
1090   gst_object_sink (stream->sync_pad);
1091   gst_pad_set_element_private (stream->sync_pad, stream);
1092   gst_pad_set_chain_function (stream->sync_pad, gst_rtp_bin_sync_chain);
1093   gst_pad_set_active (stream->sync_pad, TRUE);
1094
1095   /* provide clock_rate to the jitterbuffer when needed */
1096   g_signal_connect (buffer, "request-pt-map",
1097       (GCallback) pt_map_requested, session);
1098
1099   /* configure latency and packet lost */
1100   g_object_set (buffer, "latency", session->bin->latency, NULL);
1101   g_object_set (buffer, "do-lost", session->bin->do_lost, NULL);
1102
1103   gst_bin_add (GST_BIN_CAST (session->bin), buffer);
1104   gst_element_set_state (buffer, GST_STATE_PLAYING);
1105   gst_bin_add (GST_BIN_CAST (session->bin), demux);
1106   gst_element_set_state (demux, GST_STATE_PLAYING);
1107
1108   /* link stuff */
1109   gst_element_link (buffer, demux);
1110
1111   return stream;
1112
1113   /* ERRORS */
1114 no_jitterbuffer:
1115   {
1116     g_warning ("gstrtpbin: could not create gstrtpjitterbuffer element");
1117     return NULL;
1118   }
1119 no_demux:
1120   {
1121     gst_object_unref (buffer);
1122     g_warning ("gstrtpbin: could not create gstrtpptdemux element");
1123     return NULL;
1124   }
1125 }
1126
1127 static void
1128 free_stream (GstRtpBinStream * stream)
1129 {
1130   GstRtpBinSession *session;
1131
1132   session = stream->session;
1133
1134   gst_element_set_state (stream->buffer, GST_STATE_NULL);
1135   gst_element_set_state (stream->demux, GST_STATE_NULL);
1136
1137   gst_bin_remove (GST_BIN_CAST (session->bin), stream->buffer);
1138   gst_bin_remove (GST_BIN_CAST (session->bin), stream->demux);
1139
1140   gst_object_unref (stream->sync_pad);
1141
1142   session->streams = g_slist_remove (session->streams, stream);
1143
1144   g_free (stream);
1145 }
1146
1147 /* GObject vmethods */
1148 static void gst_rtp_bin_dispose (GObject * object);
1149 static void gst_rtp_bin_finalize (GObject * object);
1150 static void gst_rtp_bin_set_property (GObject * object, guint prop_id,
1151     const GValue * value, GParamSpec * pspec);
1152 static void gst_rtp_bin_get_property (GObject * object, guint prop_id,
1153     GValue * value, GParamSpec * pspec);
1154
1155 /* GstElement vmethods */
1156 static GstClock *gst_rtp_bin_provide_clock (GstElement * element);
1157 static GstStateChangeReturn gst_rtp_bin_change_state (GstElement * element,
1158     GstStateChange transition);
1159 static GstPad *gst_rtp_bin_request_new_pad (GstElement * element,
1160     GstPadTemplate * templ, const gchar * name);
1161 static void gst_rtp_bin_release_pad (GstElement * element, GstPad * pad);
1162 static void gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message);
1163 static void gst_rtp_bin_clear_pt_map (GstRtpBin * bin);
1164
1165 GST_BOILERPLATE (GstRtpBin, gst_rtp_bin, GstBin, GST_TYPE_BIN);
1166
1167 static void
1168 gst_rtp_bin_base_init (gpointer klass)
1169 {
1170   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
1171
1172   /* sink pads */
1173   gst_element_class_add_pad_template (element_class,
1174       gst_static_pad_template_get (&rtpbin_recv_rtp_sink_template));
1175   gst_element_class_add_pad_template (element_class,
1176       gst_static_pad_template_get (&rtpbin_recv_rtcp_sink_template));
1177   gst_element_class_add_pad_template (element_class,
1178       gst_static_pad_template_get (&rtpbin_send_rtp_sink_template));
1179
1180   /* src pads */
1181   gst_element_class_add_pad_template (element_class,
1182       gst_static_pad_template_get (&rtpbin_recv_rtp_src_template));
1183   gst_element_class_add_pad_template (element_class,
1184       gst_static_pad_template_get (&rtpbin_send_rtcp_src_template));
1185   gst_element_class_add_pad_template (element_class,
1186       gst_static_pad_template_get (&rtpbin_send_rtp_src_template));
1187
1188   gst_element_class_set_details (element_class, &rtpbin_details);
1189 }
1190
1191 static void
1192 gst_rtp_bin_class_init (GstRtpBinClass * klass)
1193 {
1194   GObjectClass *gobject_class;
1195   GstElementClass *gstelement_class;
1196   GstBinClass *gstbin_class;
1197
1198   gobject_class = (GObjectClass *) klass;
1199   gstelement_class = (GstElementClass *) klass;
1200   gstbin_class = (GstBinClass *) klass;
1201
1202   g_type_class_add_private (klass, sizeof (GstRtpBinPrivate));
1203
1204   gobject_class->dispose = gst_rtp_bin_dispose;
1205   gobject_class->finalize = gst_rtp_bin_finalize;
1206   gobject_class->set_property = gst_rtp_bin_set_property;
1207   gobject_class->get_property = gst_rtp_bin_get_property;
1208
1209   g_object_class_install_property (gobject_class, PROP_LATENCY,
1210       g_param_spec_uint ("latency", "Buffer latency in ms",
1211           "Default amount of ms to buffer in the jitterbuffers", 0,
1212           G_MAXUINT, DEFAULT_LATENCY_MS, G_PARAM_READWRITE));
1213
1214   /**
1215    * GstRtpBin::request-pt-map:
1216    * @rtpbin: the object which received the signal
1217    * @session: the session
1218    * @pt: the pt
1219    *
1220    * Request the payload type as #GstCaps for @pt in @session.
1221    */
1222   gst_rtp_bin_signals[SIGNAL_REQUEST_PT_MAP] =
1223       g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass),
1224       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, request_pt_map),
1225       NULL, NULL, gst_rtp_bin_marshal_BOXED__UINT_UINT, GST_TYPE_CAPS, 2,
1226       G_TYPE_UINT, G_TYPE_UINT);
1227   /**
1228    * GstRtpBin::clear-pt-map:
1229    * @rtpbin: the object which received the signal
1230    *
1231    * Clear all previously cached pt-mapping obtained with
1232    * #GstRtpBin::request-pt-map.
1233    */
1234   gst_rtp_bin_signals[SIGNAL_CLEAR_PT_MAP] =
1235       g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass),
1236       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstRtpBinClass,
1237           clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
1238       0, G_TYPE_NONE);
1239
1240   /**
1241    * GstRtpBin::on-new-ssrc:
1242    * @rtpbin: the object which received the signal
1243    * @session: the session
1244    * @ssrc: the SSRC 
1245    *
1246    * Notify of a new SSRC that entered @session.
1247    */
1248   gst_rtp_bin_signals[SIGNAL_ON_NEW_SSRC] =
1249       g_signal_new ("on-new-ssrc", G_TYPE_FROM_CLASS (klass),
1250       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_new_ssrc),
1251       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1252       G_TYPE_UINT, G_TYPE_UINT);
1253   /**
1254    * GstRtpBin::on-ssrc-collision:
1255    * @rtpbin: the object which received the signal
1256    * @session: the session
1257    * @ssrc: the SSRC 
1258    *
1259    * Notify when we have an SSRC collision
1260    */
1261   gst_rtp_bin_signals[SIGNAL_ON_SSRC_COLLISION] =
1262       g_signal_new ("on-ssrc-collision", G_TYPE_FROM_CLASS (klass),
1263       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_collision),
1264       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1265       G_TYPE_UINT, G_TYPE_UINT);
1266   /**
1267    * GstRtpBin::on-ssrc-validated:
1268    * @rtpbin: the object which received the signal
1269    * @session: the session
1270    * @ssrc: the SSRC 
1271    *
1272    * Notify of a new SSRC that became validated.
1273    */
1274   gst_rtp_bin_signals[SIGNAL_ON_SSRC_VALIDATED] =
1275       g_signal_new ("on-ssrc-validated", G_TYPE_FROM_CLASS (klass),
1276       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_validated),
1277       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1278       G_TYPE_UINT, G_TYPE_UINT);
1279   /**
1280    * GstRtpBin::on-ssrc-active:
1281    * @rtpbin: the object which received the signal
1282    * @session: the session
1283    * @ssrc: the SSRC
1284    *
1285    * Notify of a SSRC that is active, i.e., sending RTCP.
1286    */
1287   gst_rtp_bin_signals[SIGNAL_ON_SSRC_ACTIVE] =
1288       g_signal_new ("on-ssrc-active", G_TYPE_FROM_CLASS (klass),
1289       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_active),
1290       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1291       G_TYPE_UINT, G_TYPE_UINT);
1292   /**
1293    * GstRtpBin::on-ssrc-sdes:
1294    * @rtpbin: the object which received the signal
1295    * @session: the session
1296    * @ssrc: the SSRC
1297    *
1298    * Notify of a SSRC that is active, i.e., sending RTCP.
1299    */
1300   gst_rtp_bin_signals[SIGNAL_ON_SSRC_SDES] =
1301       g_signal_new ("on-ssrc-sdes", G_TYPE_FROM_CLASS (klass),
1302       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_ssrc_sdes),
1303       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1304       G_TYPE_UINT, G_TYPE_UINT);
1305
1306   /**
1307    * GstRtpBin::on-bye-ssrc:
1308    * @rtpbin: the object which received the signal
1309    * @session: the session
1310    * @ssrc: the SSRC 
1311    *
1312    * Notify of an SSRC that became inactive because of a BYE packet.
1313    */
1314   gst_rtp_bin_signals[SIGNAL_ON_BYE_SSRC] =
1315       g_signal_new ("on-bye-ssrc", G_TYPE_FROM_CLASS (klass),
1316       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_ssrc),
1317       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1318       G_TYPE_UINT, G_TYPE_UINT);
1319   /**
1320    * GstRtpBin::on-bye-timeout:
1321    * @rtpbin: the object which received the signal
1322    * @session: the session
1323    * @ssrc: the SSRC 
1324    *
1325    * Notify of an SSRC that has timed out because of BYE
1326    */
1327   gst_rtp_bin_signals[SIGNAL_ON_BYE_TIMEOUT] =
1328       g_signal_new ("on-bye-timeout", G_TYPE_FROM_CLASS (klass),
1329       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_bye_timeout),
1330       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1331       G_TYPE_UINT, G_TYPE_UINT);
1332   /**
1333    * GstRtpBin::on-timeout:
1334    * @rtpbin: the object which received the signal
1335    * @session: the session
1336    * @ssrc: the SSRC 
1337    *
1338    * Notify of an SSRC that has timed out
1339    */
1340   gst_rtp_bin_signals[SIGNAL_ON_TIMEOUT] =
1341       g_signal_new ("on-timeout", G_TYPE_FROM_CLASS (klass),
1342       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_timeout),
1343       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1344       G_TYPE_UINT, G_TYPE_UINT);
1345   /**
1346    * GstRtpBin::on-sender-timeout:
1347    * @rtpbin: the object which received the signal
1348    * @session: the session
1349    * @ssrc: the SSRC 
1350    *
1351    * Notify of a sender SSRC that has timed out and became a receiver
1352    */
1353   gst_rtp_bin_signals[SIGNAL_ON_SENDER_TIMEOUT] =
1354       g_signal_new ("on-sender-timeout", G_TYPE_FROM_CLASS (klass),
1355       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, on_sender_timeout),
1356       NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2,
1357       G_TYPE_UINT, G_TYPE_UINT);
1358
1359   g_object_class_install_property (gobject_class, PROP_SDES_CNAME,
1360       g_param_spec_string ("sdes-cname", "SDES CNAME",
1361           "The CNAME to put in SDES messages of this session",
1362           DEFAULT_SDES_CNAME, G_PARAM_READWRITE));
1363
1364   g_object_class_install_property (gobject_class, PROP_SDES_NAME,
1365       g_param_spec_string ("sdes-name", "SDES NAME",
1366           "The NAME to put in SDES messages of this session",
1367           DEFAULT_SDES_NAME, G_PARAM_READWRITE));
1368
1369   g_object_class_install_property (gobject_class, PROP_SDES_EMAIL,
1370       g_param_spec_string ("sdes-email", "SDES EMAIL",
1371           "The EMAIL to put in SDES messages of this session",
1372           DEFAULT_SDES_EMAIL, G_PARAM_READWRITE));
1373
1374   g_object_class_install_property (gobject_class, PROP_SDES_PHONE,
1375       g_param_spec_string ("sdes-phone", "SDES PHONE",
1376           "The PHONE to put in SDES messages of this session",
1377           DEFAULT_SDES_PHONE, G_PARAM_READWRITE));
1378
1379   g_object_class_install_property (gobject_class, PROP_SDES_LOCATION,
1380       g_param_spec_string ("sdes-location", "SDES LOCATION",
1381           "The LOCATION to put in SDES messages of this session",
1382           DEFAULT_SDES_LOCATION, G_PARAM_READWRITE));
1383
1384   g_object_class_install_property (gobject_class, PROP_SDES_TOOL,
1385       g_param_spec_string ("sdes-tool", "SDES TOOL",
1386           "The TOOL to put in SDES messages of this session",
1387           DEFAULT_SDES_TOOL, G_PARAM_READWRITE));
1388
1389   g_object_class_install_property (gobject_class, PROP_SDES_NOTE,
1390       g_param_spec_string ("sdes-note", "SDES NOTE",
1391           "The NOTE to put in SDES messages of this session",
1392           DEFAULT_SDES_NOTE, G_PARAM_READWRITE));
1393
1394   g_object_class_install_property (gobject_class, PROP_DO_LOST,
1395       g_param_spec_boolean ("do-lost", "Do Lost",
1396           "Send an event downstream when a packet is lost", DEFAULT_DO_LOST,
1397           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1398
1399   gstelement_class->provide_clock =
1400       GST_DEBUG_FUNCPTR (gst_rtp_bin_provide_clock);
1401   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_rtp_bin_change_state);
1402   gstelement_class->request_new_pad =
1403       GST_DEBUG_FUNCPTR (gst_rtp_bin_request_new_pad);
1404   gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_rtp_bin_release_pad);
1405
1406   gstbin_class->handle_message = GST_DEBUG_FUNCPTR (gst_rtp_bin_handle_message);
1407
1408   klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_bin_clear_pt_map);
1409
1410   GST_DEBUG_CATEGORY_INIT (gst_rtp_bin_debug, "rtpbin", 0, "RTP bin");
1411 }
1412
1413 static void
1414 gst_rtp_bin_init (GstRtpBin * rtpbin, GstRtpBinClass * klass)
1415 {
1416   gchar *str;
1417
1418   rtpbin->priv = GST_RTP_BIN_GET_PRIVATE (rtpbin);
1419   rtpbin->priv->bin_lock = g_mutex_new ();
1420   rtpbin->priv->dyn_lock = g_mutex_new ();
1421   rtpbin->provided_clock = gst_system_clock_obtain ();
1422
1423   rtpbin->latency = DEFAULT_LATENCY_MS;
1424   rtpbin->do_lost = DEFAULT_DO_LOST;
1425
1426   /* some default SDES entries */
1427   str = g_strdup_printf ("%s@%s", g_get_user_name (), g_get_host_name ());
1428   gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_CNAME, str);
1429   g_free (str);
1430
1431   gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_NAME, g_get_real_name ());
1432   gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_TOOL, "GStreamer");
1433 }
1434
1435 static void
1436 gst_rtp_bin_dispose (GObject * object)
1437 {
1438   GstRtpBin *rtpbin;
1439
1440   rtpbin = GST_RTP_BIN (object);
1441
1442   g_slist_foreach (rtpbin->sessions, (GFunc) free_session, NULL);
1443   g_slist_free (rtpbin->sessions);
1444   rtpbin->sessions = NULL;
1445   g_slist_foreach (rtpbin->clients, (GFunc) free_client, NULL);
1446   g_slist_free (rtpbin->clients);
1447   rtpbin->clients = NULL;
1448
1449   G_OBJECT_CLASS (parent_class)->dispose (object);
1450 }
1451
1452 static void
1453 gst_rtp_bin_finalize (GObject * object)
1454 {
1455   GstRtpBin *rtpbin;
1456   gint i;
1457
1458   rtpbin = GST_RTP_BIN (object);
1459
1460   for (i = 0; i < 9; i++)
1461     g_free (rtpbin->sdes[i]);
1462
1463   g_mutex_free (rtpbin->priv->bin_lock);
1464   g_mutex_free (rtpbin->priv->dyn_lock);
1465   gst_object_unref (rtpbin->provided_clock);
1466
1467   G_OBJECT_CLASS (parent_class)->finalize (object);
1468 }
1469
1470 static const gchar *
1471 sdes_type_to_name (GstRTCPSDESType type)
1472 {
1473   const gchar *result;
1474
1475   switch (type) {
1476     case GST_RTCP_SDES_CNAME:
1477       result = "sdes-cname";
1478       break;
1479     case GST_RTCP_SDES_NAME:
1480       result = "sdes-name";
1481       break;
1482     case GST_RTCP_SDES_EMAIL:
1483       result = "sdes-email";
1484       break;
1485     case GST_RTCP_SDES_PHONE:
1486       result = "sdes-phone";
1487       break;
1488     case GST_RTCP_SDES_LOC:
1489       result = "sdes-location";
1490       break;
1491     case GST_RTCP_SDES_TOOL:
1492       result = "sdes-tool";
1493       break;
1494     case GST_RTCP_SDES_NOTE:
1495       result = "sdes-note";
1496       break;
1497     case GST_RTCP_SDES_PRIV:
1498       result = "sdes-priv";
1499       break;
1500     default:
1501       result = NULL;
1502       break;
1503   }
1504   return result;
1505 }
1506
1507 static void
1508 gst_rtp_bin_set_sdes_string (GstRtpBin * bin, GstRTCPSDESType type,
1509     const gchar * data)
1510 {
1511   GSList *item;
1512   const gchar *name;
1513
1514   if (type < 0 || type > 8)
1515     return;
1516
1517   GST_OBJECT_LOCK (bin);
1518   g_free (bin->sdes[type]);
1519   bin->sdes[type] = g_strdup (data);
1520   name = sdes_type_to_name (type);
1521   /* store in all sessions */
1522   for (item = bin->sessions; item; item = g_slist_next (item))
1523     g_object_set (item->data, name, bin->sdes[type], NULL);
1524   GST_OBJECT_UNLOCK (bin);
1525 }
1526
1527 static gchar *
1528 gst_rtp_bin_get_sdes_string (GstRtpBin * bin, GstRTCPSDESType type)
1529 {
1530   gchar *result;
1531
1532   if (type < 0 || type > 8)
1533     return NULL;
1534
1535   GST_OBJECT_LOCK (bin);
1536   result = g_strdup (bin->sdes[type]);
1537   GST_OBJECT_UNLOCK (bin);
1538
1539   return result;
1540 }
1541
1542 static void
1543 gst_rtp_bin_set_property (GObject * object, guint prop_id,
1544     const GValue * value, GParamSpec * pspec)
1545 {
1546   GstRtpBin *rtpbin;
1547
1548   rtpbin = GST_RTP_BIN (object);
1549
1550   switch (prop_id) {
1551     case PROP_LATENCY:
1552       GST_RTP_BIN_LOCK (rtpbin);
1553       rtpbin->latency = g_value_get_uint (value);
1554       GST_RTP_BIN_UNLOCK (rtpbin);
1555       /* propegate the property down to the jitterbuffer */
1556       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "latency", value);
1557       break;
1558     case PROP_SDES_CNAME:
1559       gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_CNAME,
1560           g_value_get_string (value));
1561       break;
1562     case PROP_SDES_NAME:
1563       gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_NAME,
1564           g_value_get_string (value));
1565       break;
1566     case PROP_SDES_EMAIL:
1567       gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_EMAIL,
1568           g_value_get_string (value));
1569       break;
1570     case PROP_SDES_PHONE:
1571       gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_PHONE,
1572           g_value_get_string (value));
1573       break;
1574     case PROP_SDES_LOCATION:
1575       gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_LOC,
1576           g_value_get_string (value));
1577       break;
1578     case PROP_SDES_TOOL:
1579       gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_TOOL,
1580           g_value_get_string (value));
1581       break;
1582     case PROP_SDES_NOTE:
1583       gst_rtp_bin_set_sdes_string (rtpbin, GST_RTCP_SDES_NOTE,
1584           g_value_get_string (value));
1585       break;
1586     case PROP_DO_LOST:
1587       GST_RTP_BIN_LOCK (rtpbin);
1588       rtpbin->do_lost = g_value_get_boolean (value);
1589       GST_RTP_BIN_UNLOCK (rtpbin);
1590       gst_rtp_bin_propagate_property_to_jitterbuffer (rtpbin, "do-lost", value);
1591       break;
1592     default:
1593       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1594       break;
1595   }
1596 }
1597
1598 static void
1599 gst_rtp_bin_get_property (GObject * object, guint prop_id,
1600     GValue * value, GParamSpec * pspec)
1601 {
1602   GstRtpBin *rtpbin;
1603
1604   rtpbin = GST_RTP_BIN (object);
1605
1606   switch (prop_id) {
1607     case PROP_LATENCY:
1608       GST_RTP_BIN_LOCK (rtpbin);
1609       g_value_set_uint (value, rtpbin->latency);
1610       GST_RTP_BIN_UNLOCK (rtpbin);
1611       break;
1612     case PROP_SDES_CNAME:
1613       g_value_take_string (value, gst_rtp_bin_get_sdes_string (rtpbin,
1614               GST_RTCP_SDES_CNAME));
1615       break;
1616     case PROP_SDES_NAME:
1617       g_value_take_string (value, gst_rtp_bin_get_sdes_string (rtpbin,
1618               GST_RTCP_SDES_NAME));
1619       break;
1620     case PROP_SDES_EMAIL:
1621       g_value_take_string (value, gst_rtp_bin_get_sdes_string (rtpbin,
1622               GST_RTCP_SDES_EMAIL));
1623       break;
1624     case PROP_SDES_PHONE:
1625       g_value_take_string (value, gst_rtp_bin_get_sdes_string (rtpbin,
1626               GST_RTCP_SDES_PHONE));
1627       break;
1628     case PROP_SDES_LOCATION:
1629       g_value_take_string (value, gst_rtp_bin_get_sdes_string (rtpbin,
1630               GST_RTCP_SDES_LOC));
1631       break;
1632     case PROP_SDES_TOOL:
1633       g_value_take_string (value, gst_rtp_bin_get_sdes_string (rtpbin,
1634               GST_RTCP_SDES_TOOL));
1635       break;
1636     case PROP_SDES_NOTE:
1637       g_value_take_string (value, gst_rtp_bin_get_sdes_string (rtpbin,
1638               GST_RTCP_SDES_NOTE));
1639       break;
1640     case PROP_DO_LOST:
1641       GST_RTP_BIN_LOCK (rtpbin);
1642       g_value_set_boolean (value, rtpbin->do_lost);
1643       GST_RTP_BIN_UNLOCK (rtpbin);
1644       break;
1645     default:
1646       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1647       break;
1648   }
1649 }
1650
1651 static GstClock *
1652 gst_rtp_bin_provide_clock (GstElement * element)
1653 {
1654   GstRtpBin *rtpbin;
1655
1656   rtpbin = GST_RTP_BIN (element);
1657
1658   return GST_CLOCK_CAST (gst_object_ref (rtpbin->provided_clock));
1659 }
1660
1661 static void
1662 gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message)
1663 {
1664   GstRtpBin *rtpbin;
1665
1666   rtpbin = GST_RTP_BIN (bin);
1667
1668   switch (GST_MESSAGE_TYPE (message)) {
1669     case GST_MESSAGE_ELEMENT:
1670     {
1671       const GstStructure *s = gst_message_get_structure (message);
1672
1673       /* we change the structure name and add the session ID to it */
1674       if (gst_structure_has_name (s, "GstRTPSessionSDES")) {
1675         GSList *walk;
1676
1677         /* find the session, the message source has it */
1678         for (walk = rtpbin->sessions; walk; walk = g_slist_next (walk)) {
1679           GstRtpBinSession *sess = (GstRtpBinSession *) walk->data;
1680
1681           /* if we found the session, change message. else we exit the loop and
1682            * leave the message unchanged */
1683           if (GST_OBJECT_CAST (sess->session) == GST_MESSAGE_SRC (message)) {
1684             message = gst_message_make_writable (message);
1685             s = gst_message_get_structure (message);
1686
1687             gst_structure_set_name ((GstStructure *) s, "GstRTPBinSDES");
1688
1689             gst_structure_set ((GstStructure *) s, "session", G_TYPE_UINT,
1690                 sess->id, NULL);
1691             break;
1692           }
1693         }
1694       }
1695       /* fallthrough to forward the modified message to the parent */
1696     }
1697     default:
1698     {
1699       GST_BIN_CLASS (parent_class)->handle_message (bin, message);
1700       break;
1701     }
1702   }
1703 }
1704
1705 static void
1706 calc_ntp_ns_base (GstRtpBin * bin)
1707 {
1708   GstClockTime now;
1709   GTimeVal current;
1710   GSList *walk;
1711
1712   /* get the current time and convert it to NTP time in nanoseconds */
1713   g_get_current_time (&current);
1714   now = GST_TIMEVAL_TO_TIME (current);
1715   now += (2208988800LL * GST_SECOND);
1716
1717   GST_RTP_BIN_LOCK (bin);
1718   bin->priv->ntp_ns_base = now;
1719   for (walk = bin->sessions; walk; walk = g_slist_next (walk)) {
1720     GstRtpBinSession *session = (GstRtpBinSession *) walk->data;
1721
1722     g_object_set (session->session, "ntp-ns-base", now, NULL);
1723   }
1724   GST_RTP_BIN_UNLOCK (bin);
1725
1726   return;
1727 }
1728
1729 static GstStateChangeReturn
1730 gst_rtp_bin_change_state (GstElement * element, GstStateChange transition)
1731 {
1732   GstStateChangeReturn res;
1733   GstRtpBin *rtpbin;
1734   GstRtpBinPrivate *priv;
1735
1736   rtpbin = GST_RTP_BIN (element);
1737   priv = rtpbin->priv;
1738
1739   switch (transition) {
1740     case GST_STATE_CHANGE_NULL_TO_READY:
1741       break;
1742     case GST_STATE_CHANGE_READY_TO_PAUSED:
1743       GST_LOG_OBJECT (rtpbin, "clearing shutdown flag");
1744       g_atomic_int_set (&priv->shutdown, 0);
1745       break;
1746     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1747       calc_ntp_ns_base (rtpbin);
1748       break;
1749     case GST_STATE_CHANGE_PAUSED_TO_READY:
1750       GST_LOG_OBJECT (rtpbin, "setting shutdown flag");
1751       g_atomic_int_set (&priv->shutdown, 1);
1752       /* wait for all callbacks to end by taking the lock. No new callbacks will
1753        * be able to happen as we set the shutdown flag. */
1754       GST_RTP_BIN_DYN_LOCK (rtpbin);
1755       GST_LOG_OBJECT (rtpbin, "dynamic lock taken, we can continue shutdown");
1756       GST_RTP_BIN_DYN_UNLOCK (rtpbin);
1757       break;
1758     default:
1759       break;
1760   }
1761
1762   res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1763
1764   switch (transition) {
1765     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1766       break;
1767     case GST_STATE_CHANGE_PAUSED_TO_READY:
1768       break;
1769     case GST_STATE_CHANGE_READY_TO_NULL:
1770       break;
1771     default:
1772       break;
1773   }
1774   return res;
1775 }
1776
1777 /* a new pad (SSRC) was created in @session. This signal is emited from the
1778  * payload demuxer. */
1779 static void
1780 new_payload_found (GstElement * element, guint pt, GstPad * pad,
1781     GstRtpBinStream * stream)
1782 {
1783   GstRtpBin *rtpbin;
1784   GstElementClass *klass;
1785   GstPadTemplate *templ;
1786   gchar *padname;
1787   GstPad *gpad;
1788
1789   rtpbin = stream->bin;
1790
1791   GST_DEBUG ("new payload pad %d", pt);
1792
1793   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
1794
1795   /* ghost the pad to the parent */
1796   klass = GST_ELEMENT_GET_CLASS (rtpbin);
1797   templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%d_%d_%d");
1798   padname = g_strdup_printf ("recv_rtp_src_%d_%u_%d",
1799       stream->session->id, stream->ssrc, pt);
1800   gpad = gst_ghost_pad_new_from_template (padname, pad, templ);
1801   g_free (padname);
1802
1803   gst_pad_set_caps (gpad, GST_PAD_CAPS (pad));
1804   gst_pad_set_active (gpad, TRUE);
1805   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad);
1806
1807   GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
1808
1809   return;
1810
1811 shutdown:
1812   {
1813     GST_DEBUG ("ignoring, we are shutting down");
1814     return;
1815   }
1816 }
1817
1818 static GstCaps *
1819 pt_map_requested (GstElement * element, guint pt, GstRtpBinSession * session)
1820 {
1821   GstRtpBin *rtpbin;
1822   GstCaps *caps;
1823
1824   rtpbin = session->bin;
1825
1826   GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %d in session %d", pt,
1827       session->id);
1828
1829   caps = get_pt_map (session, pt);
1830   if (!caps)
1831     goto no_caps;
1832
1833   return caps;
1834
1835   /* ERRORS */
1836 no_caps:
1837   {
1838     GST_DEBUG_OBJECT (rtpbin, "could not get caps");
1839     return NULL;
1840   }
1841 }
1842
1843 /* emited when caps changed for the session */
1844 static void
1845 caps_changed (GstPad * pad, GParamSpec * pspec, GstRtpBinSession * session)
1846 {
1847   GstRtpBin *bin;
1848   GstCaps *caps;
1849   gint payload;
1850   const GstStructure *s;
1851
1852   bin = session->bin;
1853
1854   g_object_get (pad, "caps", &caps, NULL);
1855
1856   if (caps == NULL)
1857     return;
1858
1859   GST_DEBUG_OBJECT (bin, "got caps %" GST_PTR_FORMAT, caps);
1860
1861   s = gst_caps_get_structure (caps, 0);
1862
1863   /* get payload, finish when it's not there */
1864   if (!gst_structure_get_int (s, "payload", &payload))
1865     return;
1866
1867   GST_RTP_SESSION_LOCK (session);
1868   GST_DEBUG_OBJECT (bin, "insert caps for payload %d", payload);
1869   g_hash_table_insert (session->ptmap, GINT_TO_POINTER (payload), caps);
1870   GST_RTP_SESSION_UNLOCK (session);
1871 }
1872
1873 /* Stores the last payload type received on a particular stream */
1874 static void
1875 payload_type_change (GstElement * element, guint pt, GstRtpBinStream * stream)
1876 {
1877   GST_RTP_SESSION_LOCK (stream->session);
1878   stream->last_pt = pt;
1879   GST_RTP_SESSION_UNLOCK (stream->session);
1880 }
1881
1882 /* a new pad (SSRC) was created in @session */
1883 static void
1884 new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
1885     GstRtpBinSession * session)
1886 {
1887   GstRtpBin *rtpbin;
1888   GstRtpBinStream *stream;
1889   GstPad *sinkpad, *srcpad;
1890   gchar *padname;
1891   GstCaps *caps;
1892
1893   rtpbin = session->bin;
1894
1895   GST_DEBUG_OBJECT (rtpbin, "new SSRC pad %08x, %s:%s", ssrc,
1896       GST_DEBUG_PAD_NAME (pad));
1897
1898   GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
1899
1900   GST_RTP_SESSION_LOCK (session);
1901
1902   /* create new stream */
1903   stream = create_stream (session, ssrc);
1904   if (!stream)
1905     goto no_stream;
1906
1907   /* get the caps of the pad, we need the clock-rate and base_time if any. */
1908   if ((caps = gst_pad_get_caps (pad))) {
1909     const GstStructure *s;
1910     guint val;
1911
1912     GST_DEBUG_OBJECT (rtpbin, "pad has caps %" GST_PTR_FORMAT, caps);
1913
1914     s = gst_caps_get_structure (caps, 0);
1915
1916     if (!gst_structure_get_int (s, "clock-rate", &stream->clock_rate)) {
1917       stream->clock_rate = -1;
1918
1919       GST_WARNING_OBJECT (rtpbin,
1920           "Caps have no clock rate %s from pad %s:%s",
1921           gst_caps_to_string (caps), GST_DEBUG_PAD_NAME (pad));
1922     }
1923
1924     stream->last_clock_base = -1;
1925     if (gst_structure_get_uint (s, "clock-base", &val))
1926       stream->clock_base = val;
1927     else
1928       stream->clock_base = -1;
1929
1930     gst_caps_unref (caps);
1931   }
1932
1933   /* get pad and link */
1934   GST_DEBUG_OBJECT (rtpbin, "linking jitterbuffer");
1935   padname = g_strdup_printf ("src_%d", ssrc);
1936   srcpad = gst_element_get_static_pad (element, padname);
1937   g_free (padname);
1938   sinkpad = gst_element_get_static_pad (stream->buffer, "sink");
1939   gst_pad_link (srcpad, sinkpad);
1940   gst_object_unref (sinkpad);
1941   gst_object_unref (srcpad);
1942
1943   /* get the RTCP sync pad */
1944   GST_DEBUG_OBJECT (rtpbin, "linking sync pad");
1945   padname = g_strdup_printf ("rtcp_src_%d", ssrc);
1946   srcpad = gst_element_get_static_pad (element, padname);
1947   g_free (padname);
1948   gst_pad_link (srcpad, stream->sync_pad);
1949   gst_object_unref (srcpad);
1950
1951   /* connect to the new-pad signal of the payload demuxer, this will expose the
1952    * new pad by ghosting it. */
1953   stream->demux_newpad_sig = g_signal_connect (stream->demux,
1954       "new-payload-type", (GCallback) new_payload_found, stream);
1955   /* connect to the request-pt-map signal. This signal will be emited by the
1956    * demuxer so that it can apply a proper caps on the buffers for the
1957    * depayloaders. */
1958   stream->demux_ptreq_sig = g_signal_connect (stream->demux,
1959       "request-pt-map", (GCallback) pt_map_requested, session);
1960   /* connect to the payload-type-change signal so that we can know which
1961    * PT is the current PT so that the jitterbuffer can be matched to the right
1962    * offset. */
1963   stream->demux_pt_change_sig = g_signal_connect (stream->demux,
1964       "payload-type-change", (GCallback) payload_type_change, stream);
1965
1966   GST_RTP_SESSION_UNLOCK (session);
1967   GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
1968
1969   return;
1970
1971   /* ERRORS */
1972 shutdown:
1973   {
1974     GST_DEBUG_OBJECT (rtpbin, "we are shutting down");
1975     return;
1976   }
1977 no_stream:
1978   {
1979     GST_RTP_SESSION_UNLOCK (session);
1980     GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin);
1981     GST_DEBUG_OBJECT (rtpbin, "could not create stream");
1982     return;
1983   }
1984 }
1985
1986 /* Create a pad for receiving RTP for the session in @name. Must be called with
1987  * RTP_BIN_LOCK.
1988  */
1989 static GstPad *
1990 create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
1991 {
1992   GstPad *result, *sinkdpad;
1993   guint sessid;
1994   GstRtpBinSession *session;
1995   GstPadLinkReturn lres;
1996
1997   /* first get the session number */
1998   if (name == NULL || sscanf (name, "recv_rtp_sink_%d", &sessid) != 1)
1999     goto no_name;
2000
2001   GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
2002
2003   /* get or create session */
2004   session = find_session_by_id (rtpbin, sessid);
2005   if (!session) {
2006     GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
2007     /* create session now */
2008     session = create_session (rtpbin, sessid);
2009     if (session == NULL)
2010       goto create_error;
2011   }
2012
2013   /* check if pad was requested */
2014   if (session->recv_rtp_sink != NULL)
2015     goto existed;
2016
2017   GST_DEBUG_OBJECT (rtpbin, "getting RTP sink pad");
2018   /* get recv_rtp pad and store */
2019   session->recv_rtp_sink =
2020       gst_element_get_request_pad (session->session, "recv_rtp_sink");
2021   if (session->recv_rtp_sink == NULL)
2022     goto pad_failed;
2023
2024   g_signal_connect (session->recv_rtp_sink, "notify::caps",
2025       (GCallback) caps_changed, session);
2026
2027   GST_DEBUG_OBJECT (rtpbin, "getting RTP src pad");
2028   /* get srcpad, link to SSRCDemux */
2029   session->recv_rtp_src =
2030       gst_element_get_static_pad (session->session, "recv_rtp_src");
2031   if (session->recv_rtp_src == NULL)
2032     goto pad_failed;
2033
2034   GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTP sink pad");
2035   sinkdpad = gst_element_get_static_pad (session->demux, "sink");
2036   GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
2037   lres = gst_pad_link (session->recv_rtp_src, sinkdpad);
2038   gst_object_unref (sinkdpad);
2039   if (lres != GST_PAD_LINK_OK)
2040     goto link_failed;
2041
2042   /* connect to the new-ssrc-pad signal of the SSRC demuxer */
2043   session->demux_newpad_sig = g_signal_connect (session->demux,
2044       "new-ssrc-pad", (GCallback) new_ssrc_pad_found, session);
2045
2046   GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
2047   result =
2048       gst_ghost_pad_new_from_template (name, session->recv_rtp_sink, templ);
2049   gst_pad_set_active (result, TRUE);
2050   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
2051
2052   return result;
2053
2054   /* ERRORS */
2055 no_name:
2056   {
2057     g_warning ("gstrtpbin: invalid name given");
2058     return NULL;
2059   }
2060 create_error:
2061   {
2062     /* create_session already warned */
2063     return NULL;
2064   }
2065 existed:
2066   {
2067     g_warning ("gstrtpbin: recv_rtp pad already requested for session %d",
2068         sessid);
2069     return NULL;
2070   }
2071 pad_failed:
2072   {
2073     g_warning ("gstrtpbin: failed to get session pad");
2074     return NULL;
2075   }
2076 link_failed:
2077   {
2078     g_warning ("gstrtpbin: failed to link pads");
2079     return NULL;
2080   }
2081 }
2082
2083 /* Create a pad for receiving RTCP for the session in @name. Must be called with
2084  * RTP_BIN_LOCK.
2085  */
2086 static GstPad *
2087 create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
2088     const gchar * name)
2089 {
2090   GstPad *result;
2091   guint sessid;
2092   GstRtpBinSession *session;
2093   GstPad *sinkdpad;
2094   GstPadLinkReturn lres;
2095
2096   /* first get the session number */
2097   if (name == NULL || sscanf (name, "recv_rtcp_sink_%d", &sessid) != 1)
2098     goto no_name;
2099
2100   GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
2101
2102   /* get or create the session */
2103   session = find_session_by_id (rtpbin, sessid);
2104   if (!session) {
2105     GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
2106     /* create session now */
2107     session = create_session (rtpbin, sessid);
2108     if (session == NULL)
2109       goto create_error;
2110   }
2111
2112   /* check if pad was requested */
2113   if (session->recv_rtcp_sink != NULL)
2114     goto existed;
2115
2116   /* get recv_rtp pad and store */
2117   GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad");
2118   session->recv_rtcp_sink =
2119       gst_element_get_request_pad (session->session, "recv_rtcp_sink");
2120   if (session->recv_rtcp_sink == NULL)
2121     goto pad_failed;
2122
2123   /* get srcpad, link to SSRCDemux */
2124   GST_DEBUG_OBJECT (rtpbin, "getting sync src pad");
2125   session->sync_src = gst_element_get_static_pad (session->session, "sync_src");
2126   if (session->sync_src == NULL)
2127     goto pad_failed;
2128
2129   GST_DEBUG_OBJECT (rtpbin, "getting demuxer RTCP sink pad");
2130   sinkdpad = gst_element_get_static_pad (session->demux, "rtcp_sink");
2131   lres = gst_pad_link (session->sync_src, sinkdpad);
2132   gst_object_unref (sinkdpad);
2133   if (lres != GST_PAD_LINK_OK)
2134     goto link_failed;
2135
2136   result =
2137       gst_ghost_pad_new_from_template (name, session->recv_rtcp_sink, templ);
2138   gst_pad_set_active (result, TRUE);
2139   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
2140
2141   return result;
2142
2143   /* ERRORS */
2144 no_name:
2145   {
2146     g_warning ("gstrtpbin: invalid name given");
2147     return NULL;
2148   }
2149 create_error:
2150   {
2151     /* create_session already warned */
2152     return NULL;
2153   }
2154 existed:
2155   {
2156     g_warning ("gstrtpbin: recv_rtcp pad already requested for session %d",
2157         sessid);
2158     return NULL;
2159   }
2160 pad_failed:
2161   {
2162     g_warning ("gstrtpbin: failed to get session pad");
2163     return NULL;
2164   }
2165 link_failed:
2166   {
2167     g_warning ("gstrtpbin: failed to link pads");
2168     return NULL;
2169   }
2170 }
2171
2172 /* Create a pad for sending RTP for the session in @name. Must be called with
2173  * RTP_BIN_LOCK.
2174  */
2175 static GstPad *
2176 create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
2177 {
2178   GstPad *result, *srcghost;
2179   gchar *gname;
2180   guint sessid;
2181   GstRtpBinSession *session;
2182   GstElementClass *klass;
2183
2184   /* first get the session number */
2185   if (name == NULL || sscanf (name, "send_rtp_sink_%d", &sessid) != 1)
2186     goto no_name;
2187
2188   /* get or create session */
2189   session = find_session_by_id (rtpbin, sessid);
2190   if (!session) {
2191     /* create session now */
2192     session = create_session (rtpbin, sessid);
2193     if (session == NULL)
2194       goto create_error;
2195   }
2196
2197   /* check if pad was requested */
2198   if (session->send_rtp_sink != NULL)
2199     goto existed;
2200
2201   /* get send_rtp pad and store */
2202   session->send_rtp_sink =
2203       gst_element_get_request_pad (session->session, "send_rtp_sink");
2204   if (session->send_rtp_sink == NULL)
2205     goto pad_failed;
2206
2207   result =
2208       gst_ghost_pad_new_from_template (name, session->send_rtp_sink, templ);
2209   gst_pad_set_active (result, TRUE);
2210   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
2211
2212   /* get srcpad */
2213   session->send_rtp_src =
2214       gst_element_get_static_pad (session->session, "send_rtp_src");
2215   if (session->send_rtp_src == NULL)
2216     goto no_srcpad;
2217
2218   /* ghost the new source pad */
2219   klass = GST_ELEMENT_GET_CLASS (rtpbin);
2220   gname = g_strdup_printf ("send_rtp_src_%d", sessid);
2221   templ = gst_element_class_get_pad_template (klass, "send_rtp_src_%d");
2222   srcghost =
2223       gst_ghost_pad_new_from_template (gname, session->send_rtp_src, templ);
2224   gst_pad_set_active (srcghost, TRUE);
2225   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), srcghost);
2226   g_free (gname);
2227
2228   return result;
2229
2230   /* ERRORS */
2231 no_name:
2232   {
2233     g_warning ("gstrtpbin: invalid name given");
2234     return NULL;
2235   }
2236 create_error:
2237   {
2238     /* create_session already warned */
2239     return NULL;
2240   }
2241 existed:
2242   {
2243     g_warning ("gstrtpbin: send_rtp pad already requested for session %d",
2244         sessid);
2245     return NULL;
2246   }
2247 pad_failed:
2248   {
2249     g_warning ("gstrtpbin: failed to get session pad for session %d", sessid);
2250     return NULL;
2251   }
2252 no_srcpad:
2253   {
2254     g_warning ("gstrtpbin: failed to get rtp source pad for session %d",
2255         sessid);
2256     return NULL;
2257   }
2258 }
2259
2260 /* Create a pad for sending RTCP for the session in @name. Must be called with
2261  * RTP_BIN_LOCK.
2262  */
2263 static GstPad *
2264 create_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
2265 {
2266   GstPad *result;
2267   guint sessid;
2268   GstRtpBinSession *session;
2269
2270   /* first get the session number */
2271   if (name == NULL || sscanf (name, "send_rtcp_src_%d", &sessid) != 1)
2272     goto no_name;
2273
2274   /* get or create session */
2275   session = find_session_by_id (rtpbin, sessid);
2276   if (!session)
2277     goto no_session;
2278
2279   /* check if pad was requested */
2280   if (session->send_rtcp_src != NULL)
2281     goto existed;
2282
2283   /* get rtcp_src pad and store */
2284   session->send_rtcp_src =
2285       gst_element_get_request_pad (session->session, "send_rtcp_src");
2286   if (session->send_rtcp_src == NULL)
2287     goto pad_failed;
2288
2289   result =
2290       gst_ghost_pad_new_from_template (name, session->send_rtcp_src, templ);
2291   gst_pad_set_active (result, TRUE);
2292   gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), result);
2293
2294   return result;
2295
2296   /* ERRORS */
2297 no_name:
2298   {
2299     g_warning ("gstrtpbin: invalid name given");
2300     return NULL;
2301   }
2302 no_session:
2303   {
2304     g_warning ("gstrtpbin: session with id %d does not exist", sessid);
2305     return NULL;
2306   }
2307 existed:
2308   {
2309     g_warning ("gstrtpbin: send_rtcp_src pad already requested for session %d",
2310         sessid);
2311     return NULL;
2312   }
2313 pad_failed:
2314   {
2315     g_warning ("gstrtpbin: failed to get rtcp pad for session %d", sessid);
2316     return NULL;
2317   }
2318 }
2319
2320 /* If the requested name is NULL we should create a name with
2321  * the session number assuming we want the lowest posible session
2322  * with a free pad like the template */
2323 static gchar *
2324 gst_rtp_bin_get_free_pad_name (GstElement * element, GstPadTemplate * templ)
2325 {
2326   gboolean name_found = FALSE;
2327   gint session = 0;
2328   GstPad *pad = NULL;
2329   GstIterator *pad_it = NULL;
2330   gchar *pad_name = NULL;
2331
2332   GST_DEBUG_OBJECT (element, "find a free pad name for template");
2333   while (!name_found) {
2334     g_free (pad_name);
2335     pad_name = g_strdup_printf (templ->name_template, session++);
2336     pad_it = gst_element_iterate_pads (GST_ELEMENT (element));
2337     name_found = TRUE;
2338     while (gst_iterator_next (pad_it, (gpointer) & pad) == GST_ITERATOR_OK) {
2339       gchar *name;
2340
2341       name = gst_pad_get_name (pad);
2342       if (strcmp (name, pad_name) == 0)
2343         name_found = FALSE;
2344       g_free (name);
2345     }
2346     gst_iterator_free (pad_it);
2347   }
2348
2349   GST_DEBUG_OBJECT (element, "free pad name found: '%s'", pad_name);
2350   return pad_name;
2351 }
2352
2353 /* 
2354  */
2355 static GstPad *
2356 gst_rtp_bin_request_new_pad (GstElement * element,
2357     GstPadTemplate * templ, const gchar * name)
2358 {
2359   GstRtpBin *rtpbin;
2360   GstElementClass *klass;
2361   GstPad *result;
2362
2363   gchar *pad_name = NULL;
2364
2365   g_return_val_if_fail (templ != NULL, NULL);
2366   g_return_val_if_fail (GST_IS_RTP_BIN (element), NULL);
2367
2368   rtpbin = GST_RTP_BIN (element);
2369   klass = GST_ELEMENT_GET_CLASS (element);
2370
2371   GST_RTP_BIN_LOCK (rtpbin);
2372
2373   if (name == NULL) {
2374     /* use a free pad name */
2375     pad_name = gst_rtp_bin_get_free_pad_name (element, templ);
2376   } else {
2377     /* use the provided name */
2378     pad_name = g_strdup (name);
2379   }
2380
2381   GST_DEBUG ("Trying to request a pad with name %s", pad_name);
2382
2383   /* figure out the template */
2384   if (templ == gst_element_class_get_pad_template (klass, "recv_rtp_sink_%d")) {
2385     result = create_recv_rtp (rtpbin, templ, pad_name);
2386   } else if (templ == gst_element_class_get_pad_template (klass,
2387           "recv_rtcp_sink_%d")) {
2388     result = create_recv_rtcp (rtpbin, templ, pad_name);
2389   } else if (templ == gst_element_class_get_pad_template (klass,
2390           "send_rtp_sink_%d")) {
2391     result = create_send_rtp (rtpbin, templ, pad_name);
2392   } else if (templ == gst_element_class_get_pad_template (klass,
2393           "send_rtcp_src_%d")) {
2394     result = create_rtcp (rtpbin, templ, pad_name);
2395   } else
2396     goto wrong_template;
2397
2398   g_free (pad_name);
2399   GST_RTP_BIN_UNLOCK (rtpbin);
2400
2401   return result;
2402
2403   /* ERRORS */
2404 wrong_template:
2405   {
2406     g_free (pad_name);
2407     GST_RTP_BIN_UNLOCK (rtpbin);
2408     g_warning ("gstrtpbin: this is not our template");
2409     return NULL;
2410   }
2411 }
2412
2413 static void
2414 gst_rtp_bin_release_pad (GstElement * element, GstPad * pad)
2415 {
2416 }