summaryrefslogtreecommitdiffstats
path: root/gst/rtpmanager/rtpstats.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/rtpmanager/rtpstats.c')
-rw-r--r--gst/rtpmanager/rtpstats.c134
1 files changed, 98 insertions, 36 deletions
diff --git a/gst/rtpmanager/rtpstats.c b/gst/rtpmanager/rtpstats.c
index 456ed15f..1e18f45e 100644
--- a/gst/rtpmanager/rtpstats.c
+++ b/gst/rtpmanager/rtpstats.c
@@ -33,63 +33,77 @@ rtp_stats_init_defaults (RTPSessionStats * stats)
stats->receiver_fraction = RTP_STATS_RECEIVER_FRACTION;
stats->rtcp_bandwidth = RTP_STATS_RTCP_BANDWIDTH;
stats->min_interval = RTP_STATS_MIN_INTERVAL;
+ stats->bye_timeout = RTP_STATS_BYE_TIMEOUT;
}
/**
* rtp_stats_calculate_rtcp_interval:
* @stats: an #RTPSessionStats struct
+ * @sender: if we are a sender
+ * @first: if this is the first time
*
* Calculate the RTCP interval. The result of this function is the amount of
- * time to wait (in seconds) before sender a new RTCP message.
+ * time to wait (in nanoseconds) before sending a new RTCP message.
*
* Returns: the RTCP interval.
*/
-gdouble
-rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean sender)
+GstClockTime
+rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send,
+ gboolean first)
{
- gdouble active, senders, receivers, sfraction;
- gboolean avg_rtcp;
+ gdouble members, senders, n;
+ gdouble avg_rtcp_size, rtcp_bw;
gdouble interval;
+ gdouble rtcp_min_time;
- active = stats->active_sources;
- /* Try to avoid division by zero */
- if (stats->active_sources == 0)
- active += 1.0;
- senders = (gdouble) stats->sender_sources;
- receivers = (gdouble) (active - senders);
- avg_rtcp = (gdouble) stats->avg_rtcp_packet_size;
-
- sfraction = senders / active;
+ /* Very first call at application start-up uses half the min
+ * delay for quicker notification while still allowing some time
+ * before reporting for randomization and to learn about other
+ * sources so the report interval will converge to the correct
+ * interval more quickly.
+ */
+ rtcp_min_time = stats->min_interval;
+ if (first)
+ rtcp_min_time /= 2.0;
- GST_DEBUG ("senders: %f, receivers %f, avg_rtcp %f, sfraction %f",
- senders, receivers, avg_rtcp, sfraction);
+ /* Dedicate a fraction of the RTCP bandwidth to senders unless
+ * the number of senders is large enough that their share is
+ * more than that fraction.
+ */
+ n = members = stats->active_sources;
+ senders = (gdouble) stats->sender_sources;
+ rtcp_bw = stats->rtcp_bandwidth;
- if (senders > 0 && sfraction <= stats->sender_fraction) {
- if (sender) {
- interval =
- (avg_rtcp * senders) / (stats->sender_fraction *
- stats->rtcp_bandwidth);
+ if (senders <= members * RTP_STATS_SENDER_FRACTION) {
+ if (we_send) {
+ rtcp_bw *= RTP_STATS_SENDER_FRACTION;
+ n = senders;
} else {
- interval =
- (avg_rtcp * receivers) / ((1.0 -
- stats->sender_fraction) * stats->rtcp_bandwidth);
+ rtcp_bw *= RTP_STATS_RECEIVER_FRACTION;
+ n -= senders;
}
- } else {
- interval = (avg_rtcp * active) / stats->rtcp_bandwidth;
}
- if (interval < stats->min_interval)
- interval = stats->min_interval;
-
- if (!stats->sent_rtcp)
- interval /= 2.0;
+ avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0;
+ /*
+ * The effective number of sites times the average packet size is
+ * the total number of octets sent when each site sends a report.
+ * Dividing this by the effective bandwidth gives the time
+ * interval over which those packets must be sent in order to
+ * meet the bandwidth target, with a minimum enforced. In that
+ * time interval we send one report so this time is also our
+ * average time between reports.
+ */
+ interval = avg_rtcp_size * n / rtcp_bw;
+ if (interval < rtcp_min_time)
+ interval = rtcp_min_time;
- return interval;
+ return interval * GST_SECOND;
}
/**
- * rtp_stats_calculate_rtcp_interval:
+ * rtp_stats_add_rtcp_jitter:
* @stats: an #RTPSessionStats struct
* @interval: an RTCP interval
*
@@ -98,14 +112,62 @@ rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean sender)
*
* Returns: the new RTCP interval.
*/
-gdouble
-rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, gdouble interval)
+GstClockTime
+rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval)
{
+ gdouble temp;
+
/* see RFC 3550 p 30
* To compensate for "unconditional reconsideration" converging to a
* value below the intended average.
*/
#define COMPENSATION (2.71828 - 1.5);
- return (interval * g_random_double_range (0.5, 1.5)) / COMPENSATION;
+ temp = (interval * g_random_double_range (0.5, 1.5)) / COMPENSATION;
+
+ return (GstClockTime) temp;
+}
+
+
+/**
+ * rtp_stats_calculate_bye_interval:
+ * @stats: an #RTPSessionStats struct
+ *
+ * Calculate the BYE interval. The result of this function is the amount of
+ * time to wait (in nanoseconds) before sending a BYE message.
+ *
+ * Returns: the BYE interval.
+ */
+GstClockTime
+rtp_stats_calculate_bye_interval (RTPSessionStats * stats)
+{
+ gdouble members;
+ gdouble avg_rtcp_size, rtcp_bw;
+ gdouble interval;
+ gdouble rtcp_min_time;
+
+ rtcp_min_time = (stats->min_interval) / 2.0;
+
+ /* Dedicate a fraction of the RTCP bandwidth to senders unless
+ * the number of senders is large enough that their share is
+ * more than that fraction.
+ */
+ members = stats->bye_members;
+ rtcp_bw = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION;
+
+ avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0;
+ /*
+ * The effective number of sites times the average packet size is
+ * the total number of octets sent when each site sends a report.
+ * Dividing this by the effective bandwidth gives the time
+ * interval over which those packets must be sent in order to
+ * meet the bandwidth target, with a minimum enforced. In that
+ * time interval we send one report so this time is also our
+ * average time between reports.
+ */
+ interval = avg_rtcp_size * members / rtcp_bw;
+ if (interval < rtcp_min_time)
+ interval = rtcp_min_time;
+
+ return interval * GST_SECOND;
}