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