AEC3: Redesign delay headroom
This change reduces the risk of echo due to noise in the headroom of the linear filter. Changes: - Use shorter delay headroom - Delay headroom is specified in samples (not blocks) - No hysteresis limit when delay is reduced Bug: chromium:119942,webrtc:10341 Change-Id: I708e80e26d541dff8ca04b6da2d346a1d59cbfcb Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/126420 Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org> Reviewed-by: Sam Zackrisson <saza@webrtc.org> Reviewed-by: Per Åhgren <peah@webrtc.org> Reviewed-by: Jesus de Vicente Pena <devicentepena@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27126}
This commit is contained in:
committed by
Commit Bot
parent
41f9f2cc57
commit
9249fbf3a6
@ -46,9 +46,8 @@ class RenderDelayControllerImpl final : public RenderDelayController {
|
||||
private:
|
||||
static int instance_count_;
|
||||
std::unique_ptr<ApmDataDumper> data_dumper_;
|
||||
const int delay_headroom_blocks_;
|
||||
const int hysteresis_limit_1_blocks_;
|
||||
const int hysteresis_limit_2_blocks_;
|
||||
const int hysteresis_limit_blocks_;
|
||||
const int delay_headroom_samples_;
|
||||
absl::optional<DelayEstimate> delay_;
|
||||
EchoPathDelayEstimator delay_estimator_;
|
||||
RenderDelayControllerMetrics metrics_;
|
||||
@ -61,32 +60,22 @@ class RenderDelayControllerImpl final : public RenderDelayController {
|
||||
|
||||
DelayEstimate ComputeBufferDelay(
|
||||
const absl::optional<DelayEstimate>& current_delay,
|
||||
int delay_headroom_blocks,
|
||||
int hysteresis_limit_1_blocks,
|
||||
int hysteresis_limit_2_blocks,
|
||||
int hysteresis_limit_blocks,
|
||||
int delay_headroom_samples,
|
||||
DelayEstimate estimated_delay) {
|
||||
// The below division is not exact and the truncation is intended.
|
||||
const int echo_path_delay_blocks = estimated_delay.delay >> kBlockSizeLog2;
|
||||
// Subtract delay headroom.
|
||||
const int delay_with_headroom_samples = std::max(
|
||||
static_cast<int>(estimated_delay.delay) - delay_headroom_samples, 0);
|
||||
|
||||
// Compute the buffer delay increase required to achieve the desired latency.
|
||||
size_t new_delay_blocks =
|
||||
std::max(echo_path_delay_blocks - delay_headroom_blocks, 0);
|
||||
size_t new_delay_blocks = delay_with_headroom_samples >> kBlockSizeLog2;
|
||||
|
||||
// Add hysteresis.
|
||||
if (current_delay) {
|
||||
size_t current_delay_blocks = current_delay->delay;
|
||||
if (new_delay_blocks > current_delay_blocks) {
|
||||
if (new_delay_blocks <=
|
||||
current_delay_blocks + hysteresis_limit_1_blocks) {
|
||||
new_delay_blocks = current_delay_blocks;
|
||||
}
|
||||
} else if (new_delay_blocks < current_delay_blocks) {
|
||||
size_t hysteresis_limit = std::max(
|
||||
static_cast<int>(current_delay_blocks) - hysteresis_limit_2_blocks,
|
||||
0);
|
||||
if (new_delay_blocks >= hysteresis_limit) {
|
||||
new_delay_blocks = current_delay_blocks;
|
||||
}
|
||||
if (new_delay_blocks > current_delay_blocks &&
|
||||
new_delay_blocks <= current_delay_blocks + hysteresis_limit_blocks) {
|
||||
new_delay_blocks = current_delay_blocks;
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,12 +91,9 @@ RenderDelayControllerImpl::RenderDelayControllerImpl(
|
||||
int sample_rate_hz)
|
||||
: data_dumper_(
|
||||
new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
|
||||
delay_headroom_blocks_(
|
||||
static_cast<int>(config.delay.delay_headroom_blocks)),
|
||||
hysteresis_limit_1_blocks_(
|
||||
static_cast<int>(config.delay.hysteresis_limit_1_blocks)),
|
||||
hysteresis_limit_2_blocks_(
|
||||
static_cast<int>(config.delay.hysteresis_limit_2_blocks)),
|
||||
hysteresis_limit_blocks_(
|
||||
static_cast<int>(config.delay.hysteresis_limit_blocks)),
|
||||
delay_headroom_samples_(config.delay.delay_headroom_samples),
|
||||
delay_estimator_(data_dumper_.get(), config),
|
||||
last_delay_estimate_quality_(DelayEstimate::Quality::kCoarse) {
|
||||
RTC_DCHECK(ValidFullBandRate(sample_rate_hz));
|
||||
@ -177,10 +163,9 @@ absl::optional<DelayEstimate> RenderDelayControllerImpl::GetDelay(
|
||||
const bool use_hysteresis =
|
||||
last_delay_estimate_quality_ == DelayEstimate::Quality::kRefined &&
|
||||
delay_samples_->quality == DelayEstimate::Quality::kRefined;
|
||||
delay_ = ComputeBufferDelay(delay_, delay_headroom_blocks_,
|
||||
use_hysteresis ? hysteresis_limit_1_blocks_ : 0,
|
||||
use_hysteresis ? hysteresis_limit_2_blocks_ : 0,
|
||||
*delay_samples_);
|
||||
delay_ = ComputeBufferDelay(delay_,
|
||||
use_hysteresis ? hysteresis_limit_blocks_ : 0,
|
||||
delay_headroom_samples_, *delay_samples_);
|
||||
last_delay_estimate_quality_ = delay_samples_->quality;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user