1 /*
2 * Copyright (c) 2012 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 * BwEstimator.c
13 *
14 * This file contains the code for the Bandwidth Estimator designed
15 * for iSAC.
16 *
17 */
18
19 #include "bandwidth_estimator.h"
20 #include "settings.h"
21 #include "isac.h"
22
23 #include <math.h>
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 float kQRateTableWb[12] =
28 {
29 10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
30 18859.8f, 20963.3f, 23301.4f, 25900.3f, 28789.0f, 32000.0f};
31
32
33 static const float kQRateTableSwb[24] =
34 {
35 10000.0f, 11115.3f, 12355.1f, 13733.1f, 15264.8f, 16967.3f,
36 18859.8f, 20963.3f, 23153.1f, 25342.9f, 27532.7f, 29722.5f,
37 31912.3f, 34102.1f, 36291.9f, 38481.7f, 40671.4f, 42861.2f,
38 45051.0f, 47240.8f, 49430.6f, 51620.4f, 53810.2f, 56000.0f,
39 };
40
41
42
43
WebRtcIsac_InitBandwidthEstimator(BwEstimatorstr * bwest_str,enum IsacSamplingRate encoderSampRate,enum IsacSamplingRate decoderSampRate)44 WebRtc_Word32 WebRtcIsac_InitBandwidthEstimator(
45 BwEstimatorstr* bwest_str,
46 enum IsacSamplingRate encoderSampRate,
47 enum IsacSamplingRate decoderSampRate)
48 {
49 switch(encoderSampRate)
50 {
51 case kIsacWideband:
52 {
53 bwest_str->send_bw_avg = INIT_BN_EST_WB;
54 break;
55 }
56 case kIsacSuperWideband:
57 {
58 bwest_str->send_bw_avg = INIT_BN_EST_SWB;
59 break;
60 }
61 }
62
63 switch(decoderSampRate)
64 {
65 case kIsacWideband:
66 {
67 bwest_str->prev_frame_length = INIT_FRAME_LEN_WB;
68 bwest_str->rec_bw_inv = 1.0f /
69 (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
70 bwest_str->rec_bw = (WebRtc_Word32)INIT_BN_EST_WB;
71 bwest_str->rec_bw_avg_Q = INIT_BN_EST_WB;
72 bwest_str->rec_bw_avg = INIT_BN_EST_WB + INIT_HDR_RATE_WB;
73 bwest_str->rec_header_rate = INIT_HDR_RATE_WB;
74 break;
75 }
76 case kIsacSuperWideband:
77 {
78 bwest_str->prev_frame_length = INIT_FRAME_LEN_SWB;
79 bwest_str->rec_bw_inv = 1.0f /
80 (INIT_BN_EST_SWB + INIT_HDR_RATE_SWB);
81 bwest_str->rec_bw = (WebRtc_Word32)INIT_BN_EST_SWB;
82 bwest_str->rec_bw_avg_Q = INIT_BN_EST_SWB;
83 bwest_str->rec_bw_avg = INIT_BN_EST_SWB + INIT_HDR_RATE_SWB;
84 bwest_str->rec_header_rate = INIT_HDR_RATE_SWB;
85 break;
86 }
87 }
88
89 bwest_str->prev_rec_rtp_number = 0;
90 bwest_str->prev_rec_arr_ts = 0;
91 bwest_str->prev_rec_send_ts = 0;
92 bwest_str->prev_rec_rtp_rate = 1.0f;
93 bwest_str->last_update_ts = 0;
94 bwest_str->last_reduction_ts = 0;
95 bwest_str->count_tot_updates_rec = -9;
96 bwest_str->rec_jitter = 10.0f;
97 bwest_str->rec_jitter_short_term = 0.0f;
98 bwest_str->rec_jitter_short_term_abs = 5.0f;
99 bwest_str->rec_max_delay = 10.0f;
100 bwest_str->rec_max_delay_avg_Q = 10.0f;
101 bwest_str->num_pkts_rec = 0;
102
103 bwest_str->send_max_delay_avg = 10.0f;
104
105 bwest_str->hsn_detect_rec = 0;
106
107 bwest_str->num_consec_rec_pkts_over_30k = 0;
108
109 bwest_str->hsn_detect_snd = 0;
110
111 bwest_str->num_consec_snt_pkts_over_30k = 0;
112
113 bwest_str->in_wait_period = 0;
114
115 bwest_str->change_to_WB = 0;
116
117 bwest_str->numConsecLatePkts = 0;
118 bwest_str->consecLatency = 0;
119 bwest_str->inWaitLatePkts = 0;
120 bwest_str->senderTimestamp = 0;
121 bwest_str->receiverTimestamp = 0;
122 return 0;
123 }
124
125 /* This function updates both bottle neck rates */
126 /* Parameters: */
127 /* rtp_number - value from RTP packet, from NetEq */
128 /* frame length - length of signal frame in ms, from iSAC decoder */
129 /* send_ts - value in RTP header giving send time in samples */
130 /* arr_ts - value given by timeGetTime() time of arrival in samples of packet from NetEq */
131 /* pksize - size of packet in bytes, from NetEq */
132 /* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
133 /* returns 0 if everything went fine, -1 otherwise */
WebRtcIsac_UpdateBandwidthEstimator(BwEstimatorstr * bwest_str,const WebRtc_UWord16 rtp_number,const WebRtc_Word32 frame_length,const WebRtc_UWord32 send_ts,const WebRtc_UWord32 arr_ts,const WebRtc_Word32 pksize)134 WebRtc_Word16 WebRtcIsac_UpdateBandwidthEstimator(
135 BwEstimatorstr *bwest_str,
136 const WebRtc_UWord16 rtp_number,
137 const WebRtc_Word32 frame_length,
138 const WebRtc_UWord32 send_ts,
139 const WebRtc_UWord32 arr_ts,
140 const WebRtc_Word32 pksize
141 /*, const WebRtc_UWord16 Index*/)
142 {
143 float weight = 0.0f;
144 float curr_bw_inv = 0.0f;
145 float rec_rtp_rate;
146 float t_diff_proj;
147 float arr_ts_diff;
148 float send_ts_diff;
149 float arr_time_noise;
150 float arr_time_noise_abs;
151
152 float delay_correction_factor = 1;
153 float late_diff = 0.0f;
154 int immediate_set = 0;
155 int num_pkts_expected;
156
157
158 // We have to adjust the header-rate if the first packet has a
159 // frame-size different than the initialized value.
160 if ( frame_length != bwest_str->prev_frame_length )
161 {
162 bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
163 1000.0f / (float)frame_length; /* bits/s */
164 }
165
166 /* UPDATE ESTIMATES ON THIS SIDE */
167 /* compute far-side transmission rate */
168 rec_rtp_rate = ((float)pksize * 8.0f * 1000.0f / (float)frame_length) +
169 bwest_str->rec_header_rate;
170 // rec_rtp_rate packet bits/s + header bits/s
171
172 /* check for timer wrap-around */
173 if (arr_ts < bwest_str->prev_rec_arr_ts)
174 {
175 bwest_str->prev_rec_arr_ts = arr_ts;
176 bwest_str->last_update_ts = arr_ts;
177 bwest_str->last_reduction_ts = arr_ts + 3*FS;
178 bwest_str->num_pkts_rec = 0;
179
180 /* store frame length */
181 bwest_str->prev_frame_length = frame_length;
182
183 /* store far-side transmission rate */
184 bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
185
186 /* store far-side RTP time stamp */
187 bwest_str->prev_rec_rtp_number = rtp_number;
188
189 return 0;
190 }
191
192 bwest_str->num_pkts_rec++;
193
194 /* check that it's not one of the first 9 packets */
195 if ( bwest_str->count_tot_updates_rec > 0 )
196 {
197 if(bwest_str->in_wait_period > 0 )
198 {
199 bwest_str->in_wait_period--;
200 }
201
202 bwest_str->inWaitLatePkts -= ((bwest_str->inWaitLatePkts > 0)? 1:0);
203 send_ts_diff = (float)(send_ts - bwest_str->prev_rec_send_ts);
204
205 if (send_ts_diff <= (16 * frame_length)*2)
206 //doesn't allow for a dropped packet, not sure necessary to be
207 // that strict -DH
208 {
209 /* if not been updated for a long time, reduce the BN estimate */
210 if((WebRtc_UWord32)(arr_ts - bwest_str->last_update_ts) *
211 1000.0f / FS > 3000)
212 {
213 //how many frames should have been received since the last
214 // update if too many have been dropped or there have been
215 // big delays won't allow this reduction may no longer need
216 // the send_ts_diff here
217 num_pkts_expected = (int)(((float)(arr_ts -
218 bwest_str->last_update_ts) * 1000.0f /(float) FS) /
219 (float)frame_length);
220
221 if(((float)bwest_str->num_pkts_rec/(float)num_pkts_expected) >
222 0.9)
223 {
224 float inv_bitrate = (float) pow( 0.99995,
225 (double)((WebRtc_UWord32)(arr_ts -
226 bwest_str->last_reduction_ts)*1000.0f/FS) );
227
228 if ( inv_bitrate )
229 {
230 bwest_str->rec_bw_inv /= inv_bitrate;
231
232 //precautionary, likely never necessary
233 if (bwest_str->hsn_detect_snd &&
234 bwest_str->hsn_detect_rec)
235 {
236 if (bwest_str->rec_bw_inv > 0.000066f)
237 {
238 bwest_str->rec_bw_inv = 0.000066f;
239 }
240 }
241 }
242 else
243 {
244 bwest_str->rec_bw_inv = 1.0f /
245 (INIT_BN_EST_WB + INIT_HDR_RATE_WB);
246 }
247 /* reset time-since-update counter */
248 bwest_str->last_reduction_ts = arr_ts;
249 }
250 else
251 //reset here?
252 {
253 bwest_str->last_reduction_ts = arr_ts + 3*FS;
254 bwest_str->last_update_ts = arr_ts;
255 bwest_str->num_pkts_rec = 0;
256 }
257 }
258 }
259 else
260 {
261 bwest_str->last_reduction_ts = arr_ts + 3*FS;
262 bwest_str->last_update_ts = arr_ts;
263 bwest_str->num_pkts_rec = 0;
264 }
265
266
267 /* temporarily speed up adaptation if frame length has changed */
268 if ( frame_length != bwest_str->prev_frame_length )
269 {
270 bwest_str->count_tot_updates_rec = 10;
271 bwest_str->rec_header_rate = (float)HEADER_SIZE * 8.0f *
272 1000.0f / (float)frame_length; /* bits/s */
273
274 bwest_str->rec_bw_inv = 1.0f /((float)bwest_str->rec_bw +
275 bwest_str->rec_header_rate);
276 }
277
278 ////////////////////////
279 arr_ts_diff = (float)(arr_ts - bwest_str->prev_rec_arr_ts);
280
281 if (send_ts_diff > 0 )
282 {
283 late_diff = arr_ts_diff - send_ts_diff;
284 }
285 else
286 {
287 late_diff = arr_ts_diff - (float)(16 * frame_length);
288 }
289
290 if((late_diff > 0) && !bwest_str->inWaitLatePkts)
291 {
292 bwest_str->numConsecLatePkts++;
293 bwest_str->consecLatency += late_diff;
294 }
295 else
296 {
297 bwest_str->numConsecLatePkts = 0;
298 bwest_str->consecLatency = 0;
299 }
300 if(bwest_str->numConsecLatePkts > 50)
301 {
302 float latencyMs = bwest_str->consecLatency/(FS/1000);
303 float averageLatencyMs = latencyMs / bwest_str->numConsecLatePkts;
304 delay_correction_factor = frame_length / (frame_length + averageLatencyMs);
305 immediate_set = 1;
306 bwest_str->inWaitLatePkts = (WebRtc_Word16)((bwest_str->consecLatency/(FS/1000)) / 30);// + 150;
307 bwest_str->start_wait_period = arr_ts;
308 }
309 ///////////////////////////////////////////////
310
311
312
313 /* update only if previous packet was not lost */
314 if ( rtp_number == bwest_str->prev_rec_rtp_number + 1 )
315 {
316
317
318 if (!(bwest_str->hsn_detect_snd && bwest_str->hsn_detect_rec))
319 {
320 if ((arr_ts_diff > (float)(16 * frame_length)))
321 {
322 //1/2 second
323 if ((late_diff > 8000.0f) && !bwest_str->in_wait_period)
324 {
325 delay_correction_factor = 0.7f;
326 bwest_str->in_wait_period = 55;
327 bwest_str->start_wait_period = arr_ts;
328 immediate_set = 1;
329 }
330 //320 ms
331 else if (late_diff > 5120.0f && !bwest_str->in_wait_period)
332 {
333 delay_correction_factor = 0.8f;
334 immediate_set = 1;
335 bwest_str->in_wait_period = 44;
336 bwest_str->start_wait_period = arr_ts;
337 }
338 }
339 }
340
341
342 if ((bwest_str->prev_rec_rtp_rate > bwest_str->rec_bw_avg) &&
343 (rec_rtp_rate > bwest_str->rec_bw_avg) &&
344 !bwest_str->in_wait_period)
345 {
346 /* test if still in initiation period and increment counter */
347 if (bwest_str->count_tot_updates_rec++ > 99)
348 {
349 /* constant weight after initiation part */
350 weight = 0.01f;
351 }
352 else
353 {
354 /* weight decreases with number of updates */
355 weight = 1.0f / (float) bwest_str->count_tot_updates_rec;
356 }
357 /* Bottle Neck Estimation */
358
359 /* limit outliers */
360 /* if more than 25 ms too much */
361 if (arr_ts_diff > frame_length * FS/1000 + 400.0f)
362 {
363 // in samples, why 25ms??
364 arr_ts_diff = frame_length * FS/1000 + 400.0f;
365 }
366 if(arr_ts_diff < (frame_length * FS/1000) - 160.0f)
367 {
368 /* don't allow it to be less than frame rate - 10 ms */
369 arr_ts_diff = (float)frame_length * FS/1000 - 160.0f;
370 }
371
372 /* compute inverse receiving rate for last packet */
373 curr_bw_inv = arr_ts_diff / ((float)(pksize + HEADER_SIZE) *
374 8.0f * FS); // (180+35)*8*16000 = 27.5 Mbit....
375
376
377 if(curr_bw_inv <
378 (1.0f / (MAX_ISAC_BW + bwest_str->rec_header_rate)))
379 {
380 // don't allow inv rate to be larger than MAX
381 curr_bw_inv = (1.0f /
382 (MAX_ISAC_BW + bwest_str->rec_header_rate));
383 }
384
385 /* update bottle neck rate estimate */
386 bwest_str->rec_bw_inv = weight * curr_bw_inv +
387 (1.0f - weight) * bwest_str->rec_bw_inv;
388
389 /* reset time-since-update counter */
390 bwest_str->last_update_ts = arr_ts;
391 bwest_str->last_reduction_ts = arr_ts + 3 * FS;
392 bwest_str->num_pkts_rec = 0;
393
394 /* Jitter Estimation */
395 /* projected difference between arrival times */
396 t_diff_proj = ((float)(pksize + HEADER_SIZE) * 8.0f *
397 1000.0f) / bwest_str->rec_bw_avg;
398
399
400 // difference between projected and actual
401 // arrival time differences
402 arr_time_noise = (float)(arr_ts_diff*1000.0f/FS) -
403 t_diff_proj;
404 arr_time_noise_abs = (float) fabs( arr_time_noise );
405
406 /* long term averaged absolute jitter */
407 bwest_str->rec_jitter = weight * arr_time_noise_abs +
408 (1.0f - weight) * bwest_str->rec_jitter;
409 if (bwest_str->rec_jitter > 10.0f)
410 {
411 bwest_str->rec_jitter = 10.0f;
412 }
413 /* short term averaged absolute jitter */
414 bwest_str->rec_jitter_short_term_abs = 0.05f *
415 arr_time_noise_abs + 0.95f *
416 bwest_str->rec_jitter_short_term_abs;
417
418 /* short term averaged jitter */
419 bwest_str->rec_jitter_short_term = 0.05f * arr_time_noise +
420 0.95f * bwest_str->rec_jitter_short_term;
421 }
422 }
423 }
424 else
425 {
426 // reset time-since-update counter when
427 // receiving the first 9 packets
428 bwest_str->last_update_ts = arr_ts;
429 bwest_str->last_reduction_ts = arr_ts + 3*FS;
430 bwest_str->num_pkts_rec = 0;
431
432 bwest_str->count_tot_updates_rec++;
433 }
434
435 /* limit minimum bottle neck rate */
436 if (bwest_str->rec_bw_inv > 1.0f / ((float)MIN_ISAC_BW +
437 bwest_str->rec_header_rate))
438 {
439 bwest_str->rec_bw_inv = 1.0f / ((float)MIN_ISAC_BW +
440 bwest_str->rec_header_rate);
441 }
442
443 // limit maximum bitrate
444 if (bwest_str->rec_bw_inv < 1.0f / ((float)MAX_ISAC_BW +
445 bwest_str->rec_header_rate))
446 {
447 bwest_str->rec_bw_inv = 1.0f / ((float)MAX_ISAC_BW +
448 bwest_str->rec_header_rate);
449 }
450
451 /* store frame length */
452 bwest_str->prev_frame_length = frame_length;
453
454 /* store far-side transmission rate */
455 bwest_str->prev_rec_rtp_rate = rec_rtp_rate;
456
457 /* store far-side RTP time stamp */
458 bwest_str->prev_rec_rtp_number = rtp_number;
459
460 // Replace bwest_str->rec_max_delay by the new
461 // value (atomic operation)
462 bwest_str->rec_max_delay = 3.0f * bwest_str->rec_jitter;
463
464 /* store send and arrival time stamp */
465 bwest_str->prev_rec_arr_ts = arr_ts ;
466 bwest_str->prev_rec_send_ts = send_ts;
467
468 /* Replace bwest_str->rec_bw by the new value (atomic operation) */
469 bwest_str->rec_bw = (WebRtc_Word32)(1.0f / bwest_str->rec_bw_inv -
470 bwest_str->rec_header_rate);
471
472 if (immediate_set)
473 {
474 bwest_str->rec_bw = (WebRtc_Word32) (delay_correction_factor *
475 (float) bwest_str->rec_bw);
476
477 if (bwest_str->rec_bw < (WebRtc_Word32) MIN_ISAC_BW)
478 {
479 bwest_str->rec_bw = (WebRtc_Word32) MIN_ISAC_BW;
480 }
481
482 bwest_str->rec_bw_avg = bwest_str->rec_bw +
483 bwest_str->rec_header_rate;
484
485 bwest_str->rec_bw_avg_Q = (float) bwest_str->rec_bw;
486
487 bwest_str->rec_jitter_short_term = 0.0f;
488
489 bwest_str->rec_bw_inv = 1.0f / (bwest_str->rec_bw +
490 bwest_str->rec_header_rate);
491
492 bwest_str->count_tot_updates_rec = 1;
493
494 immediate_set = 0;
495 bwest_str->consecLatency = 0;
496 bwest_str->numConsecLatePkts = 0;
497 }
498
499 return 0;
500 }
501
502
503 /* This function updates the send bottle neck rate */
504 /* Index - integer (range 0...23) indicating bottle neck & jitter as estimated by other side */
505 /* returns 0 if everything went fine, -1 otherwise */
WebRtcIsac_UpdateUplinkBwImpl(BwEstimatorstr * bwest_str,WebRtc_Word16 index,enum IsacSamplingRate encoderSamplingFreq)506 WebRtc_Word16 WebRtcIsac_UpdateUplinkBwImpl(
507 BwEstimatorstr* bwest_str,
508 WebRtc_Word16 index,
509 enum IsacSamplingRate encoderSamplingFreq)
510 {
511 if((index < 0) || (index > 23))
512 {
513 return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
514 }
515
516 /* UPDATE ESTIMATES FROM OTHER SIDE */
517 if(encoderSamplingFreq == kIsacWideband)
518 {
519 if(index > 11)
520 {
521 index -= 12;
522 /* compute the jitter estimate as decoded on the other side */
523 bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
524 0.1f * (float)MAX_ISAC_MD;
525 }
526 else
527 {
528 /* compute the jitter estimate as decoded on the other side */
529 bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
530 0.1f * (float)MIN_ISAC_MD;
531 }
532
533 /* compute the BN estimate as decoded on the other side */
534 bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
535 0.1f * kQRateTableWb[index];
536 }
537 else
538 {
539 /* compute the BN estimate as decoded on the other side */
540 bwest_str->send_bw_avg = 0.9f * bwest_str->send_bw_avg +
541 0.1f * kQRateTableSwb[index];
542 }
543
544 if (bwest_str->send_bw_avg > (float) 28000 && !bwest_str->hsn_detect_snd)
545 {
546 bwest_str->num_consec_snt_pkts_over_30k++;
547
548 if (bwest_str->num_consec_snt_pkts_over_30k >= 66)
549 {
550 //approx 2 seconds with 30ms frames
551 bwest_str->hsn_detect_snd = 1;
552 }
553 }
554 else if (!bwest_str->hsn_detect_snd)
555 {
556 bwest_str->num_consec_snt_pkts_over_30k = 0;
557 }
558 return 0;
559 }
560
561 // called when there is upper-band bit-stream to update jitter
562 // statistics.
WebRtcIsac_UpdateUplinkJitter(BwEstimatorstr * bwest_str,WebRtc_Word32 index)563 WebRtc_Word16 WebRtcIsac_UpdateUplinkJitter(
564 BwEstimatorstr* bwest_str,
565 WebRtc_Word32 index)
566 {
567 if((index < 0) || (index > 23))
568 {
569 return -ISAC_RANGE_ERROR_BW_ESTIMATOR;
570 }
571
572 if(index > 0)
573 {
574 /* compute the jitter estimate as decoded on the other side */
575 bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
576 0.1f * (float)MAX_ISAC_MD;
577 }
578 else
579 {
580 /* compute the jitter estimate as decoded on the other side */
581 bwest_str->send_max_delay_avg = 0.9f * bwest_str->send_max_delay_avg +
582 0.1f * (float)MIN_ISAC_MD;
583 }
584
585 return 0;
586 }
587
588
589
590 // Returns the bandwidth/jitter estimation code (integer 0...23)
591 // to put in the sending iSAC payload
592 WebRtc_UWord16
WebRtcIsac_GetDownlinkBwJitIndexImpl(BwEstimatorstr * bwest_str,WebRtc_Word16 * bottleneckIndex,WebRtc_Word16 * jitterInfo,enum IsacSamplingRate decoderSamplingFreq)593 WebRtcIsac_GetDownlinkBwJitIndexImpl(
594 BwEstimatorstr* bwest_str,
595 WebRtc_Word16* bottleneckIndex,
596 WebRtc_Word16* jitterInfo,
597 enum IsacSamplingRate decoderSamplingFreq)
598 {
599 float MaxDelay;
600 //WebRtc_UWord16 MaxDelayBit;
601
602 float rate;
603 float r;
604 float e1, e2;
605 const float weight = 0.1f;
606 const float* ptrQuantizationTable;
607 WebRtc_Word16 addJitterInfo;
608 WebRtc_Word16 minInd;
609 WebRtc_Word16 maxInd;
610 WebRtc_Word16 midInd;
611
612 /* Get Max Delay Bit */
613 /* get unquantized max delay */
614 MaxDelay = (float)WebRtcIsac_GetDownlinkMaxDelay(bwest_str);
615
616 if ( ((1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
617 MAX_ISAC_MD - MaxDelay) > (MaxDelay - (1.f-weight) *
618 bwest_str->rec_max_delay_avg_Q - weight * MIN_ISAC_MD) )
619 {
620 jitterInfo[0] = 0;
621 /* update quantized average */
622 bwest_str->rec_max_delay_avg_Q =
623 (1.f - weight) * bwest_str->rec_max_delay_avg_Q + weight *
624 (float)MIN_ISAC_MD;
625 }
626 else
627 {
628 jitterInfo[0] = 1;
629 /* update quantized average */
630 bwest_str->rec_max_delay_avg_Q =
631 (1.f-weight) * bwest_str->rec_max_delay_avg_Q + weight *
632 (float)MAX_ISAC_MD;
633 }
634
635 // Get unquantized rate.
636 rate = (float)WebRtcIsac_GetDownlinkBandwidth(bwest_str);
637
638 /* Get Rate Index */
639 if(decoderSamplingFreq == kIsacWideband)
640 {
641 ptrQuantizationTable = kQRateTableWb;
642 addJitterInfo = 1;
643 maxInd = 11;
644 }
645 else
646 {
647 ptrQuantizationTable = kQRateTableSwb;
648 addJitterInfo = 0;
649 maxInd = 23;
650 }
651
652 minInd = 0;
653 while(maxInd > minInd + 1)
654 {
655 midInd = (maxInd + minInd) >> 1;
656 if(rate > ptrQuantizationTable[midInd])
657 {
658 minInd = midInd;
659 }
660 else
661 {
662 maxInd = midInd;
663 }
664 }
665 // Chose the index which gives results an average which is closest
666 // to rate
667 r = (1 - weight) * bwest_str->rec_bw_avg_Q - rate;
668 e1 = weight * ptrQuantizationTable[minInd] + r;
669 e2 = weight * ptrQuantizationTable[maxInd] + r;
670 e1 = (e1 > 0)? e1:-e1;
671 e2 = (e2 > 0)? e2:-e2;
672 if(e1 < e2)
673 {
674 bottleneckIndex[0] = minInd;
675 }
676 else
677 {
678 bottleneckIndex[0] = maxInd;
679 }
680
681 bwest_str->rec_bw_avg_Q = (1 - weight) * bwest_str->rec_bw_avg_Q +
682 weight * ptrQuantizationTable[bottleneckIndex[0]];
683 bottleneckIndex[0] += jitterInfo[0] * 12 * addJitterInfo;
684
685 bwest_str->rec_bw_avg = (1 - weight) * bwest_str->rec_bw_avg + weight *
686 (rate + bwest_str->rec_header_rate);
687
688 return 0;
689 }
690
691
692
693 /* get the bottle neck rate from far side to here, as estimated on this side */
WebRtcIsac_GetDownlinkBandwidth(const BwEstimatorstr * bwest_str)694 WebRtc_Word32 WebRtcIsac_GetDownlinkBandwidth( const BwEstimatorstr *bwest_str)
695 {
696 WebRtc_Word32 rec_bw;
697 float jitter_sign;
698 float bw_adjust;
699
700 /* create a value between -1.0 and 1.0 indicating "average sign" of jitter */
701 jitter_sign = bwest_str->rec_jitter_short_term /
702 bwest_str->rec_jitter_short_term_abs;
703
704 /* adjust bw proportionally to negative average jitter sign */
705 bw_adjust = 1.0f - jitter_sign * (0.15f + 0.15f * jitter_sign * jitter_sign);
706
707 /* adjust Rate if jitter sign is mostly constant */
708 rec_bw = (WebRtc_Word32)(bwest_str->rec_bw * bw_adjust);
709
710 /* limit range of bottle neck rate */
711 if (rec_bw < MIN_ISAC_BW)
712 {
713 rec_bw = MIN_ISAC_BW;
714 }
715 else if (rec_bw > MAX_ISAC_BW)
716 {
717 rec_bw = MAX_ISAC_BW;
718 }
719 return rec_bw;
720 }
721
722 /* Returns the max delay (in ms) */
723 WebRtc_Word32
WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr * bwest_str)724 WebRtcIsac_GetDownlinkMaxDelay(const BwEstimatorstr *bwest_str)
725 {
726 WebRtc_Word32 rec_max_delay;
727
728 rec_max_delay = (WebRtc_Word32)(bwest_str->rec_max_delay);
729
730 /* limit range of jitter estimate */
731 if (rec_max_delay < MIN_ISAC_MD)
732 {
733 rec_max_delay = MIN_ISAC_MD;
734 }
735 else if (rec_max_delay > MAX_ISAC_MD)
736 {
737 rec_max_delay = MAX_ISAC_MD;
738 }
739 return rec_max_delay;
740 }
741
742 /* get the bottle neck rate from here to far side, as estimated by far side */
743 void
WebRtcIsac_GetUplinkBandwidth(const BwEstimatorstr * bwest_str,WebRtc_Word32 * bitRate)744 WebRtcIsac_GetUplinkBandwidth(
745 const BwEstimatorstr* bwest_str,
746 WebRtc_Word32* bitRate)
747 {
748 /* limit range of bottle neck rate */
749 if (bwest_str->send_bw_avg < MIN_ISAC_BW)
750 {
751 *bitRate = MIN_ISAC_BW;
752 }
753 else if (bwest_str->send_bw_avg > MAX_ISAC_BW)
754 {
755 *bitRate = MAX_ISAC_BW;
756 }
757 else
758 {
759 *bitRate = (WebRtc_Word32)(bwest_str->send_bw_avg);
760 }
761 return;
762 }
763
764 /* Returns the max delay value from the other side in ms */
765 WebRtc_Word32
WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr * bwest_str)766 WebRtcIsac_GetUplinkMaxDelay(const BwEstimatorstr *bwest_str)
767 {
768 WebRtc_Word32 send_max_delay;
769
770 send_max_delay = (WebRtc_Word32)(bwest_str->send_max_delay_avg);
771
772 /* limit range of jitter estimate */
773 if (send_max_delay < MIN_ISAC_MD)
774 {
775 send_max_delay = MIN_ISAC_MD;
776 }
777 else if (send_max_delay > MAX_ISAC_MD)
778 {
779 send_max_delay = MAX_ISAC_MD;
780 }
781 return send_max_delay;
782 }
783
784
785 /*
786 * update long-term average bitrate and amount of data in buffer
787 * returns minimum payload size (bytes)
788 */
WebRtcIsac_GetMinBytes(RateModel * State,int StreamSize,const int FrameSamples,const double BottleNeck,const double DelayBuildUp,enum ISACBandwidth bandwidth)789 int WebRtcIsac_GetMinBytes(
790 RateModel* State,
791 int StreamSize, /* bytes in bitstream */
792 const int FrameSamples, /* samples per frame */
793 const double BottleNeck, /* bottle neck rate; excl headers (bps) */
794 const double DelayBuildUp, /* max delay from bottleneck buffering (ms) */
795 enum ISACBandwidth bandwidth
796 /*,WebRtc_Word16 frequentLargePackets*/)
797 {
798 double MinRate = 0.0;
799 int MinBytes;
800 double TransmissionTime;
801 int burstInterval = BURST_INTERVAL;
802
803 // first 10 packets @ low rate, then INIT_BURST_LEN packets @
804 // fixed rate of INIT_RATE bps
805 if (State->InitCounter > 0)
806 {
807 if (State->InitCounter-- <= INIT_BURST_LEN)
808 {
809 if(bandwidth == isac8kHz)
810 {
811 MinRate = INIT_RATE_WB;
812 }
813 else
814 {
815 MinRate = INIT_RATE_SWB;
816 }
817 }
818 else
819 {
820 MinRate = 0;
821 }
822 }
823 else
824 {
825 /* handle burst */
826 if (State->BurstCounter)
827 {
828 if (State->StillBuffered < (1.0 - 1.0/BURST_LEN) * DelayBuildUp)
829 {
830 /* max bps derived from BottleNeck and DelayBuildUp values */
831 MinRate = (1.0 + (FS/1000) * DelayBuildUp /
832 (double)(BURST_LEN * FrameSamples)) * BottleNeck;
833 }
834 else
835 {
836 // max bps derived from StillBuffered and DelayBuildUp
837 // values
838 MinRate = (1.0 + (FS/1000) * (DelayBuildUp -
839 State->StillBuffered) / (double)FrameSamples) * BottleNeck;
840 if (MinRate < 1.04 * BottleNeck)
841 {
842 MinRate = 1.04 * BottleNeck;
843 }
844 }
845 State->BurstCounter--;
846 }
847 }
848
849
850 /* convert rate from bits/second to bytes/packet */
851 MinBytes = (int) (MinRate * FrameSamples / (8.0 * FS));
852
853 /* StreamSize will be adjusted if less than MinBytes */
854 if (StreamSize < MinBytes)
855 {
856 StreamSize = MinBytes;
857 }
858
859 /* keep track of when bottle neck was last exceeded by at least 1% */
860 if (StreamSize * 8.0 * FS / FrameSamples > 1.01 * BottleNeck) {
861 if (State->PrevExceed) {
862 /* bottle_neck exceded twice in a row, decrease ExceedAgo */
863 State->ExceedAgo -= /*BURST_INTERVAL*/ burstInterval / (BURST_LEN - 1);
864 if (State->ExceedAgo < 0)
865 State->ExceedAgo = 0;
866 }
867 else
868 {
869 State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */
870 State->PrevExceed = 1;
871 }
872 }
873 else
874 {
875 State->PrevExceed = 0;
876 State->ExceedAgo += (FrameSamples * 1000) / FS; /* ms */
877 }
878
879 /* set burst flag if bottle neck not exceeded for long time */
880 if ((State->ExceedAgo > burstInterval) &&
881 (State->BurstCounter == 0))
882 {
883 if (State->PrevExceed)
884 {
885 State->BurstCounter = BURST_LEN - 1;
886 }
887 else
888 {
889 State->BurstCounter = BURST_LEN;
890 }
891 }
892
893
894 /* Update buffer delay */
895 TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck; /* ms */
896 State->StillBuffered += TransmissionTime;
897 State->StillBuffered -= (FrameSamples * 1000) / FS; /* ms */
898 if (State->StillBuffered < 0.0)
899 {
900 State->StillBuffered = 0.0;
901 }
902
903 return MinBytes;
904 }
905
906
907 /*
908 * update long-term average bitrate and amount of data in buffer
909 */
WebRtcIsac_UpdateRateModel(RateModel * State,int StreamSize,const int FrameSamples,const double BottleNeck)910 void WebRtcIsac_UpdateRateModel(
911 RateModel *State,
912 int StreamSize, /* bytes in bitstream */
913 const int FrameSamples, /* samples per frame */
914 const double BottleNeck) /* bottle neck rate; excl headers (bps) */
915 {
916 double TransmissionTime;
917
918 /* avoid the initial "high-rate" burst */
919 State->InitCounter = 0;
920
921 /* Update buffer delay */
922 TransmissionTime = StreamSize * 8.0 * 1000.0 / BottleNeck; /* ms */
923 State->StillBuffered += TransmissionTime;
924 State->StillBuffered -= (FrameSamples * 1000) / FS; /* ms */
925 if (State->StillBuffered < 0.0)
926 State->StillBuffered = 0.0;
927
928 }
929
930
WebRtcIsac_InitRateModel(RateModel * State)931 void WebRtcIsac_InitRateModel(
932 RateModel *State)
933 {
934 State->PrevExceed = 0; /* boolean */
935 State->ExceedAgo = 0; /* ms */
936 State->BurstCounter = 0; /* packets */
937 State->InitCounter = INIT_BURST_LEN + 10; /* packets */
938 State->StillBuffered = 1.0; /* ms */
939 }
940
WebRtcIsac_GetNewFrameLength(double bottle_neck,int current_framesamples)941 int WebRtcIsac_GetNewFrameLength(
942 double bottle_neck,
943 int current_framesamples)
944 {
945 int new_framesamples;
946
947 const int Thld_20_30 = 20000;
948
949 //const int Thld_30_20 = 30000;
950 const int Thld_30_20 = 1000000; // disable 20 ms frames
951
952 const int Thld_30_60 = 18000;
953 //const int Thld_30_60 = 0; // disable 60 ms frames
954
955 const int Thld_60_30 = 27000;
956
957
958 new_framesamples = current_framesamples;
959
960 /* find new framelength */
961 switch(current_framesamples) {
962 case 320:
963 if (bottle_neck < Thld_20_30)
964 new_framesamples = 480;
965 break;
966 case 480:
967 if (bottle_neck < Thld_30_60)
968 new_framesamples = 960;
969 else if (bottle_neck > Thld_30_20)
970 new_framesamples = 320;
971 break;
972 case 960:
973 if (bottle_neck >= Thld_60_30)
974 new_framesamples = 480;
975 break;
976 }
977
978 return new_framesamples;
979 }
980
WebRtcIsac_GetSnr(double bottle_neck,int framesamples)981 double WebRtcIsac_GetSnr(
982 double bottle_neck,
983 int framesamples)
984 {
985 double s2nr;
986
987 const double a_20 = -30.0;
988 const double b_20 = 0.8;
989 const double c_20 = 0.0;
990
991 const double a_30 = -23.0;
992 const double b_30 = 0.48;
993 const double c_30 = 0.0;
994
995 const double a_60 = -23.0;
996 const double b_60 = 0.53;
997 const double c_60 = 0.0;
998
999
1000 /* find new SNR value */
1001 switch(framesamples) {
1002 case 320:
1003 s2nr = a_20 + b_20 * bottle_neck * 0.001 + c_20 * bottle_neck *
1004 bottle_neck * 0.000001;
1005 break;
1006 case 480:
1007 s2nr = a_30 + b_30 * bottle_neck * 0.001 + c_30 * bottle_neck *
1008 bottle_neck * 0.000001;
1009 break;
1010 case 960:
1011 s2nr = a_60 + b_60 * bottle_neck * 0.001 + c_60 * bottle_neck *
1012 bottle_neck * 0.000001;
1013 break;
1014 default:
1015 s2nr = 0;
1016 }
1017
1018 return s2nr;
1019
1020 }
1021