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