1e18f45ed58b536ddd93b9d058aa2cdf5f145671
[platform/upstream/gst-plugins-good.git] / gst / rtpmanager / rtpstats.c
1 /* GStreamer
2  * Copyright (C) <2007> Wim Taymans <wim@fluendo.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., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "rtpstats.h"
21
22 /**
23  * rtp_stats_init_defaults:
24  * @stats: an #RTPSessionStats struct
25  *
26  * Initialize @stats with its default values.
27  */
28 void
29 rtp_stats_init_defaults (RTPSessionStats * stats)
30 {
31   stats->bandwidth = RTP_STATS_BANDWIDTH;
32   stats->sender_fraction = RTP_STATS_SENDER_FRACTION;
33   stats->receiver_fraction = RTP_STATS_RECEIVER_FRACTION;
34   stats->rtcp_bandwidth = RTP_STATS_RTCP_BANDWIDTH;
35   stats->min_interval = RTP_STATS_MIN_INTERVAL;
36   stats->bye_timeout = RTP_STATS_BYE_TIMEOUT;
37 }
38
39 /**
40  * rtp_stats_calculate_rtcp_interval:
41  * @stats: an #RTPSessionStats struct
42  * @sender: if we are a sender
43  * @first: if this is the first time
44  * 
45  * Calculate the RTCP interval. The result of this function is the amount of
46  * time to wait (in nanoseconds) before sending a new RTCP message.
47  *
48  * Returns: the RTCP interval.
49  */
50 GstClockTime
51 rtp_stats_calculate_rtcp_interval (RTPSessionStats * stats, gboolean we_send,
52     gboolean first)
53 {
54   gdouble members, senders, n;
55   gdouble avg_rtcp_size, rtcp_bw;
56   gdouble interval;
57   gdouble rtcp_min_time;
58
59
60   /* Very first call at application start-up uses half the min
61    * delay for quicker notification while still allowing some time
62    * before reporting for randomization and to learn about other
63    * sources so the report interval will converge to the correct
64    * interval more quickly.
65    */
66   rtcp_min_time = stats->min_interval;
67   if (first)
68     rtcp_min_time /= 2.0;
69
70   /* Dedicate a fraction of the RTCP bandwidth to senders unless
71    * the number of senders is large enough that their share is
72    * more than that fraction.
73    */
74   n = members = stats->active_sources;
75   senders = (gdouble) stats->sender_sources;
76   rtcp_bw = stats->rtcp_bandwidth;
77
78   if (senders <= members * RTP_STATS_SENDER_FRACTION) {
79     if (we_send) {
80       rtcp_bw *= RTP_STATS_SENDER_FRACTION;
81       n = senders;
82     } else {
83       rtcp_bw *= RTP_STATS_RECEIVER_FRACTION;
84       n -= senders;
85     }
86   }
87
88   avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0;
89   /*
90    * The effective number of sites times the average packet size is
91    * the total number of octets sent when each site sends a report.
92    * Dividing this by the effective bandwidth gives the time
93    * interval over which those packets must be sent in order to
94    * meet the bandwidth target, with a minimum enforced.  In that
95    * time interval we send one report so this time is also our
96    * average time between reports.
97    */
98   interval = avg_rtcp_size * n / rtcp_bw;
99   if (interval < rtcp_min_time)
100     interval = rtcp_min_time;
101
102   return interval * GST_SECOND;
103 }
104
105 /**
106  * rtp_stats_add_rtcp_jitter:
107  * @stats: an #RTPSessionStats struct
108  * @interval: an RTCP interval
109  * 
110  * Apply a random jitter to the @interval. @interval is typically obtained with
111  * rtp_stats_calculate_rtcp_interval().
112  *
113  * Returns: the new RTCP interval.
114  */
115 GstClockTime
116 rtp_stats_add_rtcp_jitter (RTPSessionStats * stats, GstClockTime interval)
117 {
118   gdouble temp;
119
120   /* see RFC 3550 p 30 
121    * To compensate for "unconditional reconsideration" converging to a
122    * value below the intended average.
123    */
124 #define COMPENSATION  (2.71828 - 1.5);
125
126   temp = (interval * g_random_double_range (0.5, 1.5)) / COMPENSATION;
127
128   return (GstClockTime) temp;
129 }
130
131
132 /**
133  * rtp_stats_calculate_bye_interval:
134  * @stats: an #RTPSessionStats struct
135  * 
136  * Calculate the BYE interval. The result of this function is the amount of
137  * time to wait (in nanoseconds) before sending a BYE message.
138  *
139  * Returns: the BYE interval.
140  */
141 GstClockTime
142 rtp_stats_calculate_bye_interval (RTPSessionStats * stats)
143 {
144   gdouble members;
145   gdouble avg_rtcp_size, rtcp_bw;
146   gdouble interval;
147   gdouble rtcp_min_time;
148
149   rtcp_min_time = (stats->min_interval) / 2.0;
150
151   /* Dedicate a fraction of the RTCP bandwidth to senders unless
152    * the number of senders is large enough that their share is
153    * more than that fraction.
154    */
155   members = stats->bye_members;
156   rtcp_bw = stats->rtcp_bandwidth * RTP_STATS_RECEIVER_FRACTION;
157
158   avg_rtcp_size = stats->avg_rtcp_packet_size / 16.0;
159   /*
160    * The effective number of sites times the average packet size is
161    * the total number of octets sent when each site sends a report.
162    * Dividing this by the effective bandwidth gives the time
163    * interval over which those packets must be sent in order to
164    * meet the bandwidth target, with a minimum enforced.  In that
165    * time interval we send one report so this time is also our
166    * average time between reports.
167    */
168   interval = avg_rtcp_size * members / rtcp_bw;
169   if (interval < rtcp_min_time)
170     interval = rtcp_min_time;
171
172   return interval * GST_SECOND;
173 }