From 719343c2069cc515d5fce2de071574560467f47e Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 26 Jul 2013 00:14:29 +0200 Subject: [PATCH] rtpsession: separate BYE marking and scheduling First mark sources with BYE and then schedule the BYE RTCP message. --- gst/rtpmanager/gstrtpsession.c | 4 +-- gst/rtpmanager/rtpsession.c | 66 +++++++++++++++++++++++++++--------------- gst/rtpmanager/rtpsession.h | 6 ++-- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 361542f..98912fb 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -1763,8 +1763,8 @@ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstObject * parent, ret = gst_pad_push_event (rtpsession->send_rtp_src, event); current_time = gst_clock_get_time (rtpsession->priv->sysclock); GST_DEBUG_OBJECT (rtpsession, "scheduling BYE message"); - rtp_session_schedule_bye (rtpsession->priv->session, "End of stream", - current_time); + rtp_session_mark_all_bye (rtpsession->priv->session, "End Of Stream"); + rtp_session_schedule_bye (rtpsession->priv->session, current_time); break; } default:{ diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index e109ef0..8318a08 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -125,7 +125,7 @@ G_DEFINE_TYPE (RTPSession, rtp_session, G_TYPE_OBJECT); static RTPSource *obtain_source (RTPSession * sess, guint32 ssrc, gboolean * created, RTPArrivalStats * arrival, gboolean rtp); static GstFlowReturn rtp_session_schedule_bye_locked (RTPSession * sess, - const gchar * reason, GstClockTime current_time); + GstClockTime current_time); static GstClockTime calculate_rtcp_interval (RTPSession * sess, gboolean deterministic, gboolean first); @@ -1278,8 +1278,8 @@ check_collision (RTPSession * sess, RTPSource * source, sess->change_ssrc = TRUE; - rtp_session_schedule_bye_locked (sess, "SSRC Collision", - arrival->current_time); + rtp_source_mark_bye (source, "SSRC Collision"); + rtp_session_schedule_bye_locked (sess, arrival->current_time); } } @@ -2021,7 +2021,7 @@ rtp_session_process_bye (RTPSession * sess, GstRTCPPacket * packet, } members = sess->stats.active_sources; - if (!sess->source->marked_bye && members < pmembers) { + if (!sess->scheduled_bye && members < pmembers) { /* some members went away since the previous timeout estimate. * Perform reverse reconsideration but only when we are not scheduling a * BYE ourselves. */ @@ -2291,7 +2291,7 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, type = gst_rtcp_packet_get_type (&packet); /* when we are leaving the session, we should ignore all non-BYE messages */ - if (sess->source->marked_bye && type != GST_RTCP_TYPE_BYE) { + if (sess->scheduled_bye && type != GST_RTCP_TYPE_BYE) { GST_DEBUG ("ignoring non-BYE RTCP packet because we are leaving"); goto next; } @@ -2331,7 +2331,7 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, /* if we are scheduling a BYE, we only want to count bye packets, else we * count everything */ - if (sess->source->marked_bye) { + if (sess->scheduled_bye) { if (is_bye) { sess->stats.bye_members++; UPDATE_AVG (sess->stats.avg_rtcp_packet_size, arrival.bytes); @@ -2479,7 +2479,7 @@ calculate_rtcp_interval (RTPSession * sess, gboolean deterministic, sess->recalc_bandwidth = FALSE; } - if (sess->source->marked_bye) { + if (sess->scheduled_bye) { result = rtp_stats_calculate_bye_interval (&sess->stats); } else { result = rtp_stats_calculate_rtcp_interval (&sess->stats, @@ -2497,27 +2497,47 @@ calculate_rtcp_interval (RTPSession * sess, gboolean deterministic, return result; } +static void +source_mark_bye (const gchar * key, RTPSource * source, const gchar * reason) +{ + if (source->internal) + rtp_source_mark_bye (source, reason); +} + +/** + * rtp_session_mark_all_bye: + * @sess: an #RTPSession + * @reason: a reason + * + * Mark all internal sources of the session as BYE with @reason. + */ +void +rtp_session_mark_all_bye (RTPSession * sess, const gchar * reason) +{ + g_return_if_fail (RTP_IS_SESSION (sess)); + + RTP_SESSION_LOCK (sess); + g_hash_table_foreach (sess->ssrcs[sess->mask_idx], + (GHFunc) source_mark_bye, (gpointer) reason); + RTP_SESSION_UNLOCK (sess); +} + /* Stop the current @sess and schedule a BYE message for the other members. * One must have the session lock to call this function */ static GstFlowReturn -rtp_session_schedule_bye_locked (RTPSession * sess, const gchar * reason, - GstClockTime current_time) +rtp_session_schedule_bye_locked (RTPSession * sess, GstClockTime current_time) { GstFlowReturn result = GST_FLOW_OK; - RTPSource *source; GstClockTime interval; - g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); - - source = sess->source; - - /* ignore more BYEs */ - if (source->marked_bye) + /* nothing to do it we already scheduled bye */ + if (sess->scheduled_bye) goto done; - /* we have BYE now */ - rtp_source_mark_bye (source, reason); + /* we schedule BYE now */ + sess->scheduled_bye = TRUE; + /* at least one member wants to send a BYE */ INIT_AVG (sess->stats.avg_rtcp_packet_size, 100); sess->stats.bye_members = 1; sess->first_rtcp = TRUE; @@ -2548,23 +2568,21 @@ done: /** * rtp_session_schedule_bye: * @sess: an #RTPSession - * @reason: a reason or NULL * @current_time: the current system time * - * Stop the current @sess and schedule a BYE message for the other members. + * Schedule a BYE message for all sources marked as BYE in @sess. * * Returns: a #GstFlowReturn. */ GstFlowReturn -rtp_session_schedule_bye (RTPSession * sess, const gchar * reason, - GstClockTime current_time) +rtp_session_schedule_bye (RTPSession * sess, GstClockTime current_time) { GstFlowReturn result = GST_FLOW_OK; g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR); RTP_SESSION_LOCK (sess); - result = rtp_session_schedule_bye_locked (sess, reason, current_time); + result = rtp_session_schedule_bye_locked (sess, current_time); RTP_SESSION_UNLOCK (sess); return result; @@ -2607,7 +2625,7 @@ rtp_session_next_timeout (RTPSession * sess, GstClockTime current_time) result = current_time; } - if (sess->source->marked_bye) { + if (sess->scheduled_bye) { if (sess->source->sent_bye) { GST_DEBUG ("we sent BYE already"); interval = GST_CLOCK_TIME_NONE; diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 4dbd8a4..4a27397 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -213,6 +213,8 @@ struct _RTPSession { GstClockTime next_early_rtcp_time; + gboolean scheduled_bye; + RTPSessionCallbacks callbacks; gpointer process_rtp_user_data; gpointer send_rtp_user_data; @@ -327,8 +329,8 @@ GstFlowReturn rtp_session_send_rtp (RTPSession *sess, gpointer d GstClockTime current_time, GstClockTime running_time); /* stopping the session */ -GstFlowReturn rtp_session_schedule_bye (RTPSession *sess, const gchar *reason, - GstClockTime current_time); +void rtp_session_mark_all_bye (RTPSession *sess, const gchar *reason); +GstFlowReturn rtp_session_schedule_bye (RTPSession *sess, GstClockTime current_time); /* get interval for next RTCP interval */ GstClockTime rtp_session_next_timeout (RTPSession *sess, GstClockTime current_time); -- 2.7.4