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