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