22
22
#include " modules/audio_coding/neteq/histogram.h"
23
23
#include " modules/include/module_common_types_public.h"
24
24
#include " rtc_base/checks.h"
25
+ #include " rtc_base/experiments/struct_parameters_parser.h"
25
26
#include " rtc_base/logging.h"
26
27
#include " rtc_base/numerics/safe_conversions.h"
27
28
#include " rtc_base/numerics/safe_minmax.h"
@@ -32,29 +33,34 @@ namespace {
32
33
33
34
constexpr int kMinBaseMinimumDelayMs = 0 ;
34
35
constexpr int kMaxBaseMinimumDelayMs = 10000 ;
35
- constexpr int kMaxHistoryMs = 2000 ; // Oldest packet to include in history to
36
- // calculate relative packet arrival delay.
37
36
constexpr int kDelayBuckets = 100 ;
38
37
constexpr int kBucketSizeMs = 20 ;
39
38
constexpr int kStartDelayMs = 80 ;
40
39
constexpr int kMaxNumReorderedPackets = 5 ;
41
40
42
- int PercentileToQuantile (double percentile) {
43
- return static_cast <int >((1 << 30 ) * percentile / 100.0 + 0.5 );
44
- }
45
-
46
- struct DelayHistogramConfig {
47
- int quantile = 1041529569 ; // 0.97 in Q30.
48
- int forget_factor = 32745 ; // 0.9993 in Q15.
41
+ struct DelayManagerConfig {
42
+ double quantile = 0.97 ;
43
+ double forget_factor = 0.9993 ;
49
44
absl::optional<double > start_forget_weight = 2 ;
50
- };
45
+ absl::optional<int > resample_interval_ms;
46
+ int max_history_ms = 2000 ;
47
+
48
+ std::unique_ptr<webrtc::StructParametersParser> Parser () {
49
+ return webrtc::StructParametersParser::Create ( //
50
+ " quantile" , &quantile, //
51
+ " forget_factor" , &forget_factor, //
52
+ " start_forget_weight" , &start_forget_weight, //
53
+ " resample_interval_ms" , &resample_interval_ms, //
54
+ " max_history_ms" , &max_history_ms);
55
+ }
51
56
52
- // TODO(jakobi): Remove legacy field trial.
53
- DelayHistogramConfig GetDelayHistogramConfig () {
54
- constexpr char kDelayHistogramFieldTrial [] =
55
- " WebRTC-Audio-NetEqDelayHistogram" ;
56
- DelayHistogramConfig config;
57
- if (webrtc::field_trial::IsEnabled (kDelayHistogramFieldTrial )) {
57
+ // TODO(jakobi): remove legacy field trial.
58
+ void MaybeUpdateFromLegacyFieldTrial () {
59
+ constexpr char kDelayHistogramFieldTrial [] =
60
+ " WebRTC-Audio-NetEqDelayHistogram" ;
61
+ if (!webrtc::field_trial::IsEnabled (kDelayHistogramFieldTrial )) {
62
+ return ;
63
+ }
58
64
const auto field_trial_string =
59
65
webrtc::field_trial::FindFullName (kDelayHistogramFieldTrial );
60
66
double percentile = -1.0 ;
@@ -64,34 +70,45 @@ DelayHistogramConfig GetDelayHistogramConfig() {
64
70
&forget_factor, &start_forget_weight) >= 2 &&
65
71
percentile >= 0.0 && percentile <= 100.0 && forget_factor >= 0.0 &&
66
72
forget_factor <= 1.0 ) {
67
- config. quantile = PercentileToQuantile ( percentile) ;
68
- config. forget_factor = ( 1 << 15 ) * forget_factor;
69
- config. start_forget_weight =
70
- start_forget_weight >= 1 ? absl::make_optional (start_forget_weight)
71
- : absl::nullopt;
73
+ this -> quantile = percentile / 100 ;
74
+ this -> forget_factor = forget_factor;
75
+ this -> start_forget_weight = start_forget_weight >= 1
76
+ ? absl::make_optional (start_forget_weight)
77
+ : absl::nullopt;
72
78
}
73
79
}
74
- RTC_LOG (LS_INFO) << " Delay histogram config:"
75
- " quantile="
76
- << config.quantile
77
- << " forget_factor=" << config.forget_factor
78
- << " start_forget_weight="
79
- << config.start_forget_weight .value_or (0 );
80
- return config;
81
- }
80
+
81
+ explicit DelayManagerConfig () {
82
+ Parser ()->Parse (webrtc::field_trial::FindFullName (
83
+ " WebRTC-Audio-NetEqDelayManagerConfig" ));
84
+ MaybeUpdateFromLegacyFieldTrial ();
85
+ RTC_LOG (LS_INFO) << " Delay manager config:"
86
+ " quantile="
87
+ << quantile << " forget_factor=" << forget_factor
88
+ << " start_forget_weight="
89
+ << start_forget_weight.value_or (0 )
90
+ << " resample_interval_ms="
91
+ << resample_interval_ms.value_or (0 )
92
+ << " max_history_ms=" << max_history_ms;
93
+ }
94
+ };
82
95
83
96
} // namespace
84
97
85
98
DelayManager::DelayManager (int max_packets_in_buffer,
86
99
int base_minimum_delay_ms,
87
100
int histogram_quantile,
101
+ absl::optional<int > resample_interval_ms,
102
+ int max_history_ms,
88
103
const TickTimer* tick_timer,
89
104
std::unique_ptr<Histogram> histogram)
90
105
: first_packet_received_(false ),
91
106
max_packets_in_buffer_ (max_packets_in_buffer),
92
107
histogram_(std::move(histogram)),
93
108
histogram_quantile_(histogram_quantile),
94
109
tick_timer_(tick_timer),
110
+ resample_interval_ms_(resample_interval_ms),
111
+ max_history_ms_(max_history_ms),
95
112
base_minimum_delay_ms_(base_minimum_delay_ms),
96
113
effective_minimum_delay_ms_(base_minimum_delay_ms),
97
114
minimum_delay_ms_(0 ),
@@ -108,12 +125,15 @@ std::unique_ptr<DelayManager> DelayManager::Create(
108
125
int max_packets_in_buffer,
109
126
int base_minimum_delay_ms,
110
127
const TickTimer* tick_timer) {
111
- auto config = GetDelayHistogramConfig ();
128
+ DelayManagerConfig config;
129
+ int forget_factor_q15 = (1 << 15 ) * config.forget_factor ;
130
+ int quantile_q30 = (1 << 30 ) * config.quantile ;
112
131
std::unique_ptr<Histogram> histogram = std::make_unique<Histogram>(
113
- kDelayBuckets , config.forget_factor , config.start_forget_weight );
114
- return std::make_unique<DelayManager>(max_packets_in_buffer,
115
- base_minimum_delay_ms, config.quantile ,
116
- tick_timer, std::move (histogram));
132
+ kDelayBuckets , forget_factor_q15, config.start_forget_weight );
133
+ return std::make_unique<DelayManager>(
134
+ max_packets_in_buffer, base_minimum_delay_ms, quantile_q30,
135
+ config.resample_interval_ms , config.max_history_ms , tick_timer,
136
+ std::move (histogram));
117
137
}
118
138
119
139
DelayManager::~DelayManager () {}
@@ -132,26 +152,45 @@ absl::optional<int> DelayManager::Update(uint32_t timestamp,
132
152
last_timestamp_ = timestamp;
133
153
first_packet_received_ = true ;
134
154
num_reordered_packets_ = 0 ;
155
+ resample_stopwatch_ = tick_timer_->GetNewStopwatch ();
156
+ max_delay_in_interval_ms_ = 0 ;
135
157
return absl::nullopt;
136
158
}
137
159
138
160
const int expected_iat_ms =
139
161
1000 * static_cast <int32_t >(timestamp - last_timestamp_) / sample_rate_hz;
140
162
const int iat_ms = packet_iat_stopwatch_->ElapsedMs ();
141
163
const int iat_delay_ms = iat_ms - expected_iat_ms;
142
- absl::optional< int > relative_delay;
164
+ int relative_delay;
143
165
bool reordered = !IsNewerTimestamp (timestamp, last_timestamp_);
144
166
if (reordered) {
145
167
relative_delay = std::max (iat_delay_ms, 0 );
146
168
} else {
147
169
UpdateDelayHistory (iat_delay_ms, timestamp, sample_rate_hz);
148
170
relative_delay = CalculateRelativePacketArrivalDelay ();
149
171
}
150
- const int index = relative_delay.value () / kBucketSizeMs ;
151
- if (index < histogram_->NumBuckets ()) {
152
- // Maximum delay to register is 2000 ms.
153
- histogram_->Add (index);
172
+
173
+ absl::optional<int > histogram_update;
174
+ if (resample_interval_ms_) {
175
+ if (static_cast <int >(resample_stopwatch_->ElapsedMs ()) >
176
+ *resample_interval_ms_) {
177
+ histogram_update = max_delay_in_interval_ms_;
178
+ resample_stopwatch_ = tick_timer_->GetNewStopwatch ();
179
+ max_delay_in_interval_ms_ = 0 ;
180
+ }
181
+ max_delay_in_interval_ms_ =
182
+ std::max (max_delay_in_interval_ms_, relative_delay);
183
+ } else {
184
+ histogram_update = relative_delay;
154
185
}
186
+ if (histogram_update) {
187
+ const int index = *histogram_update / kBucketSizeMs ;
188
+ if (index < histogram_->NumBuckets ()) {
189
+ // Maximum delay to register is 2000 ms.
190
+ histogram_->Add (index);
191
+ }
192
+ }
193
+
155
194
// Calculate new |target_level_ms_| based on updated statistics.
156
195
int bucket_index = histogram_->Quantile (histogram_quantile_);
157
196
target_level_ms_ = (1 + bucket_index) * kBucketSizeMs ;
@@ -191,7 +230,7 @@ void DelayManager::UpdateDelayHistory(int iat_delay_ms,
191
230
delay.timestamp = timestamp;
192
231
delay_history_.push_back (delay);
193
232
while (timestamp - delay_history_.front ().timestamp >
194
- static_cast <uint32_t >(kMaxHistoryMs * sample_rate_hz / 1000 )) {
233
+ static_cast <uint32_t >(max_history_ms_ * sample_rate_hz / 1000 )) {
195
234
delay_history_.pop_front ();
196
235
}
197
236
}
@@ -226,6 +265,8 @@ void DelayManager::Reset() {
226
265
packet_iat_stopwatch_ = tick_timer_->GetNewStopwatch ();
227
266
first_packet_received_ = false ;
228
267
num_reordered_packets_ = 0 ;
268
+ resample_stopwatch_ = tick_timer_->GetNewStopwatch ();
269
+ max_delay_in_interval_ms_ = 0 ;
229
270
}
230
271
231
272
int DelayManager::TargetDelayMs () const {
0 commit comments