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