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