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