X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Frtpmanager%2Fgstrtpbin.c;h=fbed41415536c4759bdd13c4d7bc1140794e52dd;hb=f05e14ba316d67b9cdf1440d9b2129da03625a30;hp=66470c2d25be8cb029feda987f78a46abfa6a03a;hpb=db688c5504916b780514aa3fda63fb6487a83174;p=platform%2Fupstream%2Fgst-plugins-good.git diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index 66470c2..fbed414 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -1,21 +1,21 @@ -/* GStreamer - * Copyright (C) <2007> Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ + /* GStreamer + * Copyright (C) <2007> Wim Taymans + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ /** * SECTION:element-rtpbin @@ -53,13 +53,6 @@ * SSRC in the RTP packets to its own SSRC and wil forward the packets on the * send_rtp_src_\%u pad after updating its internal state. * - * #GstRtpBin can also demultiplex incoming bundled streams. The first - * #GstRtpSession will have a #GstRtpSsrcDemux element splitting the streams - * based on their SSRC and potentially dispatched to a different #GstRtpSession. - * Because retransmission SSRCs need to be merged with the corresponding media - * stream the #GstRtpBin::on-bundled-ssrc signal is emitted so that the - * application can find out to which session the SSRC belongs. - * * The session manager needs the clock-rate of the payload types it is handling * and will signal the #GstRtpSession::request-pt-map signal when it needs such a * mapping. One can clear the cached values with the #GstRtpSession::clear-pt-map @@ -204,9 +197,6 @@ static GstStaticPadTemplate rtpbin_send_rtp_src_template = GST_STATIC_CAPS ("application/x-rtp;application/x-srtp") ); -#define GST_RTP_BIN_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTP_BIN, GstRtpBinPrivate)) - #define GST_RTP_BIN_LOCK(bin) g_mutex_lock (&(bin)->priv->bin_lock) #define GST_RTP_BIN_UNLOCK(bin) g_mutex_unlock (&(bin)->priv->bin_lock) @@ -387,12 +377,12 @@ static void free_client (GstRtpBinClient * client, GstRtpBin * bin); static void free_stream (GstRtpBinStream * stream, GstRtpBin * bin); static GstRtpBinSession *create_session (GstRtpBin * rtpbin, gint id); static GstPad *complete_session_sink (GstRtpBin * rtpbin, - GstRtpBinSession * session, gboolean bundle_demuxer_needed); + GstRtpBinSession * session); static void complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session, guint sessid); static GstPad *complete_session_rtcp (GstRtpBin * rtpbin, - GstRtpBinSession * session, guint sessid, gboolean bundle_demuxer_needed); + GstRtpBinSession * session, guint sessid); /* Manages the RTP stream for one SSRC. * @@ -418,7 +408,9 @@ struct _GstRtpBinStream gulong buffer_ptreq_sig; gulong buffer_ntpstop_sig; gint percent; - +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + gint prev_percent; +#endif /* the PT demuxer of the SSRC */ GstElement *demux; gulong demux_newpad_sig; @@ -465,12 +457,6 @@ struct _GstRtpBinSession /* Fec support */ GstElement *storage; - /* Bundling support */ - GstElement *rtp_funnel; - GstElement *rtcp_funnel; - GstElement *bundle_demux; - gulong bundle_demux_newpad_sig; - GMutex lock; /* list of GstRtpBinStream */ @@ -671,102 +657,6 @@ ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad, GST_RTP_BIN_UNLOCK (rtpbin); } -static void -new_bundled_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad, - GstRtpBinSession * session) -{ - GValue result = G_VALUE_INIT; - GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT }; - guint session_id = 0; - GstRtpBinSession *target_session = NULL; - GstRtpBin *rtpbin = session->bin; - gchar *name; - GstPad *src_pad; - GstPad *recv_rtp_sink = NULL; - GstPad *recv_rtcp_sink = NULL; - GstPadLinkReturn ret; - - GST_RTP_BIN_DYN_LOCK (rtpbin); - GST_DEBUG_OBJECT (rtpbin, "new bundled SSRC pad %08x, %s:%s", ssrc, - GST_DEBUG_PAD_NAME (pad)); - - g_value_init (&result, G_TYPE_UINT); - g_value_init (¶ms[0], GST_TYPE_ELEMENT); - g_value_set_object (¶ms[0], rtpbin); - g_value_init (¶ms[1], G_TYPE_UINT); - g_value_set_uint (¶ms[1], ssrc); - - g_signal_emitv (params, - gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC], 0, &result); - g_value_unset (¶ms[0]); - - session_id = g_value_get_uint (&result); - if (session_id == 0) { - target_session = session; - } else { - target_session = find_session_by_id (rtpbin, (gint) session_id); - if (!target_session) { - target_session = create_session (rtpbin, session_id); - } - if (!target_session) { - /* create_session() warned already */ - GST_RTP_BIN_DYN_UNLOCK (rtpbin); - return; - } - - if (!target_session->recv_rtp_sink) { - recv_rtp_sink = complete_session_sink (rtpbin, target_session, FALSE); - } - - if (!target_session->recv_rtp_src) - complete_session_receiver (rtpbin, target_session, session_id); - - if (!target_session->recv_rtcp_sink) { - recv_rtcp_sink = - complete_session_rtcp (rtpbin, target_session, session_id, FALSE); - } - } - - GST_DEBUG_OBJECT (rtpbin, "Assigning bundled ssrc %u to session %u", ssrc, - session_id); - - if (!recv_rtp_sink) { - recv_rtp_sink = - gst_element_get_request_pad (target_session->rtp_funnel, "sink_%u"); - } - - if (!recv_rtcp_sink) { - recv_rtcp_sink = - gst_element_get_request_pad (target_session->rtcp_funnel, "sink_%u"); - } - - name = g_strdup_printf ("src_%u", ssrc); - src_pad = gst_element_get_static_pad (element, name); - ret = gst_pad_link (src_pad, recv_rtp_sink); - g_free (name); - gst_object_unref (src_pad); - gst_object_unref (recv_rtp_sink); - if (ret != GST_PAD_LINK_OK) { - g_warning - ("rtpbin: failed to link bundle demuxer to receive rtp funnel for session %u", - session_id); - } - - name = g_strdup_printf ("rtcp_src_%u", ssrc); - src_pad = gst_element_get_static_pad (element, name); - gst_pad_link (src_pad, recv_rtcp_sink); - g_free (name); - gst_object_unref (src_pad); - gst_object_unref (recv_rtcp_sink); - if (ret != GST_PAD_LINK_OK) { - g_warning - ("rtpbin: failed to link bundle demuxer to receive rtcp sink pad for session %u", - session_id); - } - - GST_RTP_BIN_DYN_UNLOCK (rtpbin); -} - /* create a session with the given id. Must be called with RTP_BIN_LOCK */ static GstRtpBinSession * create_session (GstRtpBin * rtpbin, gint id) @@ -785,6 +675,9 @@ create_session (GstRtpBin * rtpbin, gint id) if (!(storage = gst_element_factory_make ("rtpstorage", NULL))) goto no_storage; + /* need to sink the storage or otherwise signal handlers from bindings will + * take ownership of it and we don't own it anymore */ + gst_object_ref_sink (storage); g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_STORAGE], 0, storage, id); @@ -796,9 +689,6 @@ create_session (GstRtpBin * rtpbin, gint id) sess->demux = demux; sess->storage = storage; - sess->rtp_funnel = gst_element_factory_make ("funnel", NULL); - sess->rtcp_funnel = gst_element_factory_make ("funnel", NULL); - sess->ptmap = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) gst_caps_unref); rtpbin->sessions = g_slist_prepend (rtpbin->sessions, sess); @@ -846,10 +736,12 @@ create_session (GstRtpBin * rtpbin, gint id) gst_bin_add (GST_BIN_CAST (rtpbin), session); gst_bin_add (GST_BIN_CAST (rtpbin), demux); - gst_bin_add (GST_BIN_CAST (rtpbin), sess->rtp_funnel); - gst_bin_add (GST_BIN_CAST (rtpbin), sess->rtcp_funnel); gst_bin_add (GST_BIN_CAST (rtpbin), storage); + /* unref the storage again, the bin has a reference now and + * we don't need it anymore */ + gst_object_unref (storage); + GST_OBJECT_LOCK (rtpbin); target = GST_STATE_TARGET (rtpbin); GST_OBJECT_UNLOCK (rtpbin); @@ -857,8 +749,6 @@ create_session (GstRtpBin * rtpbin, gint id) /* change state only to what's needed */ gst_element_set_state (demux, target); gst_element_set_state (session, target); - gst_element_set_state (sess->rtp_funnel, target); - gst_element_set_state (sess->rtcp_funnel, target); gst_element_set_state (storage, target); return sess; @@ -945,9 +835,11 @@ free_session (GstRtpBinSession * sess, GstRtpBin * bin) gst_element_set_locked_state (sess->demux, TRUE); gst_element_set_locked_state (sess->session, TRUE); + gst_element_set_locked_state (sess->storage, TRUE); gst_element_set_state (sess->demux, GST_STATE_NULL); gst_element_set_state (sess->session, GST_STATE_NULL); + gst_element_set_state (sess->storage, GST_STATE_NULL); remove_recv_rtp (bin, sess); remove_recv_rtcp (bin, sess); @@ -956,6 +848,7 @@ free_session (GstRtpBinSession * sess, GstRtpBin * bin) gst_bin_remove (GST_BIN_CAST (bin), sess->session); gst_bin_remove (GST_BIN_CAST (bin), sess->demux); + gst_bin_remove (GST_BIN_CAST (bin), sess->storage); g_slist_foreach (sess->elements, (GFunc) remove_bin_element, bin); g_slist_free (sess->elements); @@ -1799,6 +1692,9 @@ static GstRtpBinStream * create_stream (GstRtpBinSession * session, guint32 ssrc) { GstElement *buffer, *demux = NULL; +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + GstElement *queue2 = NULL; +#endif GstRtpBinStream *stream; GstRtpBin *rtpbin; GstState target; @@ -1815,7 +1711,11 @@ create_stream (GstRtpBinSession * session, guint32 ssrc) if (!(demux = gst_element_factory_make ("rtpptdemux", NULL))) goto no_demux; } - +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + if (session->bin->buffer_mode == RTP_JITTER_BUFFER_MODE_SLAVE) + if (!(queue2 = gst_element_factory_make ("queue2", NULL))) + goto no_queue2; +#endif stream = g_new0 (GstRtpBinStream, 1); stream->ssrc = ssrc; stream->bin = rtpbin; @@ -1827,6 +1727,9 @@ create_stream (GstRtpBinSession * session, guint32 ssrc) stream->rt_delta = 0; stream->rtp_delta = 0; stream->percent = 100; +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + stream->prev_percent = 0; +#endif stream->clock_base = -100 * GST_SECOND; session->streams = g_slist_prepend (session->streams, stream); @@ -1853,18 +1756,53 @@ create_stream (GstRtpBinSession * session, guint32 ssrc) g_object_set (buffer, "max-ts-offset-adjustment", rtpbin->max_ts_offset_adjustment, NULL); +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + /* configure queue2 to use live buffering */ + if (queue2) { + g_object_set_data (G_OBJECT (queue2), "GstRTPBin.stream", stream); + g_object_set (queue2, "use-buffering", TRUE, NULL); + g_object_set (queue2, "buffer-mode", GST_BUFFERING_LIVE, NULL); + } +#endif + /* need to sink the jitterbufer or otherwise signal handlers from bindings will + * take ownership of it and we don't own it anymore */ + gst_object_ref_sink (buffer); g_signal_emit (rtpbin, gst_rtp_bin_signals[SIGNAL_NEW_JITTERBUFFER], 0, buffer, session->id, ssrc); if (!rtpbin->ignore_pt) gst_bin_add (GST_BIN_CAST (rtpbin), demux); + +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + if (queue2) + gst_bin_add (GST_BIN_CAST (rtpbin), queue2); +#endif + gst_bin_add (GST_BIN_CAST (rtpbin), buffer); + /* unref the jitterbuffer again, the bin has a reference now and + * we don't need it anymore */ + gst_object_unref (buffer); + /* link stuff */ +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + if (queue2) { + gst_element_link_pads_full (buffer, "src", queue2, "sink", + GST_PAD_LINK_CHECK_NOTHING); + if (demux) { + gst_element_link_pads_full (queue2, "src", demux, "sink", + GST_PAD_LINK_CHECK_NOTHING); + } + } else if (demux) { + gst_element_link_pads_full (buffer, "src", demux, "sink", + GST_PAD_LINK_CHECK_NOTHING); + } +#else if (demux) gst_element_link_pads_full (buffer, "src", demux, "sink", GST_PAD_LINK_CHECK_NOTHING); +#endif if (rtpbin->buffering) { guint64 last_out; @@ -1884,6 +1822,11 @@ create_stream (GstRtpBinSession * session, guint32 ssrc) gst_element_set_state (buffer, target); +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + if (queue2) + gst_element_set_state (queue2, target); +#endif + return stream; /* ERRORS */ @@ -1904,6 +1847,15 @@ no_demux: g_warning ("rtpbin: could not create rtpptdemux element"); return NULL; } +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION +no_queue2: + { + gst_object_unref (buffer); + gst_object_unref (demux); + g_warning ("rtpbin: could not create queue2 element"); + return NULL; + } +#endif } /* called with RTP_BIN_LOCK */ @@ -1983,7 +1935,7 @@ static void gst_rtp_bin_release_pad (GstElement * element, GstPad * pad); static void gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message); #define gst_rtp_bin_parent_class parent_class -G_DEFINE_TYPE (GstRtpBin, gst_rtp_bin, GST_TYPE_BIN); +G_DEFINE_TYPE_WITH_PRIVATE (GstRtpBin, gst_rtp_bin, GST_TYPE_BIN); static gboolean _gst_element_accumulator (GSignalInvocationHint * ihint, @@ -2028,8 +1980,6 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) gstelement_class = (GstElementClass *) klass; gstbin_class = (GstBinClass *) klass; - g_type_class_add_private (klass, sizeof (GstRtpBinPrivate)); - gobject_class->dispose = gst_rtp_bin_dispose; gobject_class->finalize = gst_rtp_bin_finalize; gobject_class->set_property = gst_rtp_bin_set_property; @@ -2502,29 +2452,6 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass) on_sender_ssrc_active), NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - - /** - * GstRtpBin::on-bundled-ssrc: - * @rtpbin: the object which received the signal - * @ssrc: the bundled SSRC - * - * Notify of a new incoming bundled SSRC. If no handler is connected to the - * signal then the #GstRtpSession created for the recv_rtp_sink_\%u - * request pad will be managing this new SSRC. However if there is a handler - * connected then the application can decided to dispatch this new stream to - * another session by providing its ID as return value of the handler. This - * can be particularly useful to keep retransmission SSRCs grouped with the - * session for which they handle retransmission. - * - * Since: 1.12 - */ - gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC] = - g_signal_new ("on-bundled-ssrc", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass, - on_bundled_ssrc), NULL, NULL, - g_cclosure_marshal_generic, G_TYPE_UINT, 1, G_TYPE_UINT); - - g_object_class_install_property (gobject_class, PROP_SDES, g_param_spec_boxed ("sdes", "SDES", "The SDES items of this session", @@ -2754,7 +2681,7 @@ gst_rtp_bin_init (GstRtpBin * rtpbin) { gchar *cname; - rtpbin->priv = GST_RTP_BIN_GET_PRIVATE (rtpbin); + rtpbin->priv = gst_rtp_bin_get_instance_private (rtpbin); g_mutex_init (&rtpbin->priv->bin_lock); g_mutex_init (&rtpbin->priv->dyn_lock); @@ -3160,6 +3087,9 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) gint min_percent = 100; GSList *sessions, *streams; GstRtpBinStream *stream; +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + gboolean buffering_flag = FALSE, update_buffering_status = TRUE; +#endif gboolean change = FALSE, active = FALSE; GstClockTime min_out_time; GstBufferingMode mode; @@ -3192,13 +3122,52 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) for (streams = session->streams; streams; streams = g_slist_next (streams)) { GstRtpBinStream *stream = (GstRtpBinStream *) streams->data; - +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + GstPad *temp_pad_src = NULL; + GstCaps *temp_caps_src = NULL; + GstStructure *caps_structure; + const gchar *caps_str_media = NULL; + temp_pad_src = gst_element_get_static_pad (stream->buffer, "src"); + temp_caps_src = gst_pad_get_current_caps (temp_pad_src); + GST_DEBUG_OBJECT (bin, + "stream %p percent %d : temp_caps_src=%" GST_PTR_FORMAT, + stream, stream->percent, temp_caps_src); + if (temp_caps_src) { + caps_structure = gst_caps_get_structure (temp_caps_src, 0); + caps_str_media = + gst_structure_get_string (caps_structure, "media"); + if (caps_str_media != NULL) { + if ((strcmp (caps_str_media, "video") != 0) + && (strcmp (caps_str_media, "audio") != 0)) { + GST_DEBUG_OBJECT (bin, + "Non Audio/Video Stream.. ignoring the same !!"); + gst_caps_unref (temp_caps_src); + gst_object_unref (temp_pad_src); + continue; + } else if (stream->percent >= 100) { + /* Most of the time buffering icon displays in rtsp playback. + Optimizing the buffering updation code. Whenever any stream percentage + reaches 100 do not post buffering messages. */ + if (stream->prev_percent < 100) + buffering_flag = TRUE; + else + update_buffering_status = FALSE; + } + } + gst_caps_unref (temp_caps_src); + } + gst_object_unref (temp_pad_src); +#else GST_DEBUG_OBJECT (bin, "stream %p percent %d", stream, stream->percent); - +#endif /* find min percent */ if (min_percent > stream->percent) min_percent = stream->percent; +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + /* Updating prev stream percentage */ + stream->prev_percent = stream->percent; +#endif } } else { GST_INFO_OBJECT (bin, @@ -3208,7 +3177,24 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) GST_RTP_SESSION_UNLOCK (session); } GST_DEBUG_OBJECT (bin, "min percent %d", min_percent); - +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + if (rtpbin->buffer_mode != RTP_JITTER_BUFFER_MODE_SLAVE) { + if (rtpbin->buffering) { + if (min_percent == 100) { + rtpbin->buffering = FALSE; + active = TRUE; + change = TRUE; + } + } else { + if (min_percent < 100) { + /* pause the streams */ + rtpbin->buffering = TRUE; + active = FALSE; + change = TRUE; + } + } + } +#else if (rtpbin->buffering) { if (min_percent == 100) { rtpbin->buffering = FALSE; @@ -3223,16 +3209,31 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) change = TRUE; } } +#endif GST_RTP_BIN_UNLOCK (rtpbin); gst_message_unref (message); +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + if (rtpbin->buffer_mode == RTP_JITTER_BUFFER_MODE_SLAVE) { + if (update_buffering_status == FALSE) + break; + if (buffering_flag) { + min_percent = 100; + GST_DEBUG_OBJECT (bin, "forcefully change min_percent to 100!!!"); + } + } +#endif /* make a new buffering message with the min value */ message = gst_message_new_buffering (GST_OBJECT_CAST (bin), min_percent); gst_message_set_buffering_stats (message, mode, avg_in, avg_out, buffering_left); +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION + if (rtpbin->buffer_mode == RTP_JITTER_BUFFER_MODE_SLAVE) + goto slave_buffering; +#endif if (G_UNLIKELY (change)) { GstClock *clock; guint64 running_time = 0; @@ -3310,6 +3311,9 @@ gst_rtp_bin_handle_message (GstBin * bin, GstMessage * message) GST_RTP_BIN_UNLOCK (rtpbin); } } +#ifdef TIZEN_FEATURE_RTSP_MODIFICATION +slave_buffering: +#endif GST_BIN_CLASS (parent_class)->handle_message (bin, message); break; } @@ -3402,23 +3406,16 @@ copy_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data) return TRUE; } -/* a new pad (SSRC) was created in @session. This signal is emitted from the - * payload demuxer. */ static void -new_payload_found (GstElement * element, guint pt, GstPad * pad, - GstRtpBinStream * stream) +expose_recv_src_pad (GstRtpBin * rtpbin, GstPad * pad, GstRtpBinStream * stream, + guint8 pt) { - GstRtpBin *rtpbin; GstElementClass *klass; GstPadTemplate *templ; gchar *padname; GstPad *gpad; - rtpbin = stream->bin; - - GST_DEBUG_OBJECT (rtpbin, "new payload pad %u", pt); - - pad = gst_object_ref (pad); + gst_object_ref (pad); if (stream->session->storage) { GstElement *fec_decoder = @@ -3497,6 +3494,21 @@ fec_decoder_link_failed: } } +/* a new pad (SSRC) was created in @session. This signal is emited from the + * payload demuxer. */ +static void +new_payload_found (GstElement * element, guint pt, GstPad * pad, + GstRtpBinStream * stream) +{ + GstRtpBin *rtpbin; + + rtpbin = stream->bin; + + GST_DEBUG_OBJECT (rtpbin, "new payload pad %u", pt); + + expose_recv_src_pad (rtpbin, pad, stream, pt); +} + static void payload_pad_removed (GstElement * element, GstPad * pad, GstRtpBinStream * stream) @@ -3680,33 +3692,23 @@ new_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad, /* connect to the signal so it can be forwarded. */ stream->demux_ptchange_sig = g_signal_connect (stream->demux, "payload-type-change", (GCallback) payload_type_change, session); + + GST_RTP_SESSION_UNLOCK (session); + GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin); } else { /* add rtpjitterbuffer src pad to pads */ - GstElementClass *klass; - GstPadTemplate *templ; - gchar *padname; - GstPad *gpad, *pad; + GstPad *pad; pad = gst_element_get_static_pad (stream->buffer, "src"); - /* ghost the pad to the parent */ - klass = GST_ELEMENT_GET_CLASS (rtpbin); - templ = gst_element_class_get_pad_template (klass, "recv_rtp_src_%u_%u_%u"); - padname = g_strdup_printf ("recv_rtp_src_%u_%u_%u", - stream->session->id, stream->ssrc, 255); - gpad = gst_ghost_pad_new_from_template (padname, pad, templ); - g_free (padname); + GST_RTP_SESSION_UNLOCK (session); + GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin); - gst_pad_set_active (gpad, TRUE); - gst_pad_sticky_events_foreach (pad, copy_sticky_events, gpad); - gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), gpad); + expose_recv_src_pad (rtpbin, pad, stream, 255); gst_object_unref (pad); } - GST_RTP_SESSION_UNLOCK (session); - GST_RTP_BIN_SHUTDOWN_UNLOCK (rtpbin); - return; /* ERRORS */ @@ -3724,39 +3726,11 @@ no_stream: } } -static void -session_maybe_create_bundle_demuxer (GstRtpBinSession * session) -{ - GstRtpBin *rtpbin; - - if (session->bundle_demux) - return; - - rtpbin = session->bin; - if (g_signal_has_handler_pending (rtpbin, - gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC], 0, TRUE)) { - GST_DEBUG_OBJECT (rtpbin, "Adding a bundle SSRC demuxer to session %u", - session->id); - session->bundle_demux = gst_element_factory_make ("rtpssrcdemux", NULL); - session->bundle_demux_newpad_sig = g_signal_connect (session->bundle_demux, - "new-ssrc-pad", (GCallback) new_bundled_ssrc_pad_found, session); - - gst_bin_add (GST_BIN_CAST (rtpbin), session->bundle_demux); - gst_element_sync_state_with_parent (session->bundle_demux); - } else { - GST_DEBUG_OBJECT (rtpbin, - "No handler for the on-bundled-ssrc signal so no need for a bundle SSRC demuxer in session %u", - session->id); - } -} - static GstPad * -complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session, - gboolean bundle_demuxer_needed) +complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session) { guint sessid = session->id; GstPad *recv_rtp_sink; - GstPad *funnel_src; GstElement *decoder; g_assert (!session->recv_rtp_sink); @@ -3770,9 +3744,6 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session, g_signal_connect (session->recv_rtp_sink, "notify::caps", (GCallback) caps_changed, session); - if (bundle_demuxer_needed) - session_maybe_create_bundle_demuxer (session); - GST_DEBUG_OBJECT (rtpbin, "requesting RTP decoder"); decoder = session_request_element (session, SIGNAL_REQUEST_RTP_DECODER); if (decoder) { @@ -3790,14 +3761,8 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session, if (decsrc == NULL) goto dec_src_failed; - if (session->bundle_demux) { - GstPad *demux_sink; - demux_sink = gst_element_get_static_pad (session->bundle_demux, "sink"); - ret = gst_pad_link (decsrc, demux_sink); - gst_object_unref (demux_sink); - } else { - ret = gst_pad_link (decsrc, session->recv_rtp_sink); - } + ret = gst_pad_link (decsrc, session->recv_rtp_sink); + gst_object_unref (decsrc); if (ret != GST_PAD_LINK_OK) @@ -3805,19 +3770,9 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session, } else { GST_DEBUG_OBJECT (rtpbin, "no RTP decoder given"); - if (session->bundle_demux) { - recv_rtp_sink = - gst_element_get_static_pad (session->bundle_demux, "sink"); - } else { - recv_rtp_sink = - gst_element_get_request_pad (session->rtp_funnel, "sink_%u"); - } + recv_rtp_sink = gst_object_ref (session->recv_rtp_sink); } - funnel_src = gst_element_get_static_pad (session->rtp_funnel, "src"); - gst_pad_link (funnel_src, session->recv_rtp_sink); - gst_object_unref (funnel_src); - return recv_rtp_sink; /* ERRORS */ @@ -3975,11 +3930,10 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name) return session->recv_rtp_sink_ghost; /* setup the session sink pad */ - recv_rtp_sink = complete_session_sink (rtpbin, session, TRUE); + recv_rtp_sink = complete_session_sink (rtpbin, session); if (!recv_rtp_sink) goto session_sink_failed; - GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad"); session->recv_rtp_sink_ghost = gst_ghost_pad_new_from_template (name, recv_rtp_sink, templ); @@ -4020,11 +3974,6 @@ remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session) g_signal_handler_disconnect (session->demux, session->demux_padremoved_sig); session->demux_padremoved_sig = 0; } - if (session->bundle_demux_newpad_sig) { - g_signal_handler_disconnect (session->bundle_demux, - session->bundle_demux_newpad_sig); - session->bundle_demux_newpad_sig = 0; - } if (session->recv_rtp_src) { gst_object_unref (session->recv_rtp_src); session->recv_rtp_src = NULL; @@ -4044,12 +3993,11 @@ remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session) static GstPad * complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session, - guint sessid, gboolean bundle_demuxer_needed) + guint sessid) { GstElement *decoder; GstPad *sinkdpad; GstPad *decsink = NULL; - GstPad *funnel_src; /* get recv_rtp pad and store */ GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad"); @@ -4058,9 +4006,6 @@ complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session, if (session->recv_rtcp_sink == NULL) goto pad_failed; - if (bundle_demuxer_needed) - session_maybe_create_bundle_demuxer (session); - GST_DEBUG_OBJECT (rtpbin, "getting RTCP decoder"); decoder = session_request_element (session, SIGNAL_REQUEST_RTCP_DECODER); if (decoder) { @@ -4077,26 +4022,15 @@ complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session, if (decsrc == NULL) goto dec_src_failed; - if (session->bundle_demux) { - GstPad *demux_sink; - demux_sink = - gst_element_get_static_pad (session->bundle_demux, "rtcp_sink"); - ret = gst_pad_link (decsrc, demux_sink); - gst_object_unref (demux_sink); - } else { - ret = gst_pad_link (decsrc, session->recv_rtcp_sink); - } + ret = gst_pad_link (decsrc, session->recv_rtcp_sink); + gst_object_unref (decsrc); if (ret != GST_PAD_LINK_OK) goto dec_link_failed; } else { GST_DEBUG_OBJECT (rtpbin, "no RTCP decoder given"); - if (session->bundle_demux) { - decsink = gst_element_get_static_pad (session->bundle_demux, "rtcp_sink"); - } else { - decsink = gst_element_get_request_pad (session->rtcp_funnel, "sink_%u"); - } + decsink = gst_object_ref (session->recv_rtcp_sink); } /* get srcpad, link to SSRCDemux */ @@ -4110,10 +4044,6 @@ complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session, gst_pad_link_full (session->sync_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING); gst_object_unref (sinkdpad); - funnel_src = gst_element_get_static_pad (session->rtcp_funnel, "src"); - gst_pad_link (funnel_src, session->recv_rtcp_sink); - gst_object_unref (funnel_src); - return decsink; pad_failed: @@ -4177,7 +4107,7 @@ create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ, if (session->recv_rtcp_sink_ghost != NULL) return session->recv_rtcp_sink_ghost; - decsink = complete_session_rtcp (rtpbin, session, sessid, TRUE); + decsink = complete_session_rtcp (rtpbin, session, sessid); if (!decsink) goto create_error; @@ -4376,8 +4306,9 @@ create_error: } existing_session: { - g_warning ("rtpbin: session %u is already a sender", sessid); - return FALSE; + GST_DEBUG_OBJECT (rtpbin, + "skipping src_%i setup, since it is already configured.", sessid); + return TRUE; } pad_failed: {