2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
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.
12 * bandwidth_estimator.c
14 * This file contains the code for the Bandwidth Estimator designed
17 * NOTE! Castings needed for C55, do not remove!
21 #include "bandwidth_estimator.h"
25 /* array of quantization levels for bottle neck info; Matlab code: */
26 /* sprintf('%4.1ff, ', logspace(log10(5000), log10(40000), 12)) */
27 static const int16_t kQRateTable[12] = {
28 10000, 11115, 12355, 13733, 15265, 16967,
29 18860, 20963, 23301, 25900, 28789, 32000
32 /* 0.1 times the values in the table kQRateTable */
33 /* values are in Q16 */
34 static const int32_t KQRate01[12] = {
35 65536000, 72843264, 80969728, 90000589, 100040704, 111194931,
36 123600896, 137383117, 152705434, 169738240, 188671590, 209715200
39 /* Bits per Bytes Seconds
40 * 8 bits/byte * 1000 msec/sec * 1/framelength (in msec)->bits/byte*sec
41 * frame length will either be 30 or 60 msec. 8738 is 1/60 in Q19 and 1/30 in Q18
42 * The following number is either in Q15 or Q14 depending on the current frame length */
43 static const int32_t kBitsByteSec = 4369000;
45 /* Received header rate. First value is for 30 ms packets and second for 60 ms */
46 static const int16_t kRecHeaderRate[2] = {
50 /* Inverted minimum and maximum bandwidth in Q30.
51 minBwInv 30 ms, maxBwInv 30 ms,
52 minBwInv 60 ms, maxBwInv 69 ms
54 static const int32_t kInvBandwidth[4] = {
59 /* Number of samples in 25 msec */
60 static const int32_t kSamplesIn25msec = 400;
63 /****************************************************************************
64 * WebRtcIsacfix_InitBandwidthEstimator(...)
66 * This function initializes the struct for the bandwidth estimator
69 * - bweStr : Struct containing bandwidth information.
73 int32_t WebRtcIsacfix_InitBandwidthEstimator(BwEstimatorstr *bweStr)
75 bweStr->prevFrameSizeMs = INIT_FRAME_LEN;
76 bweStr->prevRtpNumber = 0;
77 bweStr->prevSendTime = 0;
78 bweStr->prevArrivalTime = 0;
79 bweStr->prevRtpRate = 1;
80 bweStr->lastUpdate = 0;
81 bweStr->lastReduction = 0;
82 bweStr->countUpdates = -9;
84 /* INIT_BN_EST = 20000
85 * INIT_BN_EST_Q7 = 2560000
86 * INIT_HDR_RATE = 4666
87 * INIT_REC_BN_EST_Q5 = 789312
89 * recBwInv = 1/(INIT_BN_EST + INIT_HDR_RATE) in Q30
90 * recBwAvg = INIT_BN_EST + INIT_HDR_RATE in Q5
92 bweStr->recBwInv = 43531;
93 bweStr->recBw = INIT_BN_EST;
94 bweStr->recBwAvgQ = INIT_BN_EST_Q7;
95 bweStr->recBwAvg = INIT_REC_BN_EST_Q5;
96 bweStr->recJitter = (int32_t) 327680; /* 10 in Q15 */
97 bweStr->recJitterShortTerm = 0;
98 bweStr->recJitterShortTermAbs = (int32_t) 40960; /* 5 in Q13 */
99 bweStr->recMaxDelay = (int32_t) 10;
100 bweStr->recMaxDelayAvgQ = (int32_t) 5120; /* 10 in Q9 */
101 bweStr->recHeaderRate = INIT_HDR_RATE;
102 bweStr->countRecPkts = 0;
103 bweStr->sendBwAvg = INIT_BN_EST_Q7;
104 bweStr->sendMaxDelayAvg = (int32_t) 5120; /* 10 in Q9 */
106 bweStr->countHighSpeedRec = 0;
107 bweStr->highSpeedRec = 0;
108 bweStr->countHighSpeedSent = 0;
109 bweStr->highSpeedSend = 0;
110 bweStr->inWaitPeriod = 0;
112 /* Find the inverse of the max bw and min bw in Q30
113 * (1 / (MAX_ISAC_BW + INIT_HDR_RATE) in Q30
114 * (1 / (MIN_ISAC_BW + INIT_HDR_RATE) in Q30
116 bweStr->maxBwInv = kInvBandwidth[3];
117 bweStr->minBwInv = kInvBandwidth[2];
122 /****************************************************************************
123 * WebRtcIsacfix_UpdateUplinkBwImpl(...)
125 * This function updates bottle neck rate received from other side in payload
126 * and calculates a new bottle neck to send to the other side.
129 * - bweStr : struct containing bandwidth information.
130 * - rtpNumber : value from RTP packet, from NetEq
131 * - frameSize : length of signal frame in ms, from iSAC decoder
132 * - sendTime : value in RTP header giving send time in samples
133 * - arrivalTime : value given by timeGetTime() time of arrival in
134 * samples of packet from NetEq
135 * - pksize : size of packet in bytes, from NetEq
136 * - Index : integer (range 0...23) indicating bottle neck &
137 * jitter as estimated by other side
139 * Return value : 0 if everything went fine,
142 int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
143 const uint16_t rtpNumber,
144 const int16_t frameSize,
145 const uint32_t sendTime,
146 const uint32_t arrivalTime,
147 const int16_t pksize,
148 const uint16_t Index)
151 uint32_t currBwInv = 0;
153 uint32_t arrTimeProj;
155 int32_t arrTimeNoise;
156 int32_t arrTimeNoiseAbs;
157 int32_t sendTimeDiff;
159 int32_t delayCorrFactor = DELAY_CORRECTION_MED;
160 int32_t lateDiff = 0;
161 int16_t immediateSet = 0;
162 int32_t frameSizeSampl;
167 uint32_t reductionFactor;
168 uint32_t numBytesInv;
171 uint32_t byteSecondsPerBit;
175 int32_t numPktsExpected;
179 /* UPDATE ESTIMATES FROM OTHER SIDE */
181 /* The function also checks if Index has a valid value */
182 errCode = WebRtcIsacfix_UpdateUplinkBwRec(bweStr, Index);
188 /* UPDATE ESTIMATES ON THIS SIDE */
190 /* Bits per second per byte * 1/30 or 1/60 */
191 if (frameSize == 60) {
192 /* If frameSize changed since last call, from 30 to 60, recalculate some values */
193 if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
194 bweStr->countUpdates = 10;
195 bweStr->recHeaderRate = kRecHeaderRate[1];
197 bweStr->maxBwInv = kInvBandwidth[3];
198 bweStr->minBwInv = kInvBandwidth[2];
199 bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
202 /* kBitsByteSec is in Q15 */
203 recRtpRate = (int16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
204 (int32_t)pksize), 15) + bweStr->recHeaderRate;
207 /* If frameSize changed since last call, from 60 to 30, recalculate some values */
208 if ( (frameSize != bweStr->prevFrameSizeMs) && (bweStr->countUpdates > 0)) {
209 bweStr->countUpdates = 10;
210 bweStr->recHeaderRate = kRecHeaderRate[0];
212 bweStr->maxBwInv = kInvBandwidth[1];
213 bweStr->minBwInv = kInvBandwidth[0];
214 bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, (bweStr->recBw + bweStr->recHeaderRate));
217 /* kBitsByteSec is in Q14 */
218 recRtpRate = (uint16_t)WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(kBitsByteSec,
219 (int32_t)pksize), 14) + bweStr->recHeaderRate;
223 /* Check for timer wrap-around */
224 if (arrivalTime < bweStr->prevArrivalTime) {
225 bweStr->prevArrivalTime = arrivalTime;
226 bweStr->lastUpdate = arrivalTime;
227 bweStr->lastReduction = arrivalTime + FS3;
229 bweStr->countRecPkts = 0;
231 /* store frame size */
232 bweStr->prevFrameSizeMs = frameSize;
234 /* store far-side transmission rate */
235 bweStr->prevRtpRate = recRtpRate;
237 /* store far-side RTP time stamp */
238 bweStr->prevRtpNumber = rtpNumber;
243 bweStr->countRecPkts++;
245 /* Calculate framesize in msec */
246 frameSizeSampl = WEBRTC_SPL_MUL_16_16((int16_t)SAMPLES_PER_MSEC, frameSize);
248 /* Check that it's not one of the first 9 packets */
249 if ( bweStr->countUpdates > 0 ) {
251 /* Stay in Wait Period for 1.5 seconds (no updates in wait period) */
252 if(bweStr->inWaitPeriod) {
253 if ((arrivalTime - bweStr->startWaitPeriod)> FS_1_HALF) {
254 bweStr->inWaitPeriod = 0;
258 /* If not been updated for a long time, reduce the BN estimate */
260 /* Check send time difference between this packet and previous received */
261 sendTimeDiff = sendTime - bweStr->prevSendTime;
262 if (sendTimeDiff <= WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1)) {
264 /* Only update if 3 seconds has past since last update */
265 if ((arrivalTime - bweStr->lastUpdate) > FS3) {
267 /* Calculate expected number of received packets since last update */
268 numPktsExpected = WEBRTC_SPL_UDIV(arrivalTime - bweStr->lastUpdate, frameSizeSampl);
270 /* If received number of packets is more than 90% of expected (922 = 0.9 in Q10): */
271 /* do the update, else not */
272 if(WEBRTC_SPL_LSHIFT_W32(bweStr->countRecPkts, 10) > WEBRTC_SPL_MUL_16_16(922, numPktsExpected)) {
273 /* Q4 chosen to approx dividing by 16 */
274 msec = (arrivalTime - bweStr->lastReduction);
276 /* the number below represents 13 seconds, highly unlikely
277 but to insure no overflow when reduction factor is multiplied by recBw inverse */
282 /* Q20 2^(negative number: - 76/1048576) = .99995
284 exponent = WEBRTC_SPL_UMUL(0x0000004C, msec);
286 /* do the approx with positive exponent so that value is actually rf^-1
287 and multiply by bw inverse */
288 reductionFactor = WEBRTC_SPL_RSHIFT_U32(0x01000000 | (exponent & 0x00FFFFFF),
289 WEBRTC_SPL_RSHIFT_U32(exponent, 24));
291 /* reductionFactor in Q13 */
292 reductionFactor = WEBRTC_SPL_RSHIFT_U32(reductionFactor, 11);
294 if ( reductionFactor != 0 ) {
295 bweStr->recBwInv = WEBRTC_SPL_MUL((int32_t)bweStr->recBwInv, (int32_t)reductionFactor);
296 bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((int32_t)bweStr->recBwInv, 13);
299 /* recBwInv = 1 / (INIT_BN_EST + INIT_HDR_RATE) in Q26 (Q30??)*/
300 bweStr->recBwInv = WEBRTC_SPL_DIV((1073741824 +
301 WEBRTC_SPL_LSHIFT_W32(((int32_t)INIT_BN_EST + INIT_HDR_RATE), 1)), INIT_BN_EST + INIT_HDR_RATE);
304 /* reset time-since-update counter */
305 bweStr->lastReduction = arrivalTime;
307 /* Delay last reduction with 3 seconds */
308 bweStr->lastReduction = arrivalTime + FS3;
309 bweStr->lastUpdate = arrivalTime;
310 bweStr->countRecPkts = 0;
314 bweStr->lastReduction = arrivalTime + FS3;
315 bweStr->lastUpdate = arrivalTime;
316 bweStr->countRecPkts = 0;
320 /* update only if previous packet was not lost */
321 if ( rtpNumber == bweStr->prevRtpNumber + 1 ) {
322 arrTimeDiff = arrivalTime - bweStr->prevArrivalTime;
324 if (!(bweStr->highSpeedSend && bweStr->highSpeedRec)) {
325 if (arrTimeDiff > frameSizeSampl) {
326 if (sendTimeDiff > 0) {
327 lateDiff = arrTimeDiff - sendTimeDiff -
328 WEBRTC_SPL_LSHIFT_W32(frameSizeSampl, 1);
330 lateDiff = arrTimeDiff - frameSizeSampl;
333 /* 8000 is 1/2 second (in samples at FS) */
334 if (lateDiff > 8000) {
335 delayCorrFactor = (int32_t) DELAY_CORRECTION_MAX;
336 bweStr->inWaitPeriod = 1;
337 bweStr->startWaitPeriod = arrivalTime;
339 } else if (lateDiff > 5120) {
340 delayCorrFactor = (int32_t) DELAY_CORRECTION_MED;
342 bweStr->inWaitPeriod = 1;
343 bweStr->startWaitPeriod = arrivalTime;
348 if ((bweStr->prevRtpRate > WEBRTC_SPL_RSHIFT_W32((int32_t) bweStr->recBwAvg, 5)) &&
349 (recRtpRate > WEBRTC_SPL_RSHIFT_W32((int32_t)bweStr->recBwAvg, 5)) &&
350 !bweStr->inWaitPeriod) {
352 /* test if still in initiation period and increment counter */
353 if (bweStr->countUpdates++ > 99) {
354 /* constant weight after initiation part, 0.01 in Q13 */
355 weight = (uint16_t) 82;
357 /* weight decreases with number of updates, 1/countUpdates in Q13 */
358 weight = (uint16_t) WebRtcSpl_DivW32W16(
359 (int32_t)(8192 + WEBRTC_SPL_RSHIFT_W32((int32_t) bweStr->countUpdates, 1)),
360 (int16_t)bweStr->countUpdates);
363 /* Bottle Neck Estimation */
365 /* limit outliers, if more than 25 ms too much */
366 if (arrTimeDiff > frameSizeSampl + kSamplesIn25msec) {
367 arrTimeDiff = frameSizeSampl + kSamplesIn25msec;
370 /* don't allow it to be less than frame rate - 10 ms */
371 if (arrTimeDiff < frameSizeSampl - FRAMESAMPLES_10ms) {
372 arrTimeDiff = frameSizeSampl - FRAMESAMPLES_10ms;
375 /* compute inverse receiving rate for last packet, in Q19 */
376 numBytesInv = (uint16_t) WebRtcSpl_DivW32W16(
377 (int32_t)(524288 + WEBRTC_SPL_RSHIFT_W32(((int32_t)pksize + HEADER_SIZE), 1)),
378 (int16_t)(pksize + HEADER_SIZE));
380 /* 8389 is ~ 1/128000 in Q30 */
381 byteSecondsPerBit = WEBRTC_SPL_MUL_16_16(arrTimeDiff, 8389);
383 /* get upper N bits */
384 tempUpper = WEBRTC_SPL_RSHIFT_U32(byteSecondsPerBit, 15);
386 /* get lower 15 bits */
387 tempLower = byteSecondsPerBit & 0x00007FFF;
389 tempUpper = WEBRTC_SPL_MUL(tempUpper, numBytesInv);
390 tempLower = WEBRTC_SPL_MUL(tempLower, numBytesInv);
391 tempLower = WEBRTC_SPL_RSHIFT_U32(tempLower, 15);
393 currBwInv = tempUpper + tempLower;
394 currBwInv = WEBRTC_SPL_RSHIFT_U32(currBwInv, 4);
396 /* Limit inv rate. Note that minBwInv > maxBwInv! */
397 if(currBwInv < bweStr->maxBwInv) {
398 currBwInv = bweStr->maxBwInv;
399 } else if(currBwInv > bweStr->minBwInv) {
400 currBwInv = bweStr->minBwInv;
403 /* update bottle neck rate estimate */
404 bweStr->recBwInv = WEBRTC_SPL_UMUL(weight, currBwInv) +
405 WEBRTC_SPL_UMUL((uint32_t) 8192 - weight, bweStr->recBwInv);
407 /* Shift back to Q30 from Q40 (actual used bits shouldn't be more than 27 based on minBwInv)
408 up to 30 bits used with Q13 weight */
409 bweStr->recBwInv = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwInv, 13);
411 /* reset time-since-update counter */
412 bweStr->lastUpdate = arrivalTime;
413 bweStr->lastReduction = arrivalTime + FS3;
414 bweStr->countRecPkts = 0;
416 /* to save resolution compute the inverse of recBwAvg in Q26 by left shifting numerator to 2^31
417 and NOT right shifting recBwAvg 5 bits to an integer
418 At max 13 bits are used
420 recBwAvgInv = WEBRTC_SPL_UDIV((uint32_t)(0x80000000 + WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 1)),
423 /* Calculate Projected arrival time difference */
425 /* The numerator of the quotient can be 22 bits so right shift inv by 4 to avoid overflow
427 arrTimeProj = WEBRTC_SPL_MUL((int32_t)8000, recBwAvgInv);
429 arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 4);
430 /* complete calulation */
431 arrTimeProj = WEBRTC_SPL_MUL(((int32_t)pksize + HEADER_SIZE), arrTimeProj);
433 arrTimeProj = WEBRTC_SPL_RSHIFT_U32(arrTimeProj, 12);
435 /* difference between projected and actual arrival time differences */
436 /* Q9 (only shift arrTimeDiff by 5 to simulate divide by 16 (need to revisit if change sampling rate) DH */
437 if (WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) > (int32_t)arrTimeProj) {
438 arrTimeNoise = WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6) - arrTimeProj;
441 arrTimeNoise = arrTimeProj - WEBRTC_SPL_LSHIFT_W32(arrTimeDiff, 6);
446 arrTimeNoiseAbs = arrTimeNoise;
448 /* long term averaged absolute jitter, Q15 */
449 weight = WEBRTC_SPL_RSHIFT_W32(weight, 3);
450 bweStr->recJitter = WEBRTC_SPL_MUL(weight, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 5))
451 + WEBRTC_SPL_MUL(1024 - weight, bweStr->recJitter);
453 /* remove the fractional portion */
454 bweStr->recJitter = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitter, 10);
456 /* Maximum jitter is 10 msec in Q15 */
457 if (bweStr->recJitter > (int32_t)327680) {
458 bweStr->recJitter = (int32_t)327680;
461 /* short term averaged absolute jitter */
462 /* Calculation in Q13 products in Q23 */
463 bweStr->recJitterShortTermAbs = WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32(arrTimeNoiseAbs, 3)) +
464 WEBRTC_SPL_MUL(973, bweStr->recJitterShortTermAbs);
465 bweStr->recJitterShortTermAbs = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTermAbs , 10);
467 /* short term averaged jitter */
468 /* Calculation in Q13 products in Q23 */
469 bweStr->recJitterShortTerm = WEBRTC_SPL_MUL(205, WEBRTC_SPL_LSHIFT_W32(arrTimeNoise, 3)) * sign +
470 WEBRTC_SPL_MUL(3891, bweStr->recJitterShortTerm);
472 if (bweStr->recJitterShortTerm < 0) {
473 temp = -bweStr->recJitterShortTerm;
474 temp = WEBRTC_SPL_RSHIFT_W32(temp, 12);
475 bweStr->recJitterShortTerm = -temp;
477 bweStr->recJitterShortTerm = WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 12);
482 /* reset time-since-update counter when receiving the first 9 packets */
483 bweStr->lastUpdate = arrivalTime;
484 bweStr->lastReduction = arrivalTime + FS3;
485 bweStr->countRecPkts = 0;
486 bweStr->countUpdates++;
489 /* Limit to minimum or maximum bottle neck rate (in Q30) */
490 if (bweStr->recBwInv > bweStr->minBwInv) {
491 bweStr->recBwInv = bweStr->minBwInv;
492 } else if (bweStr->recBwInv < bweStr->maxBwInv) {
493 bweStr->recBwInv = bweStr->maxBwInv;
497 /* store frame length */
498 bweStr->prevFrameSizeMs = frameSize;
500 /* store far-side transmission rate */
501 bweStr->prevRtpRate = recRtpRate;
503 /* store far-side RTP time stamp */
504 bweStr->prevRtpNumber = rtpNumber;
506 /* Replace bweStr->recMaxDelay by the new value (atomic operation) */
507 if (bweStr->prevArrivalTime != 0xffffffff) {
508 bweStr->recMaxDelay = WEBRTC_SPL_MUL(3, bweStr->recJitter);
511 /* store arrival time stamp */
512 bweStr->prevArrivalTime = arrivalTime;
513 bweStr->prevSendTime = sendTime;
515 /* Replace bweStr->recBw by the new value */
516 bweStr->recBw = WEBRTC_SPL_UDIV(1073741824, bweStr->recBwInv) - bweStr->recHeaderRate;
519 /* delay correction factor is in Q10 */
520 bweStr->recBw = WEBRTC_SPL_UMUL(delayCorrFactor, bweStr->recBw);
521 bweStr->recBw = WEBRTC_SPL_RSHIFT_U32(bweStr->recBw, 10);
523 if (bweStr->recBw < (int32_t) MIN_ISAC_BW) {
524 bweStr->recBw = (int32_t) MIN_ISAC_BW;
527 bweStr->recBwAvg = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw + bweStr->recHeaderRate, 5);
529 bweStr->recBwAvgQ = WEBRTC_SPL_LSHIFT_U32(bweStr->recBw, 7);
531 bweStr->recJitterShortTerm = 0;
533 bweStr->recBwInv = WEBRTC_SPL_UDIV(1073741824, bweStr->recBw + bweStr->recHeaderRate);
542 /* This function updates the send bottle neck rate */
543 /* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
544 /* returns 0 if everything went fine, -1 otherwise */
545 int16_t WebRtcIsacfix_UpdateUplinkBwRec(BwEstimatorstr *bweStr,
550 if ( (Index < 0) || (Index > 23) ) {
551 return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
554 /* UPDATE ESTIMATES FROM OTHER SIDE */
557 RateInd = Index - 12;
558 /* compute the jitter estimate as decoded on the other side in Q9 */
559 /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MAX_ISAC_MD */
560 bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
561 WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((int32_t)MAX_ISAC_MD, 9));
562 bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
566 /* compute the jitter estimate as decoded on the other side in Q9 */
567 /* sendMaxDelayAvg = 0.9 * sendMaxDelayAvg + 0.1 * MIN_ISAC_MD */
568 bweStr->sendMaxDelayAvg = WEBRTC_SPL_MUL(461, bweStr->sendMaxDelayAvg) +
569 WEBRTC_SPL_MUL(51, WEBRTC_SPL_LSHIFT_W32((int32_t)MIN_ISAC_MD,9));
570 bweStr->sendMaxDelayAvg = WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
575 /* compute the BN estimate as decoded on the other side */
576 /* sendBwAvg = 0.9 * sendBwAvg + 0.1 * kQRateTable[RateInd]; */
577 bweStr->sendBwAvg = WEBRTC_SPL_UMUL(461, bweStr->sendBwAvg) +
578 WEBRTC_SPL_UMUL(51, WEBRTC_SPL_LSHIFT_U32(kQRateTable[RateInd], 7));
579 bweStr->sendBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 9);
582 if (WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7) > 28000 && !bweStr->highSpeedSend) {
583 bweStr->countHighSpeedSent++;
585 /* approx 2 seconds with 30ms frames */
586 if (bweStr->countHighSpeedSent >= 66) {
587 bweStr->highSpeedSend = 1;
589 } else if (!bweStr->highSpeedSend) {
590 bweStr->countHighSpeedSent = 0;
596 /****************************************************************************
597 * WebRtcIsacfix_GetDownlinkBwIndexImpl(...)
599 * This function calculates and returns the bandwidth/jitter estimation code
600 * (integer 0...23) to put in the sending iSAC payload.
603 * - bweStr : BWE struct
606 * bandwith and jitter index (0..23)
608 uint16_t WebRtcIsacfix_GetDownlinkBwIndexImpl(BwEstimatorstr *bweStr)
613 uint16_t maxDelayBit;
623 /* Get unquantized rate. Always returns 10000 <= rate <= 32000 */
624 rate = WebRtcIsacfix_GetDownlinkBandwidth(bweStr);
626 /* Compute the averaged BN estimate on this side */
628 /* recBwAvg = 0.9 * recBwAvg + 0.1 * (rate + bweStr->recHeaderRate), 0.9 and 0.1 in Q9 */
629 bweStr->recBwAvg = WEBRTC_SPL_UMUL(922, bweStr->recBwAvg) +
630 WEBRTC_SPL_UMUL(102, WEBRTC_SPL_LSHIFT_U32((uint32_t)rate + bweStr->recHeaderRate, 5));
631 bweStr->recBwAvg = WEBRTC_SPL_RSHIFT_U32(bweStr->recBwAvg, 10);
633 /* Find quantization index that gives the closest rate after averaging.
634 * Note that we don't need to check the last value, rate <= kQRateTable[11],
635 * because we will use rateInd = 11 even if rate > kQRateTable[11]. */
636 for (rateInd = 1; rateInd < 11; rateInd++) {
637 if (rate <= kQRateTable[rateInd]){
642 /* find closest quantization index, and update quantized average by taking: */
643 /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
645 /* 0.9 times recBwAvgQ in Q16 */
646 /* 461/512 - 25/65536 =0.900009 */
647 tempTerm1 = WEBRTC_SPL_MUL(bweStr->recBwAvgQ, 25);
648 tempTerm1 = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 7);
649 tempTermX = WEBRTC_SPL_UMUL(461, bweStr->recBwAvgQ) - tempTerm1;
652 tempTermY = WEBRTC_SPL_LSHIFT_W32((int32_t)rate, 16);
654 /* 0.1 * kQRateTable[rateInd] = KQRate01[rateInd] */
655 tempTerm1 = tempTermX + KQRate01[rateInd] - tempTermY;
656 tempTerm2 = tempTermY - tempTermX - KQRate01[rateInd-1];
658 /* Compare (0.9 * recBwAvgQ + 0.1 * kQRateTable[rateInd] - rate) >
659 (rate - 0.9 * recBwAvgQ - 0.1 * kQRateTable[rateInd-1]) */
660 if (tempTerm1 > tempTerm2) {
664 /* Update quantized average by taking: */
665 /* 0.9*recBwAvgQ + 0.1*kQRateTable[rateInd] */
667 /* Add 0.1 times kQRateTable[rateInd], in Q16 */
668 tempTermX += KQRate01[rateInd];
670 /* Shift back to Q7 */
671 bweStr->recBwAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTermX, 9);
673 /* Count consecutive received bandwidth above 28000 kbps (28000 in Q7 = 3584000) */
674 /* If 66 high estimates in a row, set highSpeedRec to one */
675 /* 66 corresponds to ~2 seconds in 30 msec mode */
676 if ((bweStr->recBwAvgQ > 3584000) && !bweStr->highSpeedRec) {
677 bweStr->countHighSpeedRec++;
678 if (bweStr->countHighSpeedRec >= 66) {
679 bweStr->highSpeedRec = 1;
681 } else if (!bweStr->highSpeedRec) {
682 bweStr->countHighSpeedRec = 0;
685 /* Get Max Delay Bit */
687 /* get unquantized max delay */
688 maxDelay = WebRtcIsacfix_GetDownlinkMaxDelay(bweStr);
690 /* Update quantized max delay average */
691 tempMax = 652800; /* MAX_ISAC_MD * 0.1 in Q18 */
692 tempMin = 130560; /* MIN_ISAC_MD * 0.1 in Q18 */
693 tempTermX = WEBRTC_SPL_MUL((int32_t)bweStr->recMaxDelayAvgQ, (int32_t)461);
694 tempTermY = WEBRTC_SPL_LSHIFT_W32((int32_t)maxDelay, 18);
696 tempTerm1 = tempTermX + tempMax - tempTermY;
697 tempTerm2 = tempTermY - tempTermX - tempMin;
699 if ( tempTerm1 > tempTerm2) {
701 tempTerm1 = tempTermX + tempMin;
703 /* update quantized average, shift back to Q9 */
704 bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
707 tempTerm1 = tempTermX + tempMax;
709 /* update quantized average, shift back to Q9 */
710 bweStr->recMaxDelayAvgQ = WEBRTC_SPL_RSHIFT_W32(tempTerm1, 9);
713 /* Return bandwitdh and jitter index (0..23) */
714 return (uint16_t)(rateInd + maxDelayBit);
717 /* get the bottle neck rate from far side to here, as estimated on this side */
718 uint16_t WebRtcIsacfix_GetDownlinkBandwidth(const BwEstimatorstr *bweStr)
721 int32_t jitter_sign; /* Q8 */
722 int32_t bw_adjust; /* Q16 */
723 int32_t rec_jitter_short_term_abs_inv; /* Q18 */
726 /* Q18 rec jitter short term abs is in Q13, multiply it by 2^13 to save precision
727 2^18 then needs to be shifted 13 bits to 2^31 */
728 rec_jitter_short_term_abs_inv = WEBRTC_SPL_UDIV(0x80000000, bweStr->recJitterShortTermAbs);
731 jitter_sign = WEBRTC_SPL_MUL(WEBRTC_SPL_RSHIFT_W32(bweStr->recJitterShortTerm, 4), (int32_t)rec_jitter_short_term_abs_inv);
733 if (jitter_sign < 0) {
735 temp = WEBRTC_SPL_RSHIFT_W32(temp, 19);
738 jitter_sign = WEBRTC_SPL_RSHIFT_W32(jitter_sign, 19);
741 /* adjust bw proportionally to negative average jitter sign */
742 //bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
743 //Q8 -> Q16 .15 +.15 * jitter^2 first term is .15 in Q16 latter term is Q8*Q8*Q8
744 //38 in Q8 ~.15 9830 in Q16 ~.15
745 temp = 9830 + WEBRTC_SPL_RSHIFT_W32((WEBRTC_SPL_MUL(38, WEBRTC_SPL_MUL(jitter_sign, jitter_sign))), 8);
747 if (jitter_sign < 0) {
748 temp = WEBRTC_SPL_MUL(jitter_sign, temp);
750 temp = WEBRTC_SPL_RSHIFT_W32(temp, 8);
751 bw_adjust = (uint32_t)65536 + temp; /* (1 << 16) + temp; */
753 bw_adjust = (uint32_t)65536 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(jitter_sign, temp), 8);/* (1 << 16) - ((jitter_sign * temp) >> 8); */
756 //make sure following multiplication won't overflow
758 bw_adjust = WEBRTC_SPL_RSHIFT_W32(bw_adjust, 2);//see if good resolution is maintained
760 /* adjust Rate if jitter sign is mostly constant */
761 recBw = WEBRTC_SPL_UMUL(bweStr->recBw, bw_adjust);
763 recBw = WEBRTC_SPL_RSHIFT_W32(recBw, 14);
765 /* limit range of bottle neck rate */
766 if (recBw < MIN_ISAC_BW) {
768 } else if (recBw > MAX_ISAC_BW) {
772 return (uint16_t) recBw;
775 /* Returns the mmax delay (in ms) */
776 int16_t WebRtcIsacfix_GetDownlinkMaxDelay(const BwEstimatorstr *bweStr)
780 recMaxDelay = (int16_t) WEBRTC_SPL_RSHIFT_W32(bweStr->recMaxDelay, 15);
782 /* limit range of jitter estimate */
783 if (recMaxDelay < MIN_ISAC_MD) {
784 recMaxDelay = MIN_ISAC_MD;
785 } else if (recMaxDelay > MAX_ISAC_MD) {
786 recMaxDelay = MAX_ISAC_MD;
792 /* get the bottle neck rate from here to far side, as estimated by far side */
793 int16_t WebRtcIsacfix_GetUplinkBandwidth(const BwEstimatorstr *bweStr)
797 send_bw = (int16_t) WEBRTC_SPL_RSHIFT_U32(bweStr->sendBwAvg, 7);
799 /* limit range of bottle neck rate */
800 if (send_bw < MIN_ISAC_BW) {
801 send_bw = MIN_ISAC_BW;
802 } else if (send_bw > MAX_ISAC_BW) {
803 send_bw = MAX_ISAC_BW;
811 /* Returns the max delay value from the other side in ms */
812 int16_t WebRtcIsacfix_GetUplinkMaxDelay(const BwEstimatorstr *bweStr)
814 int16_t send_max_delay;
816 send_max_delay = (int16_t) WEBRTC_SPL_RSHIFT_W32(bweStr->sendMaxDelayAvg, 9);
818 /* limit range of jitter estimate */
819 if (send_max_delay < MIN_ISAC_MD) {
820 send_max_delay = MIN_ISAC_MD;
821 } else if (send_max_delay > MAX_ISAC_MD) {
822 send_max_delay = MAX_ISAC_MD;
825 return send_max_delay;
832 * update long-term average bitrate and amount of data in buffer
833 * returns minimum payload size (bytes)
835 uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State,
836 int16_t StreamSize, /* bytes in bitstream */
837 const int16_t FrameSamples, /* samples per frame */
838 const int16_t BottleNeck, /* bottle neck rate; excl headers (bps) */
839 const int16_t DelayBuildUp) /* max delay from bottle neck buffering (ms) */
843 int16_t TransmissionTime;
848 /* first 10 packets @ low rate, then INIT_BURST_LEN packets @ fixed rate of INIT_RATE bps */
849 if (State->InitCounter > 0) {
850 if (State->InitCounter-- <= INIT_BURST_LEN) {
857 if (State->BurstCounter) {
858 if (State->StillBuffered < WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL((512 - WEBRTC_SPL_DIV(512, BURST_LEN)), DelayBuildUp), 9)) {
859 /* max bps derived from BottleNeck and DelayBuildUp values */
860 inv_Q12 = WEBRTC_SPL_DIV(4096, WEBRTC_SPL_MUL(BURST_LEN, FrameSamples));
861 MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck);
863 /* max bps derived from StillBuffered and DelayBuildUp values */
864 inv_Q12 = WEBRTC_SPL_DIV(4096, FrameSamples);
865 if (DelayBuildUp > State->StillBuffered) {
866 MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck);
867 } else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) {
868 /* MinRate will be negative here */
871 MinRate = WEBRTC_SPL_MUL((512 - WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(den, inv_Q12), 3)), BottleNeck);
873 //if (MinRate < 1.04 * BottleNeck)
874 // MinRate = 1.04 * BottleNeck;
876 if (MinRate < WEBRTC_SPL_MUL(532, BottleNeck)) {
877 MinRate += WEBRTC_SPL_MUL(22, BottleNeck);
881 State->BurstCounter--;
886 /* convert rate from bits/second to bytes/packet */
887 //round and shift before conversion
889 MinRate = WEBRTC_SPL_RSHIFT_W32(MinRate, 9);
890 MinBytes = (uint16_t)WEBRTC_SPL_UDIV(WEBRTC_SPL_MUL(MinRate, FrameSamples), FS8);
892 /* StreamSize will be adjusted if less than MinBytes */
893 if (StreamSize < MinBytes) {
894 StreamSize = MinBytes;
897 /* keep track of when bottle neck was last exceeded by at least 1% */
899 if (WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, FS8), FrameSamples) > (WEBRTC_SPL_MUL(517, BottleNeck) >> 9)) {
900 if (State->PrevExceed) {
901 /* bottle_neck exceded twice in a row, decrease ExceedAgo */
902 State->ExceedAgo -= WEBRTC_SPL_DIV(BURST_INTERVAL, BURST_LEN - 1);
903 if (State->ExceedAgo < 0) {
904 State->ExceedAgo = 0;
907 State->ExceedAgo += (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */
908 State->PrevExceed = 1;
911 State->PrevExceed = 0;
912 State->ExceedAgo += (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */
915 /* set burst flag if bottle neck not exceeded for long time */
916 if ((State->ExceedAgo > BURST_INTERVAL) && (State->BurstCounter == 0)) {
917 if (State->PrevExceed) {
918 State->BurstCounter = BURST_LEN - 1;
920 State->BurstCounter = BURST_LEN;
925 /* Update buffer delay */
926 TransmissionTime = (int16_t)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, 8000), BottleNeck); /* ms */
927 State->StillBuffered += TransmissionTime;
928 State->StillBuffered -= (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); //>>4 = SAMPLES_PER_MSEC /* ms */
929 if (State->StillBuffered < 0) {
930 State->StillBuffered = 0;
933 if (State->StillBuffered > 2000) {
934 State->StillBuffered = 2000;
942 * update long-term average bitrate and amount of data in buffer
944 void WebRtcIsacfix_UpdateRateModel(RateModel *State,
945 int16_t StreamSize, /* bytes in bitstream */
946 const int16_t FrameSamples, /* samples per frame */
947 const int16_t BottleNeck) /* bottle neck rate; excl headers (bps) */
949 int16_t TransmissionTime;
951 /* avoid the initial "high-rate" burst */
952 State->InitCounter = 0;
954 /* Update buffer delay */
955 TransmissionTime = (int16_t)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(WEBRTC_SPL_MUL(StreamSize, 8), 1000), BottleNeck); /* ms */
956 State->StillBuffered += TransmissionTime;
957 State->StillBuffered -= (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */
958 if (State->StillBuffered < 0) {
959 State->StillBuffered = 0;
965 void WebRtcIsacfix_InitRateModel(RateModel *State)
967 State->PrevExceed = 0; /* boolean */
968 State->ExceedAgo = 0; /* ms */
969 State->BurstCounter = 0; /* packets */
970 State->InitCounter = INIT_BURST_LEN + 10; /* packets */
971 State->StillBuffered = 1; /* ms */
978 int16_t WebRtcIsacfix_GetNewFrameLength(int16_t bottle_neck, int16_t current_framesamples)
980 int16_t new_framesamples;
982 new_framesamples = current_framesamples;
984 /* find new framelength */
985 switch(current_framesamples) {
987 if (bottle_neck < Thld_30_60) {
988 new_framesamples = 960;
992 if (bottle_neck >= Thld_60_30) {
993 new_framesamples = 480;
997 new_framesamples = -1; /* Error */
1000 return new_framesamples;
1003 int16_t WebRtcIsacfix_GetSnr(int16_t bottle_neck, int16_t framesamples)
1007 /* find new SNR value */
1008 //consider BottleNeck to be in Q10 ( * 1 in Q10)
1009 switch(framesamples) {
1011 /*s2nr = -1*(a_30 << 10) + ((b_30 * bottle_neck) >> 10);*/
1012 s2nr = -22500 + (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
1015 /*s2nr = -1*(a_60 << 10) + ((b_60 * bottle_neck) >> 10);*/
1016 s2nr = -22500 + (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(500, bottle_neck, 10); //* 0.001; //+ c_30 * bottle_neck * bottle_neck * 0.000001;
1019 s2nr = -1; /* Error */
1022 return s2nr; //return in Q10