1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 /*
12  * BwEstimator.c
13  *
14  * This file contains the code for the Bandwidth Estimator designed
15  * for iSAC.
16  *
17  */
18 
19 #include "bandwidth_estimator.h"
20 #include "settings.h"
21 #include "isac.h"
22 
23 #include <math.h>
24 
25 /* array of quantization levels for bottle neck info; Matlab code: */
26 /* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */
27 static const float kQRateTableWb[12] =
28 {
29   10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
30   18859.8f, 20963.3f, 23301.4f, 25900.3f, 28789.0f, 32000.0f};
31 
32 
33 static const float kQRateTableSwb[24] =
34 {
35   10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
36   18859.8f, 20963.3f, 23153.1f, 25342.9f, 27532.7f, 29722.5f,
37   31912.3f, 34102.1f, 36291.9f, 38481.7f, 40671.4f, 42861.2f,
38   45051.0f, 47240.8f, 49430.6f, 51620.4f, 53810.2f, 56000.0f,
39 };
40 
41 
42 
43 
WebRtcIsac_InitBandwidthEstimator(BwEstimatorstr * bwest_str,enum IsacSamplingRate encoderSampRate,enum IsacSamplingRate decoderSampRate)44 WebRtc_Word32 WebRtcIsac_InitBandwidthEstimator(
45     BwEstimatorstr*              bwest_str,
46     enum IsacSamplingRate encoderSampRate,
47     enum IsacSamplingRate decoderSampRate)
48 {
49   switch(encoderSampRate)
50   {
51     case kIsacWideband:
52       {
53         bwest_str->send_bw_avg       = INIT_BN_EST_WB;
54         break;
55       }
56     case kIsacSuperWideband:
57       {
58         bwest_str->send_bw_avg       = INIT_BN_EST_SWB;
59         break;
60       }
61     default:
62       return -1;
63   }
64 
65   switch(decoderSampRate)
66   {
67     case kIsacWideband:
68       {
69         bwest_str->prev_frame_length = INIT_FRAME_LEN_WB;
70         bwest_str->rec_bw_inv        = 1.0f /
71             (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
72         bwest_str->rec_bw            = (WebRtc_Word32)INIT_BN_EST_WB;
73         bwest_str->rec_bw_avg_Q      = INIT_BN_EST_WB;
74         bwest_str->rec_bw_avg        = INIT_BN_EST_WB + INIT_HDR_RATE_WB;
75         bwest_str->rec_header_rate   = INIT_HDR_RATE_WB;
76         break;
77       }
78     case kIsacSuperWideband:
79       {
80         bwest_str->prev_frame_length = INIT_FRAME_LEN_SWB;
81         bwest_str->rec_bw_inv        = 1.0f /
82             (INIT_BN_EST_SWB + INIT_HDR_RATE_SWB);
83         bwest_str->rec_bw            = (WebRtc_Word32)INIT_BN_EST_SWB;
84         bwest_str->rec_bw_avg_Q      = INIT_BN_EST_SWB;
85         bwest_str->rec_bw_avg        = INIT_BN_EST_SWB + INIT_HDR_RATE_SWB;
86         bwest_str->rec_header_rate   = INIT_HDR_RATE_SWB;
87         break;
88       }
89     default:
90       return -1;
91   }
92 
93   bwest_str->prev_rec_rtp_number       = 0;
94   bwest_str->prev_rec_arr_ts           = 0;
95   bwest_str->prev_rec_send_ts          = 0;
96   bwest_str->prev_rec_rtp_rate         = 1.0f;
97   bwest_str->last_update_ts            = 0;
98   bwest_str->last_reduction_ts         = 0;
99   bwest_str->count_tot_updates_rec     = -9;
100   bwest_str->rec_jitter                = 10.0f;
101   bwest_str->rec_jitter_short_term     = 0.0f;
102   bwest_str->rec_jitter_short_term_abs = 5.0f;
103   bwest_str->rec_max_delay             = 10.0f;
104   bwest_str->rec_max_delay_avg_Q       = 10.0f;
105   bwest_str->num_pkts_rec              = 0;
106 
107   bwest_str->send_max_delay_avg        = 10.0f;
108 
109   bwest_str->hsn_detect_rec = 0;
110 
111   bwest_str->num_consec_rec_pkts_over_30k = 0;
112 
113   bwest_str->hsn_detect_snd = 0;
114 
115   bwest_str->num_consec_snt_pkts_over_30k = 0;
116 
117   bwest_str->in_wait_period = 0;
118 
119   bwest_str->change_to_WB = 0;
120 
121   bwest_str->numConsecLatePkts = 0;
122   bwest_str->consecLatency = 0;
123   bwest_str->inWaitLatePkts = 0;
124   bwest_str->senderTimestamp = 0;
125   bwest_str->receiverTimestamp = 0;
126   return 0;
127 }
128 
129 /* This function updates both bottle neck rates                                                      */
130 /* Parameters:                                                                                       */
131 /* rtp_number    - value from RTP packet, from NetEq                                                 */
132 /* frame length  - length of signal frame in ms, from iSAC decoder                                   */
133 /* send_ts       - value in RTP header giving send time in samples                                     */
134 /* arr_ts        - value given by timeGetTime() time of arrival in samples of packet from NetEq      */
135 /* pksize        - size of packet in bytes, from NetEq                                               */
136 /* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
137 /* returns 0 if everything went fine, -1 otherwise                                                   */
WebRtcIsac_UpdateBandwidthEstimator(BwEstimatorstr * bwest_str,const WebRtc_UWord16 rtp_number,const WebRtc_Word32 frame_length,const WebRtc_UWord32 send_ts,const WebRtc_UWord32 arr_ts,const WebRtc_Word32 pksize)138 WebRtc_Word16 WebRtcIsac_UpdateBandwidthEstimator(
139     BwEstimatorstr *bwest_str,
140     const WebRtc_UWord16 rtp_number,
141     const WebRtc_Word32  frame_length,
142     const WebRtc_UWord32 send_ts,
143     const WebRtc_UWord32 arr_ts,
144     const WebRtc_Word32  pksize
145     /*,    const WebRtc_UWord16 Index*/)
146 {
147   float weight = 0.0f;
148   float curr_bw_inv = 0.0f;
149   float rec_rtp_rate;
150   float t_diff_proj;
151   float arr_ts_diff;
152   float send_ts_diff;
153   float arr_time_noise;
154   float arr_time_noise_abs;
155 
156   float delay_correction_factor = 1;
157   float late_diff = 0.0f;
158   int immediate_set = 0;
159   int num_pkts_expected;
160 
161 
162   // We have to adjust the header-rate if the first packet has a
163   // frame-size different than the initialized value.
164   if ( frame_length != bwest_str->prev_frame_length )
165   {
166     bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
167         1000.0f / (float)frame_length;     /* bits/s */
168   }
169 
170   /* UPDATE ESTIMATES ON THIS SIDE */
171   /* compute far-side transmission rate */
172   rec_rtp_rate = ((float)pksize * 8.0f * 1000.0f / (float)frame_length) +
173       bwest_str->rec_header_rate;
174   // rec_rtp_rate packet bits/s + header bits/s
175 
176   /* check for timer wrap-around */
177   if (arr_ts < bwest_str->prev_rec_arr_ts)
178   {
179     bwest_str->prev_rec_arr_ts   = arr_ts;
180     bwest_str->last_update_ts    = arr_ts;
181     bwest_str->last_reduction_ts = arr_ts + 3*FS;
182     bwest_str->num_pkts_rec      = 0;
183 
184     /* store frame length */
185     bwest_str->prev_frame_length = frame_length;
186 
187     /* store far-side transmission rate */
188     bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
189 
190     /* store far-side RTP time stamp */
191     bwest_str->prev_rec_rtp_number = rtp_number;
192 
193     return 0;
194   }
195 
196   bwest_str->num_pkts_rec++;
197 
198   /* check that it's not one of the first 9 packets */
199   if ( bwest_str->count_tot_updates_rec > 0 )
200   {
201     if(bwest_str->in_wait_period > 0 )
202     {
203       bwest_str->in_wait_period--;
204     }
205 
206     bwest_str->inWaitLatePkts -= ((bwest_str->inWaitLatePkts > 0)? 1:0);
207     send_ts_diff = (float)(send_ts - bwest_str->prev_rec_send_ts);
208 
209     if (send_ts_diff <= (16 * frame_length)*2)
210       //doesn't allow for a dropped packet, not sure necessary to be
211       // that strict -DH
212     {
213       /* if not been updated for a long time, reduce the BN estimate */
214       if((WebRtc_UWord32)(arr_ts - bwest_str->last_update_ts) *
215          1000.0f / FS > 3000)
216       {
217         //how many frames should have been received since the last
218         // update if too many have been dropped or there have been
219         // big delays won't allow this reduction may no longer need
220         // the send_ts_diff here
221         num_pkts_expected = (int)(((float)(arr_ts -
222                                            bwest_str->last_update_ts) * 1000.0f /(float) FS) /
223                                   (float)frame_length);
224 
225         if(((float)bwest_str->num_pkts_rec/(float)num_pkts_expected) >
226            0.9)
227         {
228           float inv_bitrate = (float) pow( 0.99995,
229                                            (double)((WebRtc_UWord32)(arr_ts -
230                                                                      bwest_str->last_reduction_ts)*1000.0f/FS) );
231 
232           if ( inv_bitrate )
233           {
234             bwest_str->rec_bw_inv /= inv_bitrate;
235 
236             //precautionary, likely never necessary
237             if (bwest_str->hsn_detect_snd &&
238                 bwest_str->hsn_detect_rec)
239             {
240               if (bwest_str->rec_bw_inv > 0.000066f)
241               {
242                 bwest_str->rec_bw_inv = 0.000066f;
243               }
244             }
245           }
246           else
247           {
248             bwest_str->rec_bw_inv = 1.0f /
249                 (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
250           }
251           /* reset time-since-update counter */
252           bwest_str->last_reduction_ts = arr_ts;
253         }
254         else
255           //reset here?
256         {
257           bwest_str->last_reduction_ts = arr_ts + 3*FS;
258           bwest_str->last_update_ts = arr_ts;
259           bwest_str->num_pkts_rec = 0;
260         }
261       }
262     }
263     else
264     {
265       bwest_str->last_reduction_ts = arr_ts + 3*FS;
266       bwest_str->last_update_ts = arr_ts;
267       bwest_str->num_pkts_rec = 0;
268     }
269 
270 
271     /* temporarily speed up adaptation if frame length has changed */
272     if ( frame_length != bwest_str->prev_frame_length )
273     {
274       bwest_str->count_tot_updates_rec = 10;
275       bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
276           1000.0f / (float)frame_length;     /* bits/s */
277 
278       bwest_str->rec_bw_inv = 1.0f /((float)bwest_str->rec_bw +
279                                      bwest_str->rec_header_rate);
280     }
281 
282     ////////////////////////
283     arr_ts_diff = (float)(arr_ts - bwest_str->prev_rec_arr_ts);
284 
285     if (send_ts_diff > 0 )
286     {
287       late_diff = arr_ts_diff - send_ts_diff;
288     }
289     else
290     {
291       late_diff = arr_ts_diff - (float)(16 * frame_length);
292     }
293 
294     if((late_diff > 0) && !bwest_str->inWaitLatePkts)
295     {
296       bwest_str->numConsecLatePkts++;
297       bwest_str->consecLatency += late_diff;
298     }
299     else
300     {
301       bwest_str->numConsecLatePkts = 0;
302       bwest_str->consecLatency = 0;
303     }
304     if(bwest_str->numConsecLatePkts > 50)
305     {
306       float latencyMs = bwest_str->consecLatency/(FS/1000);
307       float averageLatencyMs = latencyMs / bwest_str->numConsecLatePkts;
308       delay_correction_factor = frame_length / (frame_length + averageLatencyMs);
309       immediate_set = 1;
310       bwest_str->inWaitLatePkts = (WebRtc_Word16)((bwest_str->consecLatency/(FS/1000)) / 30);// + 150;
311       bwest_str->start_wait_period = arr_ts;
312     }
313     ///////////////////////////////////////////////
314 
315 
316 
317     /*   update only if previous packet was not lost */
318     if ( rtp_number == bwest_str->prev_rec_rtp_number + 1 )
319     {
320 
321 
322       if (!(bwest_str->hsn_detect_snd && bwest_str->hsn_detect_rec))
323       {
324         if ((arr_ts_diff > (float)(16 * frame_length)))
325         {
326           //1/2 second
327           if ((late_diff > 8000.0f) && !bwest_str->in_wait_period)
328           {
329             delay_correction_factor = 0.7f;
330             bwest_str->in_wait_period = 55;
331             bwest_str->start_wait_period = arr_ts;
332             immediate_set = 1;
333           }
334           //320 ms
335           else if (late_diff > 5120.0f && !bwest_str->in_wait_period)
336           {
337             delay_correction_factor = 0.8f;
338             immediate_set = 1;
339             bwest_str->in_wait_period = 44;
340             bwest_str->start_wait_period = arr_ts;
341           }
342         }
343       }
344 
345 
346       if ((bwest_str->prev_rec_rtp_rate > bwest_str->rec_bw_avg) &&
347           (rec_rtp_rate > bwest_str->rec_bw_avg)                 &&
348           !bwest_str->in_wait_period)
349       {
350         /* test if still in initiation period and increment counter */
351         if (bwest_str->count_tot_updates_rec++ > 99)
352         {
353           /* constant weight after initiation part */
354           weight = 0.01f;
355         }
356         else
357         {
358           /* weight decreases with number of updates */
359           weight = 1.0f / (float) bwest_str->count_tot_updates_rec;
360         }
361         /* Bottle Neck Estimation */
362 
363         /* limit outliers */
364         /* if more than 25 ms too much */
365         if (arr_ts_diff > frame_length * FS/1000 + 400.0f)
366         {
367           // in samples,  why 25ms??
368           arr_ts_diff = frame_length * FS/1000 + 400.0f;
369         }
370         if(arr_ts_diff < (frame_length * FS/1000) - 160.0f)
371         {
372           /* don't allow it to be less than frame rate - 10 ms */
373           arr_ts_diff = (float)frame_length * FS/1000 - 160.0f;
374         }
375 
376         /* compute inverse receiving rate for last packet */
377         curr_bw_inv = arr_ts_diff / ((float)(pksize + HEADER_SIZE) *
378                                      8.0f * FS); // (180+35)*8*16000 = 27.5 Mbit....
379 
380 
381         if(curr_bw_inv <
382            (1.0f / (MAX_ISAC_BW + bwest_str->rec_header_rate)))
383         {
384           // don't allow inv rate to be larger than MAX
385           curr_bw_inv = (1.0f /
386                          (MAX_ISAC_BW + bwest_str->rec_header_rate));
387         }
388 
389         /* update bottle neck rate estimate */
390         bwest_str->rec_bw_inv = weight * curr_bw_inv +
391             (1.0f - weight) * bwest_str->rec_bw_inv;
392 
393         /* reset time-since-update counter */
394         bwest_str->last_update_ts    = arr_ts;
395         bwest_str->last_reduction_ts = arr_ts + 3 * FS;
396         bwest_str->num_pkts_rec = 0;
397 
398         /* Jitter Estimation */
399         /* projected difference between arrival times */
400         t_diff_proj = ((float)(pksize + HEADER_SIZE) * 8.0f *
401                        1000.0f) / bwest_str->rec_bw_avg;
402 
403 
404         // difference between projected and actual
405         //   arrival time differences
406         arr_time_noise = (float)(arr_ts_diff*1000.0f/FS) -
407             t_diff_proj;
408         arr_time_noise_abs = (float) fabs( arr_time_noise );
409 
410         /* long term averaged absolute jitter */
411         bwest_str->rec_jitter = weight * arr_time_noise_abs +
412             (1.0f - weight) * bwest_str->rec_jitter;
413         if (bwest_str->rec_jitter > 10.0f)
414         {
415           bwest_str->rec_jitter = 10.0f;
416         }
417         /* short term averaged absolute jitter */
418         bwest_str->rec_jitter_short_term_abs = 0.05f *
419             arr_time_noise_abs + 0.95f *
420             bwest_str->rec_jitter_short_term_abs;
421 
422         /* short term averaged jitter */
423         bwest_str->rec_jitter_short_term = 0.05f * arr_time_noise +
424             0.95f * bwest_str->rec_jitter_short_term;
425       }
426     }
427   }
428   else
429   {
430     // reset time-since-update counter when
431     // receiving the first 9 packets
432     bwest_str->last_update_ts    = arr_ts;
433     bwest_str->last_reduction_ts = arr_ts + 3*FS;
434     bwest_str->num_pkts_rec = 0;
435 
436     bwest_str->count_tot_updates_rec++;
437   }
438 
439   /* limit minimum bottle neck rate */
440   if (bwest_str->rec_bw_inv > 1.0f / ((float)MIN_ISAC_BW +
441                                       bwest_str->rec_header_rate))
442   {
443     bwest_str->rec_bw_inv = 1.0f / ((float)MIN_ISAC_BW +
444                                     bwest_str->rec_header_rate);
445   }
446 
447   // limit maximum bitrate
448   if (bwest_str->rec_bw_inv < 1.0f / ((float)MAX_ISAC_BW +
449                                       bwest_str->rec_header_rate))
450   {
451     bwest_str->rec_bw_inv = 1.0f / ((float)MAX_ISAC_BW +
452                                     bwest_str->rec_header_rate);
453   }
454 
455   /* store frame length */
456   bwest_str->prev_frame_length = frame_length;
457 
458   /* store far-side transmission rate */
459   bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
460 
461   /* store far-side RTP time stamp */
462   bwest_str->prev_rec_rtp_number = rtp_number;
463 
464   // Replace bwest_str->rec_max_delay by the new
465   // value (atomic operation)
466   bwest_str->rec_max_delay = 3.0f * bwest_str->rec_jitter;
467 
468   /* store send and arrival time stamp */
469   bwest_str->prev_rec_arr_ts = arr_ts ;
470   bwest_str->prev_rec_send_ts = send_ts;
471 
472   /* Replace bwest_str->rec_bw by the new value (atomic operation) */
473   bwest_str->rec_bw = (WebRtc_Word32)(1.0f / bwest_str->rec_bw_inv -
474                                       bwest_str->rec_header_rate);
475 
476   if (immediate_set)
477   {
478     bwest_str->rec_bw = (WebRtc_Word32) (delay_correction_factor *
479                                          (float) bwest_str->rec_bw);
480 
481     if (bwest_str->rec_bw < (WebRtc_Word32) MIN_ISAC_BW)
482     {
483       bwest_str->rec_bw = (WebRtc_Word32) MIN_ISAC_BW;
484     }
485 
486     bwest_str->rec_bw_avg = bwest_str->rec_bw +
487         bwest_str->rec_header_rate;
488 
489     bwest_str->rec_bw_avg_Q = (float) bwest_str->rec_bw;
490 
491     bwest_str->rec_jitter_short_term = 0.0f;
492 
493     bwest_str->rec_bw_inv = 1.0f / (bwest_str->rec_bw +
494                                     bwest_str->rec_header_rate);
495 
496     bwest_str->count_tot_updates_rec = 1;
497 
498     immediate_set = 0;
499     bwest_str->consecLatency = 0;
500     bwest_str->numConsecLatePkts = 0;
501   }
502 
503   return 0;
504 }
505 
506 
507 /* This function updates the send bottle neck rate                                                   */
508 /* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
509 /* returns 0 if everything went fine, -1 otherwise                                                   */
WebRtcIsac_UpdateUplinkBwImpl(BwEstimatorstr * bwest_str,WebRtc_Word16 index,enum IsacSamplingRate encoderSamplingFreq)510 WebRtc_Word16 WebRtcIsac_UpdateUplinkBwImpl(
511     BwEstimatorstr*           bwest_str,
512     WebRtc_Word16               index,
513     enum IsacSamplingRate encoderSamplingFreq)
514 {
515   if((index < 0) || (index > 23))
516   {
517     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
518   }
519 
520   /* UPDATE ESTIMATES FROM OTHER SIDE */
521   if(encoderSamplingFreq == kIsacWideband)
522   {
523     if(index > 11)
524     {
525       index -= 12;
526       /* compute the jitter estimate as decoded on the other side */
527       bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
528           0.1f * (float)MAX_ISAC_MD;
529     }
530     else
531     {
532       /* compute the jitter estimate as decoded on the other side */
533       bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
534           0.1f * (float)MIN_ISAC_MD;
535     }
536 
537     /* compute the BN estimate as decoded on the other side */
538     bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
539         0.1f * kQRateTableWb[index];
540   }
541   else
542   {
543     /* compute the BN estimate as decoded on the other side */
544     bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
545         0.1f * kQRateTableSwb[index];
546   }
547 
548   if (bwest_str->send_bw_avg > (float) 28000 && !bwest_str->hsn_detect_snd)
549   {
550     bwest_str->num_consec_snt_pkts_over_30k++;
551 
552     if (bwest_str->num_consec_snt_pkts_over_30k >= 66)
553     {
554       //approx 2 seconds with 30ms frames
555       bwest_str->hsn_detect_snd = 1;
556     }
557   }
558   else if (!bwest_str->hsn_detect_snd)
559   {
560     bwest_str->num_consec_snt_pkts_over_30k = 0;
561   }
562   return 0;
563 }
564 
565 // called when there is upper-band bit-stream to update jitter
566 // statistics.
WebRtcIsac_UpdateUplinkJitter(BwEstimatorstr * bwest_str,WebRtc_Word32 index)567 WebRtc_Word16 WebRtcIsac_UpdateUplinkJitter(
568     BwEstimatorstr*              bwest_str,
569     WebRtc_Word32                  index)
570 {
571   if((index < 0) || (index > 23))
572   {
573     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
574   }
575 
576   if(index > 0)
577   {
578     /* compute the jitter estimate as decoded on the other side */
579     bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
580         0.1f * (float)MAX_ISAC_MD;
581   }
582   else
583   {
584     /* compute the jitter estimate as decoded on the other side */
585     bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
586         0.1f * (float)MIN_ISAC_MD;
587   }
588 
589   return 0;
590 }
591 
592 
593 
594 // Returns the bandwidth/jitter estimation code (integer 0...23)
595 // to put in the sending iSAC payload
596 WebRtc_UWord16
WebRtcIsac_GetDownlinkBwJitIndexImpl(BwEstimatorstr * bwest_str,WebRtc_Word16 * bottleneckIndex,WebRtc_Word16 * jitterInfo,enum IsacSamplingRate decoderSamplingFreq)597 WebRtcIsac_GetDownlinkBwJitIndexImpl(
598     BwEstimatorstr*           bwest_str,
599     WebRtc_Word16*              bottleneckIndex,
600     WebRtc_Word16*              jitterInfo,
601     enum IsacSamplingRate decoderSamplingFreq)
602 {
603   float MaxDelay;
604   //WebRtc_UWord16 MaxDelayBit;
605 
606   float rate;
607   float r;
608   float e1, e2;
609   const float weight = 0.1f;
610   const float* ptrQuantizationTable;
611   WebRtc_Word16 addJitterInfo;
612   WebRtc_Word16 minInd;
613   WebRtc_Word16 maxInd;
614   WebRtc_Word16 midInd;
615 
616   /* Get Max Delay Bit */
617   /* get unquantized max delay */
618   MaxDelay = (float)WebRtcIsac_GetDownlinkMaxDelay(bwest_str);
619 
620   if ( ((1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
621         MAX_ISAC_MD - MaxDelay) > (MaxDelay - (1.f-weight) *
622                                    bwest_str->rec_max_delay_avg_Q - weight * MIN_ISAC_MD) )
623   {
624     jitterInfo[0] = 0;
625     /* update quantized average */
626     bwest_str->rec_max_delay_avg_Q =
627         (1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
628         (float)MIN_ISAC_MD;
629   }
630   else
631   {
632     jitterInfo[0] = 1;
633     /* update quantized average */
634     bwest_str->rec_max_delay_avg_Q =
635         (1.f-weight) * bwest_str->rec_max_delay_avg_Q + weight *
636         (float)MAX_ISAC_MD;
637   }
638 
639   // Get unquantized rate.
640   rate = (float)WebRtcIsac_GetDownlinkBandwidth(bwest_str);
641 
642   /* Get Rate Index */
643   if(decoderSamplingFreq == kIsacWideband)
644   {
645     ptrQuantizationTable = kQRateTableWb;
646     addJitterInfo = 1;
647     maxInd = 11;
648   }
649   else
650   {
651     ptrQuantizationTable = kQRateTableSwb;
652     addJitterInfo = 0;
653     maxInd = 23;
654   }
655 
656   minInd = 0;
657   while(maxInd > minInd + 1)
658   {
659     midInd = (maxInd + minInd) >> 1;
660     if(rate > ptrQuantizationTable[midInd])
661     {
662       minInd = midInd;
663     }
664     else
665     {
666       maxInd = midInd;
667     }
668   }
669   // Chose the index which gives results an average which is closest
670   // to rate
671   r = (1 - weight) * bwest_str->rec_bw_avg_Q - rate;
672   e1 = weight * ptrQuantizationTable[minInd] + r;
673   e2 = weight * ptrQuantizationTable[maxInd] + r;
674   e1 = (e1 > 0)? e1:-e1;
675   e2 = (e2 > 0)? e2:-e2;
676   if(e1 < e2)
677   {
678     bottleneckIndex[0] = minInd;
679   }
680   else
681   {
682     bottleneckIndex[0] = maxInd;
683   }
684 
685   bwest_str->rec_bw_avg_Q = (1 - weight) * bwest_str->rec_bw_avg_Q +
686       weight * ptrQuantizationTable[bottleneckIndex[0]];
687   bottleneckIndex[0] += jitterInfo[0] * 12 * addJitterInfo;
688 
689   bwest_str->rec_bw_avg = (1 - weight) * bwest_str->rec_bw_avg + weight *
690       (rate + bwest_str->rec_header_rate);
691 
692   return 0;
693 }
694 
695 
696 
697 /* get the bottle neck rate from far side to here, as estimated on this side */
WebRtcIsac_GetDownlinkBandwidth(const BwEstimatorstr * bwest_str)698 WebRtc_Word32 WebRtcIsac_GetDownlinkBandwidth( const BwEstimatorstr *bwest_str)
699 {
700   WebRtc_Word32  rec_bw;
701   float   jitter_sign;
702   float   bw_adjust;
703 
704   /* create a value between -1.0 and 1.0 indicating "average sign" of jitter */
705   jitter_sign = bwest_str->rec_jitter_short_term /
706       bwest_str->rec_jitter_short_term_abs;
707 
708   /* adjust bw proportionally to negative average jitter sign */
709   bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
710 
711   /* adjust Rate if jitter sign is mostly constant */
712   rec_bw = (WebRtc_Word32)(bwest_str->rec_bw * bw_adjust);
713 
714   /* limit range of bottle neck rate */
715   if (rec_bw < MIN_ISAC_BW)
716   {
717     rec_bw = MIN_ISAC_BW;
718   }
719   else if (rec_bw > MAX_ISAC_BW)
720   {
721     rec_bw = MAX_ISAC_BW;
722   }
723   return rec_bw;
724 }
725 
726 /* Returns the max delay (in ms) */
727 WebRtc_Word32
WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr * bwest_str)728 WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str)
729 {
730   WebRtc_Word32 rec_max_delay;
731 
732   rec_max_delay = (WebRtc_Word32)(bwest_str->rec_max_delay);
733 
734   /* limit range of jitter estimate */
735   if (rec_max_delay < MIN_ISAC_MD)
736   {
737     rec_max_delay = MIN_ISAC_MD;
738   }
739   else if (rec_max_delay > MAX_ISAC_MD)
740   {
741     rec_max_delay = MAX_ISAC_MD;
742   }
743   return rec_max_delay;
744 }
745 
746 /* get the bottle neck rate from here to far side, as estimated by far side */
747 void
WebRtcIsac_GetUplinkBandwidth(const BwEstimatorstr * bwest_str,WebRtc_Word32 * bitRate)748 WebRtcIsac_GetUplinkBandwidth(
749     const BwEstimatorstr* bwest_str,
750     WebRtc_Word32*          bitRate)
751 {
752   /* limit range of bottle neck rate */
753   if (bwest_str->send_bw_avg < MIN_ISAC_BW)
754   {
755     *bitRate = MIN_ISAC_BW;
756   }
757   else if (bwest_str->send_bw_avg > MAX_ISAC_BW)
758   {
759     *bitRate = MAX_ISAC_BW;
760   }
761   else
762   {
763     *bitRate = (WebRtc_Word32)(bwest_str->send_bw_avg);
764   }
765   return;
766 }
767 
768 /* Returns the max delay value from the other side in ms */
769 WebRtc_Word32
WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr * bwest_str)770 WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str)
771 {
772   WebRtc_Word32 send_max_delay;
773 
774   send_max_delay = (WebRtc_Word32)(bwest_str->send_max_delay_avg);
775 
776   /* limit range of jitter estimate */
777   if (send_max_delay < MIN_ISAC_MD)
778   {
779     send_max_delay = MIN_ISAC_MD;
780   }
781   else if (send_max_delay > MAX_ISAC_MD)
782   {
783     send_max_delay = MAX_ISAC_MD;
784   }
785   return send_max_delay;
786 }
787 
788 
789 /*
790  * update long-term average bitrate and amount of data in buffer
791  * returns minimum payload size (bytes)
792  */
WebRtcIsac_GetMinBytes(RateModel * State,int StreamSize,const int FrameSamples,const double BottleNeck,const double DelayBuildUp,enum ISACBandwidth bandwidth)793 int WebRtcIsac_GetMinBytes(
794     RateModel*         State,
795     int                StreamSize,    /* bytes in bitstream */
796     const int          FrameSamples,  /* samples per frame */
797     const double       BottleNeck,    /* bottle neck rate; excl headers (bps) */
798     const double       DelayBuildUp,  /* max delay from bottleneck buffering (ms) */
799     enum ISACBandwidth bandwidth
800     /*,WebRtc_Word16        frequentLargePackets*/)
801 {
802   double MinRate = 0.0;
803   int    MinBytes;
804   double TransmissionTime;
805   int    burstInterval = BURST_INTERVAL;
806 
807   // first 10 packets @ low rate, then INIT_BURST_LEN packets @
808   // fixed rate of INIT_RATE bps
809   if (State->InitCounter > 0)
810   {
811     if (State->InitCounter-- <= INIT_BURST_LEN)
812     {
813       if(bandwidth == isac8kHz)
814       {
815         MinRate = INIT_RATE_WB;
816       }
817       else
818       {
819         MinRate = INIT_RATE_SWB;
820       }
821     }
822     else
823     {
824       MinRate = 0;
825     }
826   }
827   else
828   {
829     /* handle burst */
830     if (State->BurstCounter)
831     {
832       if (State->StillBuffered < (1.0 - 1.0/BURST_LEN) * DelayBuildUp)
833       {
834         /* max bps derived from BottleNeck and DelayBuildUp values */
835         MinRate = (1.0 + (FS/1000) * DelayBuildUp /
836                    (double)(BURST_LEN * FrameSamples)) * BottleNeck;
837       }
838       else
839       {
840         // max bps derived from StillBuffered and DelayBuildUp
841         // values
842         MinRate = (1.0 + (FS/1000) * (DelayBuildUp -
843                                       State->StillBuffered) / (double)FrameSamples) * BottleNeck;
844         if (MinRate < 1.04 * BottleNeck)
845         {
846           MinRate = 1.04 * BottleNeck;
847         }
848       }
849       State->BurstCounter--;
850     }
851   }
852 
853 
854   /* convert rate from bits/second to bytes/packet */
855   MinBytes = (int) (MinRate * FrameSamples / (8.0 * FS));
856 
857   /* StreamSize will be adjusted if less than MinBytes */
858   if (StreamSize < MinBytes)
859   {
860     StreamSize = MinBytes;
861   }
862 
863   /* keep track of when bottle neck was last exceeded by at least 1% */
864   if (StreamSize * 8.0 * FS / FrameSamples > 1.01 * BottleNeck) {
865     if (State->PrevExceed) {
866       /* bottle_neck exceded twice in a row, decrease ExceedAgo */
867       State->ExceedAgo -= /*BURST_INTERVAL*/ burstInterval / (BURST_LEN - 1);
868       if (State->ExceedAgo < 0)
869         State->ExceedAgo = 0;
870     }
871     else
872     {
873       State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */
874       State->PrevExceed = 1;
875     }
876   }
877   else
878   {
879     State->PrevExceed = 0;
880     State->ExceedAgo += (FrameSamples * 1000) / FS;     /* ms */
881   }
882 
883   /* set burst flag if bottle neck not exceeded for long time */
884   if ((State->ExceedAgo > burstInterval) &&
885       (State->BurstCounter == 0))
886   {
887     if (State->PrevExceed)
888     {
889       State->BurstCounter = BURST_LEN - 1;
890     }
891     else
892     {
893       State->BurstCounter = BURST_LEN;
894     }
895   }
896 
897 
898   /* Update buffer delay */
899   TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
900   State->StillBuffered += TransmissionTime;
901   State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
902   if (State->StillBuffered < 0.0)
903   {
904     State->StillBuffered = 0.0;
905   }
906 
907   return MinBytes;
908 }
909 
910 
911 /*
912  * update long-term average bitrate and amount of data in buffer
913  */
WebRtcIsac_UpdateRateModel(RateModel * State,int StreamSize,const int FrameSamples,const double BottleNeck)914 void WebRtcIsac_UpdateRateModel(
915     RateModel *State,
916     int StreamSize,                    /* bytes in bitstream */
917     const int FrameSamples,            /* samples per frame */
918     const double BottleNeck)        /* bottle neck rate; excl headers (bps) */
919 {
920   double TransmissionTime;
921 
922   /* avoid the initial "high-rate" burst */
923   State->InitCounter = 0;
924 
925   /* Update buffer delay */
926   TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck;  /* ms */
927   State->StillBuffered += TransmissionTime;
928   State->StillBuffered -= (FrameSamples * 1000) / FS;     /* ms */
929   if (State->StillBuffered < 0.0)
930     State->StillBuffered = 0.0;
931 
932 }
933 
934 
WebRtcIsac_InitRateModel(RateModel * State)935 void WebRtcIsac_InitRateModel(
936     RateModel *State)
937 {
938   State->PrevExceed      = 0;                        /* boolean */
939   State->ExceedAgo       = 0;                        /* ms */
940   State->BurstCounter    = 0;                        /* packets */
941   State->InitCounter     = INIT_BURST_LEN + 10;    /* packets */
942   State->StillBuffered   = 1.0;                    /* ms */
943 }
944 
WebRtcIsac_GetNewFrameLength(double bottle_neck,int current_framesamples)945 int WebRtcIsac_GetNewFrameLength(
946     double bottle_neck,
947     int    current_framesamples)
948 {
949   int new_framesamples;
950 
951   const int Thld_20_30 = 20000;
952 
953   //const int Thld_30_20 = 30000;
954   const int Thld_30_20 = 1000000;   // disable 20 ms frames
955 
956   const int Thld_30_60 = 18000;
957   //const int Thld_30_60 = 0;      // disable 60 ms frames
958 
959   const int Thld_60_30 = 27000;
960 
961 
962   new_framesamples = current_framesamples;
963 
964   /* find new framelength */
965   switch(current_framesamples) {
966     case 320:
967       if (bottle_neck < Thld_20_30)
968         new_framesamples = 480;
969       break;
970     case 480:
971       if (bottle_neck < Thld_30_60)
972         new_framesamples = 960;
973       else if (bottle_neck > Thld_30_20)
974         new_framesamples = 320;
975       break;
976     case 960:
977       if (bottle_neck >= Thld_60_30)
978         new_framesamples = 480;
979       break;
980   }
981 
982   return new_framesamples;
983 }
984 
WebRtcIsac_GetSnr(double bottle_neck,int framesamples)985 double WebRtcIsac_GetSnr(
986     double bottle_neck,
987     int    framesamples)
988 {
989   double s2nr;
990 
991   const double a_20 = -30.0;
992   const double b_20 = 0.8;
993   const double c_20 = 0.0;
994 
995   const double a_30 = -23.0;
996   const double b_30 = 0.48;
997   const double c_30 = 0.0;
998 
999   const double a_60 = -23.0;
1000   const double b_60 = 0.53;
1001   const double c_60 = 0.0;
1002 
1003 
1004   /* find new SNR value */
1005   switch(framesamples) {
1006     case 320:
1007       s2nr = a_20 + b_20 * bottle_neck * 0.001 + c_20 * bottle_neck *
1008           bottle_neck * 0.000001;
1009       break;
1010     case 480:
1011       s2nr = a_30 + b_30 * bottle_neck * 0.001 + c_30 * bottle_neck *
1012           bottle_neck * 0.000001;
1013       break;
1014     case 960:
1015       s2nr = a_60 + b_60 * bottle_neck * 0.001 + c_60 * bottle_neck *
1016           bottle_neck * 0.000001;
1017       break;
1018     default:
1019       s2nr = 0;
1020   }
1021 
1022   return s2nr;
1023 
1024 }
1025