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 <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 
     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                                                   */
    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                                                   */
    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.
    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
    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 */
    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
    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
    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
    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  */
    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  */
    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 
    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 
    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 
    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