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 */ 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 */ 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 */ 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 */ 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 */ 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) */ 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]. */ 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 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 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 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 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 */ 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 */ 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 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 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 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