Home | History | Annotate | Download | only in source
      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 
     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                                                   */
    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                                                   */
    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.
    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
    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 */
    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
    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]. */
    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 
    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 
    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 
    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 
    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  */
    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  */
    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 
    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 
    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 
    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