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