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