Home | History | Annotate | Download | only in source
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /*
     12  * bandwidth_estimator.c
     13  *
     14  * This file contains the code for the Bandwidth Estimator designed
     15  * for iSAC.
     16  *
     17  * NOTE! Castings needed for C55, do not remove!
     18  *
     19  */
     20 
     21 #include "bandwidth_estimator.h"
     22 #include "settings.h"
     23 
     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 WebRtc_Word16 kQRateTable[12] = {
     28   10000, 11115, 12355, 13733, 15265, 16967,
     29   18860, 20963, 23301, 25900, 28789, 32000
     30 };
     31 
     32 /* 0.1 times the values in the table kQRateTable */
     33 /* values are in Q16                                         */
     34 static const WebRtc_Word32 KQRate01[12] = {
     35   65536000,  72843264,  80969728,  90000589,  100040704, 111194931,
     36   123600896, 137383117, 152705434, 169738240, 188671590, 209715200
     37 };
     38 
     39 /* Bits per Bytes Seconds
     40  * 8 bits/byte * 1000 msec/sec * 1/framelength (in msec)->bits/byte*sec
     41  * frame length will either be 30 or 60 msec. 8738 is 1/60 in Q19 and 1/30 in Q18
     42  * The following number is either in Q15 or Q14 depending on the current frame length */
     43 static const WebRtc_Word32 kBitsByteSec = 4369000;
     44 
     45 /* Received header rate. First value is for 30 ms packets and second for 60 ms */
     46 static const WebRtc_Word16 kRecHeaderRate[2] = {
     47   9333, 4666
     48 };
     49 
     50 /* Inverted minimum and maximum bandwidth in Q30.
     51    minBwInv 30 ms, maxBwInv 30 ms,
     52    minBwInv 60 ms, maxBwInv 69 ms
     53 */
     54 static const WebRtc_Word32 kInvBandwidth[4] = {
     55   55539, 25978,
     56   73213, 29284
     57 };
     58 
     59 /* Number of samples in 25 msec */
     60 static const WebRtc_Word32 kSamplesIn25msec = 400;
     61 
     62 
     63 /****************************************************************************
     64  * WebRtcIsacfix_InitBandwidthEstimator(...)
     65  *
     66  * This function initializes the struct for the bandwidth estimator
     67  *
     68  * Input/Output:
     69  *      - bweStr        : Struct containing bandwidth information.
     70  *
     71  * Return value            : 0
     72  */
     73 WebRtc_Word32 WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bweStr)
     74 {
     75   bweStr->prevFrameSizeMs       = INIT_FRAME_LEN;
     76   bweStr->prevRtpNumber         = 0;
     77   bweStr->prevSendTime          = 0;
     78   bweStr->prevArrivalTime       = 0;
     79   bweStr->prevRtpRate           = 1;
     80   bweStr->lastUpdate            = 0;
     81   bweStr->lastReduction         = 0;
     82   bweStr->countUpdates          = -9;
     83 
     84   /* INIT_BN_EST = 20000
     85    * INIT_BN_EST_Q7 = 2560000
     86    * INIT_HDR_RATE = 4666
     87    * INIT_REC_BN_EST_Q5 = 789312
     88    *
     89    * recBwInv = 1/(INIT_BN_EST + INIT_HDR_RATE) in Q30
     90    * recBwAvg = INIT_BN_EST + INIT_HDR_RATE in Q5
     91    */
     92   bweStr->recBwInv              = 43531;
     93   bweStr->recBw                 = INIT_BN_EST;
     94   bweStr->recBwAvgQ             = INIT_BN_EST_Q7;
     95   bweStr->recBwAvg              = INIT_REC_BN_EST_Q5;
     96   bweStr->recJitter             = (WebRtc_Word32) 327680;   /* 10 in Q15 */
     97   bweStr->recJitterShortTerm    = 0;
     98   bweStr->recJitterShortTermAbs = (WebRtc_Word32) 40960;    /* 5 in Q13 */
     99   bweStr->recMaxDelay           = (WebRtc_Word32) 10;
    100   bweStr->recMaxDelayAvgQ       = (WebRtc_Word32) 5120;     /* 10 in Q9 */
    101   bweStr->recHeaderRate         = INIT_HDR_RATE;
    102   bweStr->countRecPkts          = 0;
    103   bweStr->sendBwAvg             = INIT_BN_EST_Q7;
    104   bweStr->sendMaxDelayAvg       = (WebRtc_Word32) 5120;     /* 10 in Q9 */
    105 
    106   bweStr->countHighSpeedRec     = 0;
    107   bweStr->highSpeedRec          = 0;
    108   bweStr->countHighSpeedSent    = 0;
    109   bweStr->highSpeedSend         = 0;
    110   bweStr->inWaitPeriod          = 0;
    111 
    112   /* Find the inverse of the max bw and min bw in Q30
    113    *  (1 / (MAX_ISAC_BW + INIT_HDR_RATE) in Q30
    114    *  (1 / (MIN_ISAC_BW + INIT_HDR_RATE) in Q30
    115    */
    116   bweStr->maxBwInv              = kInvBandwidth[3];
    117   bweStr->minBwInv              = kInvBandwidth[2];
    118 
    119   return 0;
    120 }
    121 
    122 /****************************************************************************
    123  * WebRtcIsacfix_UpdateUplinkBwImpl(...)
    124  *
    125  * This function updates bottle neck rate received from other side in payload
    126  * and calculates a new bottle neck to send to the other side.
    127  *
    128  * Input/Output:
    129  *      - bweStr           : struct containing bandwidth information.
    130  *      - rtpNumber        : value from RTP packet, from NetEq
    131  *      - frameSize        : length of signal frame in ms, from iSAC decoder
    132  *      - sendTime         : value in RTP header giving send time in samples
    133  *      - arrivalTime      : value given by timeGetTime() time of arrival in
    134  *                           samples of packet from NetEq
    135  *      - pksize           : size of packet in bytes, from NetEq
    136  *      - Index            : integer (range 0...23) indicating bottle neck &
    137  *                           jitter as estimated by other side
    138  *
    139  * Return value            : 0 if everything went fine,
    140  *                           -1 otherwise
    141  */
    142 WebRtc_Word32 WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
    143                                                const WebRtc_UWord16 rtpNumber,
    144                                                const WebRtc_Word16  frameSize,
    145                                                const WebRtc_UWord32 sendTime,
    146                                                const WebRtc_UWord32 arrivalTime,
    147                                                const WebRtc_Word16  pksize,
    148                                                const WebRtc_UWord16 Index)
    149 {
    150   WebRtc_UWord16  weight = 0;
    151   WebRtc_UWord32  currBwInv = 0;
    152   WebRtc_UWord16  recRtpRate;
    153   WebRtc_UWord32  arrTimeProj;
    154   WebRtc_Word32   arrTimeDiff;
    155   WebRtc_Word32   arrTimeNoise;
    156   WebRtc_Word32   arrTimeNoiseAbs;
    157   WebRtc_Word32   sendTimeDiff;
    158 
    159   WebRtc_Word32 delayCorrFactor = DELAY_CORRECTION_MED;
    160   WebRtc_Word32 lateDiff = 0;
    161   WebRtc_Word16 immediateSet = 0;
    162   WebRtc_Word32 frameSizeSampl;
    163 
    164   WebRtc_Word32  temp;
    165   WebRtc_Word32  msec;
    166   WebRtc_UWord32 exponent;
    167   WebRtc_UWord32 reductionFactor;
    168   WebRtc_UWord32 numBytesInv;
    169   WebRtc_Word32  sign;
    170 
    171   WebRtc_UWord32 byteSecondsPerBit;
    172   WebRtc_UWord32 tempLower;
    173   WebRtc_UWord32 tempUpper;
    174   WebRtc_Word32 recBwAvgInv;
    175   WebRtc_Word32 numPktsExpected;
    176 
    177   WebRtc_Word16 errCode;
    178 
    179   /* UPDATE ESTIMATES FROM OTHER SIDE */
    180 
    181   /* The function also checks if Index has a valid value */
    182   errCode = WebRtcIsacfix_UpdateUplinkBwRec(bweStr, Index);
    183   if (errCode <0) {
    184     return(errCode);
    185   }
    186 
    187 
    188   /* UPDATE ESTIMATES ON THIS SIDE */
    189 
    190   /* Bits per second per byte * 1/30 or 1/60 */
    191   if (frameSize == 60) {
    192     /* If frameSize changed since last call, from 30 to 60, recalculate some values */
    193     if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
    194       bweStr->countUpdates = 10;
    195       bweStr->recHeaderRate = kRecHeaderRate[1];
    196 
    197       bweStr->maxBwInv = kInvBandwidth[3];
    198       bweStr->minBwInv = kInvBandwidth[2];
    199       bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
    200     }
    201 
    202     /* kBitsByteSec is in Q15 */
    203     recRtpRate = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
    204                                                                      (WebRtc_Word32)pksize), 15) + bweStr->recHeaderRate;
    205 
    206   } else {
    207     /* If frameSize changed since last call, from 60 to 30, recalculate some values */
    208     if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
    209       bweStr->countUpdates = 10;
    210       bweStr->recHeaderRate = kRecHeaderRate[0];
    211 
    212       bweStr->maxBwInv = kInvBandwidth[1];
    213       bweStr->minBwInv = kInvBandwidth[0];
    214       bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
    215     }
    216 
    217     /* kBitsByteSec is in Q14 */
    218     recRtpRate = (WebRtc_UWord16)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
    219                                                                       (WebRtc_Word32)pksize), 14) + bweStr->recHeaderRate;
    220   }
    221 
    222 
    223   /* Check for timer wrap-around */
    224   if (arrivalTime < bweStr->prevArrivalTime) {
    225     bweStr->prevArrivalTime = arrivalTime;
    226     bweStr->lastUpdate      = arrivalTime;
    227     bweStr->lastReduction   = arrivalTime + FS3;
    228 
    229     bweStr->countRecPkts      = 0;
    230 
    231     /* store frame size */
    232     bweStr->prevFrameSizeMs = frameSize;
    233 
    234     /* store far-side transmission rate */
    235     bweStr->prevRtpRate = recRtpRate;
    236 
    237     /* store far-side RTP time stamp */
    238     bweStr->prevRtpNumber = rtpNumber;
    239 
    240     return 0;
    241   }
    242 
    243   bweStr->countRecPkts++;
    244 
    245   /* Calculate framesize in msec */
    246   frameSizeSampl = WEBRTC_SPL_MUL_16_16((WebRtc_Word16)SAMPLES_PER_MSEC, frameSize);
    247 
    248   /* Check that it's not one of the first 9 packets */
    249   if ( bweStr->countUpdates > 0 ) {
    250 
    251     /* Stay in Wait Period for 1.5 seconds (no updates in wait period) */
    252     if(bweStr->inWaitPeriod) {
    253       if ((arrivalTime - bweStr->startWaitPeriod)> FS_1_HALF) {
    254         bweStr->inWaitPeriod = 0;
    255       }
    256     }
    257 
    258     /* If not been updated for a long time, reduce the BN estimate */
    259 
    260     /* Check send time difference between this packet and previous received      */
    261     sendTimeDiff = sendTime - bweStr->prevSendTime;
    262     if (sendTimeDiff <= WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1)) {
    263 
    264       /* Only update if 3 seconds has past since last update */
    265       if ((arrivalTime - bweStr->lastUpdate) > FS3) {
    266 
    267         /* Calculate expected number of received packets since last update */
    268         numPktsExpected =  WEBRTC_SPL_UDIV(arrivalTime - bweStr->lastUpdate, frameSizeSampl);
    269 
    270         /* If received number of packets is more than 90% of expected (922 = 0.9 in Q10): */
    271         /* do the update, else not                                                        */
    272         if(WEBRTC_SPL_LSHIFT_W32(bweStr->countRecPkts, 10)  > WEBRTC_SPL_MUL_16_16(922, numPktsExpected)) {
    273           /* Q4 chosen to approx dividing by 16 */
    274           msec = (arrivalTime - bweStr->lastReduction);
    275 
    276           /* the number below represents 13 seconds, highly unlikely
    277              but to insure no overflow when reduction factor is multiplied by recBw inverse */
    278           if (msec > 208000) {
    279             msec = 208000;
    280           }
    281 
    282           /* Q20 2^(negative number: - 76/1048576) = .99995
    283              product is Q24 */
    284           exponent = WEBRTC_SPL_UMUL(0x0000004C, msec);
    285 
    286           /* do the approx with positive exponent so that value is actually rf^-1
    287              and multiply by bw inverse */
    288           reductionFactor = WEBRTC_SPL_RSHIFT_U32(0x01000000 | (exponent & 0x00FFFFFF),
    289                                                   WEBRTC_SPL_RSHIFT_U32(exponent, 24));
    290 
    291           /* reductionFactor in Q13 */
    292           reductionFactor = WEBRTC_SPL_RSHIFT_U32(reductionFactor, 11);
    293 
    294           if ( reductionFactor != 0 ) {
    295             bweStr->recBwInv = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recBwInv, (WebRtc_Word32)reductionFactor);
    296             bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwInv, 13);
    297 
    298           } else {
    299             /* recBwInv = 1 / (INIT_BN_EST + INIT_HDR_RATE) in Q26 (Q30??)*/
    300             bweStr->recBwInv = WEBRTC_SPL_DIV((1073741824 +
    301                                                WEBRTC_SPL_LSHIFT_W32(((WebRtc_Word32)INIT_BN_EST + INIT_HDR_RATE), 1)), INIT_BN_EST + INIT_HDR_RATE);
    302           }
    303 
    304           /* reset time-since-update counter */
    305           bweStr->lastReduction = arrivalTime;
    306         } else {
    307           /* Delay last reduction with 3 seconds */
    308           bweStr->lastReduction = arrivalTime + FS3;
    309           bweStr->lastUpdate    = arrivalTime;
    310           bweStr->countRecPkts  = 0;
    311         }
    312       }
    313     } else {
    314       bweStr->lastReduction = arrivalTime + FS3;
    315       bweStr->lastUpdate    = arrivalTime;
    316       bweStr->countRecPkts  = 0;
    317     }
    318 
    319 
    320     /*   update only if previous packet was not lost */
    321     if ( rtpNumber == bweStr->prevRtpNumber + 1 ) {
    322       arrTimeDiff = arrivalTime - bweStr->prevArrivalTime;
    323 
    324       if (!(bweStr->highSpeedSend && bweStr->highSpeedRec)) {
    325         if (arrTimeDiff > frameSizeSampl) {
    326           if (sendTimeDiff > 0) {
    327             lateDiff = arrTimeDiff - sendTimeDiff -
    328                 WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1);
    329           } else {
    330             lateDiff = arrTimeDiff - frameSizeSampl;
    331           }
    332 
    333           /* 8000 is 1/2 second (in samples at FS) */
    334           if (lateDiff > 8000) {
    335             delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MAX;
    336             bweStr->inWaitPeriod = 1;
    337             bweStr->startWaitPeriod = arrivalTime;
    338             immediateSet = 1;
    339           } else if (lateDiff > 5120) {
    340             delayCorrFactor = (WebRtc_Word32) DELAY_CORRECTION_MED;
    341             immediateSet = 1;
    342             bweStr->inWaitPeriod = 1;
    343             bweStr->startWaitPeriod = arrivalTime;
    344           }
    345         }
    346       }
    347 
    348       if ((bweStr->prevRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->recBwAvg, 5)) &&
    349           (recRtpRate > WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)bweStr->recBwAvg, 5)) &&
    350           !bweStr->inWaitPeriod) {
    351 
    352         /* test if still in initiation period and increment counter */
    353         if (bweStr->countUpdates++ > 99) {
    354           /* constant weight after initiation part, 0.01 in Q13 */
    355           weight = (WebRtc_UWord16) 82;
    356         } else {
    357           /* weight decreases with number of updates, 1/countUpdates in Q13  */
    358           weight = (WebRtc_UWord16) WebRtcSpl_DivW32W16(
    359               (WebRtc_Word32)(8192 + WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32) bweStr->countUpdates, 1)),
    360               (WebRtc_Word16)bweStr->countUpdates);
    361         }
    362 
    363         /* Bottle Neck Estimation */
    364 
    365         /* limit outliers, if more than 25 ms too much */
    366         if (arrTimeDiff > frameSizeSampl + kSamplesIn25msec) {
    367           arrTimeDiff = frameSizeSampl + kSamplesIn25msec;
    368         }
    369 
    370         /* don't allow it to be less than frame rate - 10 ms */
    371         if (arrTimeDiff < frameSizeSampl - FRAMESAMPLES_10ms) {
    372           arrTimeDiff = frameSizeSampl - FRAMESAMPLES_10ms;
    373         }
    374 
    375         /* compute inverse receiving rate for last packet, in Q19 */
    376         numBytesInv = (WebRtc_UWord16) WebRtcSpl_DivW32W16(
    377             (WebRtc_Word32)(524288 + WEBRTC_SPL_RSHIFT_W32(((WebRtc_Word32)pksize + HEADER_SIZE), 1)),
    378             (WebRtc_Word16)(pksize + HEADER_SIZE));
    379 
    380         /* 8389 is  ~ 1/128000 in Q30 */
    381         byteSecondsPerBit = WEBRTC_SPL_MUL_16_16(arrTimeDiff, 8389);
    382 
    383         /* get upper N bits */
    384         tempUpper = WEBRTC_SPL_RSHIFT_U32(byteSecondsPerBit, 15);
    385 
    386         /* get lower 15 bits */
    387         tempLower = byteSecondsPerBit & 0x00007FFF;
    388 
    389         tempUpper = WEBRTC_SPL_MUL(tempUpper, numBytesInv);
    390         tempLower = WEBRTC_SPL_MUL(tempLower, numBytesInv);
    391         tempLower = WEBRTC_SPL_RSHIFT_U32(tempLower, 15);
    392 
    393         currBwInv = tempUpper + tempLower;
    394         currBwInv = WEBRTC_SPL_RSHIFT_U32(currBwInv, 4);
    395 
    396         /* Limit inv rate. Note that minBwInv > maxBwInv! */
    397         if(currBwInv < bweStr->maxBwInv) {
    398           currBwInv = bweStr->maxBwInv;
    399         } else if(currBwInv > bweStr->minBwInv) {
    400           currBwInv = bweStr->minBwInv;
    401         }
    402 
    403         /* update bottle neck rate estimate */
    404         bweStr->recBwInv = WEBRTC_SPL_UMUL(weight, currBwInv) +
    405             WEBRTC_SPL_UMUL((WebRtc_UWord32) 8192 - weight, bweStr->recBwInv);
    406 
    407         /* Shift back to Q30 from Q40 (actual used bits shouldn't be more than 27 based on minBwInv)
    408            up to 30 bits used with Q13 weight */
    409         bweStr->recBwInv = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwInv, 13);
    410 
    411         /* reset time-since-update counter */
    412         bweStr->lastUpdate    = arrivalTime;
    413         bweStr->lastReduction = arrivalTime + FS3;
    414         bweStr->countRecPkts  = 0;
    415 
    416         /* to save resolution compute the inverse of recBwAvg in Q26 by left shifting numerator to 2^31
    417            and NOT right shifting recBwAvg 5 bits to an integer
    418            At max 13 bits are used
    419            shift to Q5 */
    420         recBwAvgInv = WEBRTC_SPL_UDIV((WebRtc_UWord32)(0x80000000 + WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 1)),
    421                                       bweStr->recBwAvg);
    422 
    423         /* Calculate Projected arrival time difference */
    424 
    425         /* The numerator of the quotient can be 22 bits so right shift inv by 4 to avoid overflow
    426            result in Q22 */
    427         arrTimeProj = WEBRTC_SPL_MUL((WebRtc_Word32)8000, recBwAvgInv);
    428         /* shift to Q22 */
    429         arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 4);
    430         /* complete calulation */
    431         arrTimeProj = WEBRTC_SPL_MUL(((WebRtc_Word32)pksize + HEADER_SIZE), arrTimeProj);
    432         /* shift to Q10 */
    433         arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 12);
    434 
    435         /* difference between projected and actual arrival time differences */
    436         /* Q9 (only shift arrTimeDiff by 5 to simulate divide by 16 (need to revisit if change sampling rate) DH */
    437         if (WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) > (WebRtc_Word32)arrTimeProj) {
    438           arrTimeNoise = WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) -  arrTimeProj;
    439           sign = 1;
    440         } else {
    441           arrTimeNoise = arrTimeProj - WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6);
    442           sign = -1;
    443         }
    444 
    445         /* Q9 */
    446         arrTimeNoiseAbs = arrTimeNoise;
    447 
    448         /* long term averaged absolute jitter, Q15 */
    449         weight = WEBRTC_SPL_RSHIFT_W32(weight, 3);
    450         bweStr->recJitter = WEBRTC_SPL_MUL(weight, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 5))
    451             +  WEBRTC_SPL_MUL(1024 - weight, bweStr->recJitter);
    452 
    453         /* remove the fractional portion */
    454         bweStr->recJitter = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitter, 10);
    455 
    456         /* Maximum jitter is 10 msec in Q15 */
    457         if (bweStr->recJitter > (WebRtc_Word32)327680) {
    458           bweStr->recJitter = (WebRtc_Word32)327680;
    459         }
    460 
    461         /* short term averaged absolute jitter */
    462         /* Calculation in Q13 products in Q23 */
    463         bweStr->recJitterShortTermAbs = WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 3)) +
    464             WEBRTC_SPL_MUL(973, bweStr->recJitterShortTermAbs);
    465         bweStr->recJitterShortTermAbs = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTermAbs , 10);
    466 
    467         /* short term averaged jitter */
    468         /* Calculation in Q13 products in Q23 */
    469         bweStr->recJitterShortTerm = WEBRTC_SPL_MUL(205, WEBRTC_SPL_LSHIFT_W32(arrTimeNoise, 3)) * sign +
    470             WEBRTC_SPL_MUL(3891, bweStr->recJitterShortTerm);
    471 
    472         if (bweStr->recJitterShortTerm < 0) {
    473           temp = -bweStr->recJitterShortTerm;
    474           temp = WEBRTC_SPL_RSHIFT_W32(temp, 12);
    475           bweStr->recJitterShortTerm = -temp;
    476         } else {
    477           bweStr->recJitterShortTerm = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 12);
    478         }
    479       }
    480     }
    481   } else {
    482     /* reset time-since-update counter when receiving the first 9 packets */
    483     bweStr->lastUpdate    = arrivalTime;
    484     bweStr->lastReduction = arrivalTime + FS3;
    485     bweStr->countRecPkts  = 0;
    486     bweStr->countUpdates++;
    487   }
    488 
    489   /* Limit to minimum or maximum bottle neck rate (in Q30) */
    490   if (bweStr->recBwInv > bweStr->minBwInv) {
    491     bweStr->recBwInv = bweStr->minBwInv;
    492   } else if (bweStr->recBwInv < bweStr->maxBwInv) {
    493     bweStr->recBwInv = bweStr->maxBwInv;
    494   }
    495 
    496 
    497   /* store frame length */
    498   bweStr->prevFrameSizeMs = frameSize;
    499 
    500   /* store far-side transmission rate */
    501   bweStr->prevRtpRate = recRtpRate;
    502 
    503   /* store far-side RTP time stamp */
    504   bweStr->prevRtpNumber = rtpNumber;
    505 
    506   /* Replace bweStr->recMaxDelay by the new value (atomic operation) */
    507   if (bweStr->prevArrivalTime != 0xffffffff) {
    508     bweStr->recMaxDelay = WEBRTC_SPL_MUL(3, bweStr->recJitter);
    509   }
    510 
    511   /* store arrival time stamp */
    512   bweStr->prevArrivalTime = arrivalTime;
    513   bweStr->prevSendTime = sendTime;
    514 
    515   /* Replace bweStr->recBw by the new value */
    516   bweStr->recBw = WEBRTC_SPL_UDIV(1073741824, bweStr->recBwInv) - bweStr->recHeaderRate;
    517 
    518   if (immediateSet) {
    519     /* delay correction factor is in Q10 */
    520     bweStr->recBw = WEBRTC_SPL_UMUL(delayCorrFactor, bweStr->recBw);
    521     bweStr->recBw = WEBRTC_SPL_RSHIFT_U32(bweStr->recBw, 10);
    522 
    523     if (bweStr->recBw < (WebRtc_Word32) MIN_ISAC_BW) {
    524       bweStr->recBw = (WebRtc_Word32) MIN_ISAC_BW;
    525     }
    526 
    527     bweStr->recBwAvg = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw + bweStr->recHeaderRate, 5);
    528 
    529     bweStr->recBwAvgQ = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw, 7);
    530 
    531     bweStr->recJitterShortTerm = 0;
    532 
    533     bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, bweStr->recBw + bweStr->recHeaderRate);
    534 
    535     immediateSet = 0;
    536   }
    537 
    538 
    539   return 0;
    540 }
    541 
    542 /* This function updates the send bottle neck rate                                                   */
    543 /* Index         - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
    544 /* returns 0 if everything went fine, -1 otherwise                                                   */
    545 WebRtc_Word16 WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr,
    546                                               const WebRtc_Word16 Index)
    547 {
    548   WebRtc_UWord16 RateInd;
    549 
    550   if ( (Index < 0) || (Index > 23) ) {
    551     return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
    552   }
    553 
    554   /* UPDATE ESTIMATES FROM OTHER SIDE */
    555 
    556   if ( Index > 11 ) {
    557     RateInd = Index - 12;
    558     /* compute the jitter estimate as decoded on the other side in Q9 */
    559     /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */
    560     bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
    561         WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MAX_ISAC_MD, 9));
    562     bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
    563 
    564   } else {
    565     RateInd = Index;
    566     /* compute the jitter estimate as decoded on the other side in Q9 */
    567     /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MIN_ISAC_MD */
    568     bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
    569         WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)MIN_ISAC_MD,9));
    570     bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
    571 
    572   }
    573 
    574 
    575   /* compute the BN estimate as decoded on the other side */
    576   /* sendBwAvg = 0.9 * sendBwAvg + 0.1 * kQRateTable[RateInd]; */
    577   bweStr->sendBwAvg = WEBRTC_SPL_UMUL(461, bweStr->sendBwAvg) +
    578       WEBRTC_SPL_UMUL(51, WEBRTC_SPL_LSHIFT_U32(kQRateTable[RateInd], 7));
    579   bweStr->sendBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 9);
    580 
    581 
    582   if (WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7) > 28000 && !bweStr->highSpeedSend) {
    583     bweStr->countHighSpeedSent++;
    584 
    585     /* approx 2 seconds with 30ms frames */
    586     if (bweStr->countHighSpeedSent >= 66) {
    587       bweStr->highSpeedSend = 1;
    588     }
    589   } else if (!bweStr->highSpeedSend) {
    590     bweStr->countHighSpeedSent = 0;
    591   }
    592 
    593   return 0;
    594 }
    595 
    596 /****************************************************************************
    597  * WebRtcIsacfix_GetDownlinkBwIndexImpl(...)
    598  *
    599  * This function calculates and returns the bandwidth/jitter estimation code
    600  * (integer 0...23) to put in the sending iSAC payload.
    601  *
    602  * Input:
    603  *      - bweStr       : BWE struct
    604  *
    605  * Return:
    606  *      bandwith and jitter index (0..23)
    607  */
    608 WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr)
    609 {
    610   WebRtc_Word32  rate;
    611   WebRtc_Word32  maxDelay;
    612   WebRtc_UWord16 rateInd;
    613   WebRtc_UWord16 maxDelayBit;
    614   WebRtc_Word32  tempTerm1;
    615   WebRtc_Word32  tempTerm2;
    616   WebRtc_Word32  tempTermX;
    617   WebRtc_Word32  tempTermY;
    618   WebRtc_Word32  tempMin;
    619   WebRtc_Word32  tempMax;
    620 
    621   /* Get Rate Index */
    622 
    623   /* Get unquantized rate. Always returns 10000 <= rate <= 32000 */
    624   rate = WebRtcIsacfix_GetDownlinkBandwidth(bweStr);
    625 
    626   /* Compute the averaged BN estimate on this side */
    627 
    628   /* recBwAvg = 0.9 * recBwAvg + 0.1 * (rate + bweStr->recHeaderRate), 0.9 and 0.1 in Q9 */
    629   bweStr->recBwAvg = WEBRTC_SPL_UMUL(922, bweStr->recBwAvg) +
    630       WEBRTC_SPL_UMUL(102, WEBRTC_SPL_LSHIFT_U32((WebRtc_UWord32)rate + bweStr->recHeaderRate, 5));
    631   bweStr->recBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 10);
    632 
    633   /* find quantization index that gives the closest rate after averaging */
    634   for (rateInd = 1; rateInd < 12; rateInd++) {
    635     if (rate <= kQRateTable[rateInd]){
    636       break;
    637     }
    638   }
    639 
    640   /* find closest quantization index, and update quantized average by taking: */
    641   /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
    642 
    643   /* 0.9 times recBwAvgQ in Q16 */
    644   /* 461/512 - 25/65536 =0.900009 */
    645   tempTerm1 = WEBRTC_SPL_MUL(bweStr->recBwAvgQ, 25);
    646   tempTerm1 = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 7);
    647   tempTermX = WEBRTC_SPL_UMUL(461, bweStr->recBwAvgQ) - tempTerm1;
    648 
    649   /* rate in Q16 */
    650   tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)rate, 16);
    651 
    652   /* 0.1 * kQRateTable[rateInd] = KQRate01[rateInd] */
    653   tempTerm1 = tempTermX + KQRate01[rateInd] - tempTermY;
    654   tempTerm2 = tempTermY - tempTermX - KQRate01[rateInd-1];
    655 
    656   /* Compare (0.9 * recBwAvgQ + 0.1 * kQRateTable[rateInd] - rate) >
    657      (rate - 0.9 * recBwAvgQ - 0.1 * kQRateTable[rateInd-1]) */
    658   if (tempTerm1  > tempTerm2) {
    659     rateInd--;
    660   }
    661 
    662   /* Update quantized average by taking:                  */
    663   /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
    664 
    665   /* Add 0.1 times kQRateTable[rateInd], in Q16 */
    666   tempTermX += KQRate01[rateInd];
    667 
    668   /* Shift back to Q7 */
    669   bweStr->recBwAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTermX, 9);
    670 
    671   /* Count consecutive received bandwidth above 28000 kbps (28000 in Q7 = 3584000) */
    672   /* If 66 high estimates in a row, set highSpeedRec to one */
    673   /* 66 corresponds to ~2 seconds in 30 msec mode */
    674   if ((bweStr->recBwAvgQ > 3584000) && !bweStr->highSpeedRec) {
    675     bweStr->countHighSpeedRec++;
    676     if (bweStr->countHighSpeedRec >= 66) {
    677       bweStr->highSpeedRec = 1;
    678     }
    679   } else if (!bweStr->highSpeedRec)    {
    680     bweStr->countHighSpeedRec = 0;
    681   }
    682 
    683   /* Get Max Delay Bit */
    684 
    685   /* get unquantized max delay */
    686   maxDelay = WebRtcIsacfix_GetDownlinkMaxDelay(bweStr);
    687 
    688   /* Update quantized max delay average */
    689   tempMax = 652800; /* MAX_ISAC_MD * 0.1 in Q18 */
    690   tempMin = 130560; /* MIN_ISAC_MD * 0.1 in Q18 */
    691   tempTermX = WEBRTC_SPL_MUL((WebRtc_Word32)bweStr->recMaxDelayAvgQ, (WebRtc_Word32)461);
    692   tempTermY = WEBRTC_SPL_LSHIFT_W32((WebRtc_Word32)maxDelay, 18);
    693 
    694   tempTerm1 = tempTermX + tempMax - tempTermY;
    695   tempTerm2 = tempTermY - tempTermX - tempMin;
    696 
    697   if ( tempTerm1 > tempTerm2) {
    698     maxDelayBit = 0;
    699     tempTerm1 = tempTermX + tempMin;
    700 
    701     /* update quantized average, shift back to Q9 */
    702     bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
    703   } else {
    704     maxDelayBit = 12;
    705     tempTerm1 =  tempTermX + tempMax;
    706 
    707     /* update quantized average, shift back to Q9 */
    708     bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
    709   }
    710 
    711   /* Return bandwitdh and jitter index (0..23) */
    712   return (WebRtc_UWord16)(rateInd + maxDelayBit);
    713 }
    714 
    715 /* get the bottle neck rate from far side to here, as estimated on this side */
    716 WebRtc_UWord16 WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr)
    717 {
    718   WebRtc_UWord32  recBw;
    719   WebRtc_Word32   jitter_sign; /* Q8 */
    720   WebRtc_Word32   bw_adjust;   /* Q16 */
    721   WebRtc_Word32   rec_jitter_short_term_abs_inv; /* Q18 */
    722   WebRtc_Word32   temp;
    723 
    724   /* Q18  rec jitter short term abs is in Q13, multiply it by 2^13 to save precision
    725      2^18 then needs to be shifted 13 bits to 2^31 */
    726   rec_jitter_short_term_abs_inv = WEBRTC_SPL_UDIV(0x80000000, bweStr->recJitterShortTermAbs);
    727 
    728   /* Q27 = 9 + 18 */
    729   jitter_sign = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 4), (WebRtc_Word32)rec_jitter_short_term_abs_inv);
    730 
    731   if (jitter_sign < 0) {
    732     temp = -jitter_sign;
    733     temp = WEBRTC_SPL_RSHIFT_W32(temp, 19);
    734     jitter_sign = -temp;
    735   } else {
    736     jitter_sign = WEBRTC_SPL_RSHIFT_W32(jitter_sign, 19);
    737   }
    738 
    739   /* adjust bw proportionally to negative average jitter sign */
    740   //bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
    741   //Q8 -> Q16 .15 +.15 * jitter^2 first term is .15 in Q16 latter term is Q8*Q8*Q8
    742   //38 in Q8 ~.15 9830 in Q16 ~.15
    743   temp = 9830  + WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL(38, WEBRTC_SPL_MUL(jitter_sign, jitter_sign))), 8);
    744 
    745   if (jitter_sign < 0) {
    746     temp = WEBRTC_SPL_MUL(jitter_sign, temp);
    747     temp = -temp;
    748     temp = WEBRTC_SPL_RSHIFT_W32(temp, 8);
    749     bw_adjust = (WebRtc_UWord32)65536 + temp; /* (1 << 16) + temp; */
    750   } else {
    751     bw_adjust = (WebRtc_UWord32)65536 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(jitter_sign, temp), 8);/* (1 << 16) - ((jitter_sign * temp) >> 8); */
    752   }
    753 
    754   //make sure following multiplication won't overflow
    755   //bw adjust now Q14
    756   bw_adjust = WEBRTC_SPL_RSHIFT_W32(bw_adjust, 2);//see if good resolution is maintained
    757 
    758   /* adjust Rate if jitter sign is mostly constant */
    759   recBw = WEBRTC_SPL_UMUL(bweStr->recBw, bw_adjust);
    760 
    761   recBw = WEBRTC_SPL_RSHIFT_W32(recBw, 14);
    762 
    763   /* limit range of bottle neck rate */
    764   if (recBw < MIN_ISAC_BW) {
    765     recBw = MIN_ISAC_BW;
    766   } else if (recBw > MAX_ISAC_BW) {
    767     recBw = MAX_ISAC_BW;
    768   }
    769 
    770   return  (WebRtc_UWord16) recBw;
    771 }
    772 
    773 /* Returns the mmax delay (in ms) */
    774 WebRtc_Word16 WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr)
    775 {
    776   WebRtc_Word16 recMaxDelay;
    777 
    778   recMaxDelay = (WebRtc_Word16)  WEBRTC_SPL_RSHIFT_W32(bweStr->recMaxDelay, 15);
    779 
    780   /* limit range of jitter estimate */
    781   if (recMaxDelay < MIN_ISAC_MD) {
    782     recMaxDelay = MIN_ISAC_MD;
    783   } else if (recMaxDelay > MAX_ISAC_MD) {
    784     recMaxDelay = MAX_ISAC_MD;
    785   }
    786 
    787   return recMaxDelay;
    788 }
    789 
    790 /* get the bottle neck rate from here to far side, as estimated by far side */
    791 WebRtc_Word16 WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bweStr)
    792 {
    793   WebRtc_Word16 send_bw;
    794 
    795   send_bw = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7);
    796 
    797   /* limit range of bottle neck rate */
    798   if (send_bw < MIN_ISAC_BW) {
    799     send_bw = MIN_ISAC_BW;
    800   } else if (send_bw > MAX_ISAC_BW) {
    801     send_bw = MAX_ISAC_BW;
    802   }
    803 
    804   return send_bw;
    805 }
    806 
    807 
    808 
    809 /* Returns the max delay value from the other side in ms */
    810 WebRtc_Word16 WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bweStr)
    811 {
    812   WebRtc_Word16 send_max_delay;
    813 
    814   send_max_delay = (WebRtc_Word16) WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
    815 
    816   /* limit range of jitter estimate */
    817   if (send_max_delay < MIN_ISAC_MD) {
    818     send_max_delay = MIN_ISAC_MD;
    819   } else if (send_max_delay > MAX_ISAC_MD) {
    820     send_max_delay = MAX_ISAC_MD;
    821   }
    822 
    823   return send_max_delay;
    824 }
    825 
    826 
    827 
    828 
    829 /*
    830  * update long-term average bitrate and amount of data in buffer
    831  * returns minimum payload size (bytes)
    832  */
    833 WebRtc_UWord16 WebRtcIsacfix_GetMinBytes(RateModel *State,
    834                                          WebRtc_Word16 StreamSize,                    /* bytes in bitstream */
    835                                          const WebRtc_Word16 FrameSamples,            /* samples per frame */
    836                                          const WebRtc_Word16 BottleNeck,        /* bottle neck rate; excl headers (bps) */
    837                                          const WebRtc_Word16 DelayBuildUp)      /* max delay from bottle neck buffering (ms) */
    838 {
    839   WebRtc_Word32 MinRate = 0;
    840   WebRtc_UWord16    MinBytes;
    841   WebRtc_Word16 TransmissionTime;
    842   WebRtc_Word32 inv_Q12;
    843   WebRtc_Word32 den;
    844 
    845 
    846   /* first 10 packets @ low rate, then INIT_BURST_LEN packets @ fixed rate of INIT_RATE bps */
    847   if (State->InitCounter > 0) {
    848     if (State->InitCounter-- <= INIT_BURST_LEN) {
    849       MinRate = INIT_RATE;
    850     } else {
    851       MinRate = 0;
    852     }
    853   } else {
    854     /* handle burst */
    855     if (State->BurstCounter) {
    856       if (State->StillBuffered < WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL((512 - WEBRTC_SPL_DIV(512, BURST_LEN)), DelayBuildUp), 9)) {
    857         /* max bps derived from BottleNeck and DelayBuildUp values */
    858         inv_Q12 = WEBRTC_SPL_DIV(4096, WEBRTC_SPL_MUL(BURST_LEN, FrameSamples));
    859         MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck);
    860       } else {
    861         /* max bps derived from StillBuffered and DelayBuildUp values */
    862         inv_Q12 = WEBRTC_SPL_DIV(4096, FrameSamples);
    863         if (DelayBuildUp > State->StillBuffered) {
    864           MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck);
    865         } else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) {
    866           /* MinRate will be negative here */
    867           MinRate = 0;
    868         } else {
    869           MinRate = WEBRTC_SPL_MUL((512 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(den, inv_Q12), 3)), BottleNeck);
    870         }
    871         //if (MinRate < 1.04 * BottleNeck)
    872         //    MinRate = 1.04 * BottleNeck;
    873         //Q9
    874         if (MinRate < WEBRTC_SPL_MUL(532, BottleNeck)) {
    875           MinRate += WEBRTC_SPL_MUL(22, BottleNeck);
    876         }
    877       }
    878 
    879       State->BurstCounter--;
    880     }
    881   }
    882 
    883 
    884   /* convert rate from bits/second to bytes/packet */
    885   //round and shift before conversion
    886   MinRate += 256;
    887   MinRate = WEBRTC_SPL_RSHIFT_W32(MinRate, 9);
    888   MinBytes = (WebRtc_UWord16)WEBRTC_SPL_UDIV(WEBRTC_SPL_MUL(MinRate, FrameSamples), FS8);
    889 
    890   /* StreamSize will be adjusted if less than MinBytes */
    891   if (StreamSize < MinBytes) {
    892     StreamSize = MinBytes;
    893   }
    894 
    895   /* keep track of when bottle neck was last exceeded by at least 1% */
    896   //517/512 ~ 1.01
    897   if (WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, FS8), FrameSamples) > (WEBRTC_SPL_MUL(517, BottleNeck) >> 9)) {
    898     if (State->PrevExceed) {
    899       /* bottle_neck exceded twice in a row, decrease ExceedAgo */
    900       State->ExceedAgo -= WEBRTC_SPL_DIV(BURST_INTERVAL, BURST_LEN - 1);
    901       if (State->ExceedAgo < 0) {
    902         State->ExceedAgo = 0;
    903       }
    904     } else {
    905       State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);       /* ms */
    906       State->PrevExceed = 1;
    907     }
    908   } else {
    909     State->PrevExceed = 0;
    910     State->ExceedAgo += (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);           /* ms */
    911   }
    912 
    913   /* set burst flag if bottle neck not exceeded for long time */
    914   if ((State->ExceedAgo > BURST_INTERVAL) && (State->BurstCounter == 0)) {
    915     if (State->PrevExceed) {
    916       State->BurstCounter = BURST_LEN - 1;
    917     } else {
    918       State->BurstCounter = BURST_LEN;
    919     }
    920   }
    921 
    922 
    923   /* Update buffer delay */
    924   TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, 8000), BottleNeck);    /* ms */
    925   State->StillBuffered += TransmissionTime;
    926   State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);  //>>4 =  SAMPLES_PER_MSEC        /* ms */
    927   if (State->StillBuffered < 0) {
    928     State->StillBuffered = 0;
    929   }
    930 
    931   if (State->StillBuffered > 2000) {
    932     State->StillBuffered = 2000;
    933   }
    934 
    935   return MinBytes;
    936 }
    937 
    938 
    939 /*
    940  * update long-term average bitrate and amount of data in buffer
    941  */
    942 void WebRtcIsacfix_UpdateRateModel(RateModel *State,
    943                                    WebRtc_Word16 StreamSize,                    /* bytes in bitstream */
    944                                    const WebRtc_Word16 FrameSamples,            /* samples per frame */
    945                                    const WebRtc_Word16 BottleNeck)        /* bottle neck rate; excl headers (bps) */
    946 {
    947   WebRtc_Word16 TransmissionTime;
    948 
    949   /* avoid the initial "high-rate" burst */
    950   State->InitCounter = 0;
    951 
    952   /* Update buffer delay */
    953   TransmissionTime = (WebRtc_Word16)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(WEBRTC_SPL_MUL(StreamSize, 8), 1000), BottleNeck);    /* ms */
    954   State->StillBuffered += TransmissionTime;
    955   State->StillBuffered -= (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4);            /* ms */
    956   if (State->StillBuffered < 0) {
    957     State->StillBuffered = 0;
    958   }
    959 
    960 }
    961 
    962 
    963 void WebRtcIsacfix_InitRateModel(RateModel *State)
    964 {
    965   State->PrevExceed      = 0;                        /* boolean */
    966   State->ExceedAgo       = 0;                        /* ms */
    967   State->BurstCounter    = 0;                        /* packets */
    968   State->InitCounter     = INIT_BURST_LEN + 10;    /* packets */
    969   State->StillBuffered   = 1;                    /* ms */
    970 }
    971 
    972 
    973 
    974 
    975 
    976 WebRtc_Word16 WebRtcIsacfix_GetNewFrameLength(WebRtc_Word16 bottle_neck, WebRtc_Word16 current_framesamples)
    977 {
    978   WebRtc_Word16 new_framesamples;
    979 
    980   new_framesamples = current_framesamples;
    981 
    982   /* find new framelength */
    983   switch(current_framesamples) {
    984     case 480:
    985       if (bottle_neck < Thld_30_60) {
    986         new_framesamples = 960;
    987       }
    988       break;
    989     case 960:
    990       if (bottle_neck >= Thld_60_30) {
    991         new_framesamples = 480;
    992       }
    993       break;
    994     default:
    995       new_framesamples = -1; /* Error */
    996   }
    997 
    998   return new_framesamples;
    999 }
   1000 
   1001 WebRtc_Word16 WebRtcIsacfix_GetSnr(WebRtc_Word16 bottle_neck, WebRtc_Word16 framesamples)
   1002 {
   1003   WebRtc_Word16 s2nr = 0;
   1004 
   1005   /* find new SNR value */
   1006   //consider BottleNeck to be in Q10 ( * 1 in Q10)
   1007   switch(framesamples) {
   1008     case 480:
   1009       /*s2nr = -1*(a_30 << 10) + ((b_30 * bottle_neck) >> 10);*/
   1010       s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
   1011       break;
   1012     case 960:
   1013       /*s2nr = -1*(a_60 << 10) + ((b_60 * bottle_neck) >> 10);*/
   1014       s2nr = -22500 + (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
   1015       break;
   1016     default:
   1017       s2nr = -1; /* Error */
   1018   }
   1019 
   1020   return s2nr; //return in Q10
   1021 
   1022 }
   1023