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