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