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