From 0da5cf2e21add8e128db79a39079b163575b6a83 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 7 May 2010 16:55:13 +0200 Subject: [PATCH] rtpstats: make bandwidths more configurable Add a method to configure the various bandwidths in the session. --- gst/rtpmanager/rtpstats.c | 99 ++++++++++++++++++++++++++++++++++----- gst/rtpmanager/rtpstats.h | 13 +++-- 2 files changed, 95 insertions(+), 17 deletions(-) diff --git a/gst/rtpmanager/rtpstats.c b/gst/rtpmanager/rtpstats.c index 04849ff0cc..1f14eb22ae 100644 --- a/gst/rtpmanager/rtpstats.c +++ b/gst/rtpmanager/rtpstats.c @@ -28,20 +28,85 @@ void rtp_stats_init_defaults (RTPSessionStats * stats) { - stats->bandwidth = RTP_STATS_BANDWIDTH; - stats->sender_fraction = RTP_STATS_SENDER_FRACTION; - stats->receiver_fraction = RTP_STATS_RECEIVER_FRACTION; - stats->rtcp_bandwidth = RTP_STATS_RTCP_BANDWIDTH; + rtp_stats_set_bandwidths (stats, -1, -1, -1, -1); stats->min_interval = RTP_STATS_MIN_INTERVAL; stats->bye_timeout = RTP_STATS_BYE_TIMEOUT; } +/** + * rtp_stats_set_bandwidths: + * @stats: an #RTPSessionStats struct + * @rtp_bw: RTP bandwidth + * @rtcp_bw: RTCP bandwidth + * @rs: sender RTCP bandwidth + * @rr: receiver RTCP bandwidth + * + * Configure the bandwidth parameters in the stats. When an input variable is + * set to -1, it will be calculated from the other input variables and from the + * defaults. + */ +void +rtp_stats_set_bandwidths (RTPSessionStats * stats, guint rtp_bw, guint rtcp_bw, + guint rs, guint rr) +{ + /* when given, sender and receive bandwidth add up to the total + * rtcp bandwidth */ + if (rs != -1 && rr != -1) + rtcp_bw = rs + rr; + + /* RTCP is 5% of the RTP bandwidth */ + if (rtp_bw == -1 && rtcp_bw != -1) + rtp_bw = rtcp_bw * 20; + else if (rtp_bw != -1 && rtcp_bw == -1) + rtcp_bw = rtp_bw / 20; + else if (rtp_bw == -1 && rtcp_bw == -1) { + /* nothing given, take defaults */ + rtp_bw = RTP_STATS_BANDWIDTH; + rtcp_bw = RTP_STATS_RTCP_BANDWIDTH; + } + stats->bandwidth = rtp_bw; + stats->rtcp_bandwidth = rtcp_bw; + + /* now figure out the fractions */ + if (rs == -1) { + /* rs unknown */ + if (rr == -1) { + /* both not given, use defaults */ + rs = stats->rtcp_bandwidth * RTP_STATS_SENDER_FRACTION; + rr = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION; + } else { + /* rr known, calculate rs */ + if (stats->rtcp_bandwidth > rr) + rs = stats->rtcp_bandwidth - rr; + else + rs = 0; + } + } else if (rr == -1) { + /* rs known, calculate rr */ + if (stats->rtcp_bandwidth > rs) + rr = stats->rtcp_bandwidth - rs; + else + rr = 0; + } + + if (stats->rtcp_bandwidth > 0) { + stats->sender_fraction = ((gdouble) rs) / ((gdouble) stats->rtcp_bandwidth); + stats->receiver_fraction = 1.0 - stats->sender_fraction; + } else { + /* no RTCP bandwidth, set dummy values */ + stats->sender_fraction = 0.0; + stats->receiver_fraction = 0.0; + } + GST_DEBUG ("bandwidths: RTP %u, RTCP %u, RS %f, RR %f", stats->bandwidth, + stats->rtcp_bandwidth, stats->sender_fraction, stats->receiver_fraction); +} + /** * 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 nanoseconds) before sending a new RTCP message. * @@ -74,16 +139,21 @@ rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send, senders = (gdouble) stats->sender_sources; rtcp_bw = stats->rtcp_bandwidth; - if (senders <= members * RTP_STATS_SENDER_FRACTION) { + if (senders <= members * stats->sender_fraction) { if (we_send) { - rtcp_bw *= RTP_STATS_SENDER_FRACTION; + rtcp_bw *= stats->sender_fraction; n = senders; } else { - rtcp_bw *= RTP_STATS_RECEIVER_FRACTION; + rtcp_bw *= stats->receiver_fraction; n -= senders; } } + /* no bandwidth for RTCP, return NONE to signal that we don't want to send + * RTCP packets */ + if (rtcp_bw <= 0.00001) + return GST_CLOCK_TIME_NONE; + avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0; /* * The effective number of sites times the average packet size is @@ -105,7 +175,7 @@ rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send, * rtp_stats_add_rtcp_jitter: * @stats: an #RTPSessionStats struct * @interval: an RTCP interval - * + * * Apply a random jitter to the @interval. @interval is typically obtained with * rtp_stats_calculate_rtcp_interval(). * @@ -116,7 +186,7 @@ rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval) { gdouble temp; - /* see RFC 3550 p 30 + /* see RFC 3550 p 30 * To compensate for "unconditional reconsideration" converging to a * value below the intended average. */ @@ -131,7 +201,7 @@ rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval) /** * 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. * @@ -156,7 +226,12 @@ rtp_stats_calculate_bye_interval (RTPSessionStats * stats) * more than that fraction. */ members = stats->bye_members; - rtcp_bw = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION; + rtcp_bw = stats->rtcp_bandwidth * stats->receiver_fraction; + + /* no bandwidth for RTCP, return NONE to signal that we don't want to send + * RTCP packets */ + if (rtcp_bw <= 0.0001) + return GST_CLOCK_TIME_NONE; avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0; /* diff --git a/gst/rtpmanager/rtpstats.h b/gst/rtpmanager/rtpstats.h index 7e742e6ed9..d650a7be63 100644 --- a/gst/rtpmanager/rtpstats.h +++ b/gst/rtpmanager/rtpstats.h @@ -127,8 +127,8 @@ typedef struct { RTPSenderReport sr[2]; } RTPSourceStats; -#define RTP_STATS_BANDWIDTH 64000.0 -#define RTP_STATS_RTCP_BANDWIDTH 3000.0 +#define RTP_STATS_BANDWIDTH 64000 +#define RTP_STATS_RTCP_BANDWIDTH 3200 /* * Minimum average time between RTCP packets from this site (in * seconds). This time prevents the reports from `clumping' when @@ -172,10 +172,10 @@ typedef struct { * Stats kept for a session and used to produce RTCP packet timeouts. */ typedef struct { - gdouble bandwidth; + guint bandwidth; + guint rtcp_bandwidth; gdouble sender_fraction; gdouble receiver_fraction; - gdouble rtcp_bandwidth; gdouble min_interval; GstClockTime bye_timeout; guint sender_sources; @@ -184,7 +184,10 @@ typedef struct { guint bye_members; } RTPSessionStats; -void rtp_stats_init_defaults (RTPSessionStats *stats); +void rtp_stats_init_defaults (RTPSessionStats *stats); + +void rtp_stats_set_bandwidths (RTPSessionStats *stats, guint rtp_bw, guint rtcp_bw, + guint rs, guint rr); GstClockTime rtp_stats_calculate_rtcp_interval (RTPSessionStats *stats, gboolean sender, gboolean first); GstClockTime rtp_stats_add_rtcp_jitter (RTPSessionStats *stats, GstClockTime interval);