Make AEC3 recover more quickly for lost capture data

This CL ensures that AEC3 recovers more quickly when capture data is
lost in such a manner that the echo path, as seen by AEC3, becomes
noncausal due to the AEC3 buffer misalignment caused by the data loss.

The CL adds the assumption of a minimum echo path delay of 5 blocks
and makes the hysteresis in the delay selection one-sided.

BUG=chromium:757796, webrtc:8131

Review-Url: https://codereview.webrtc.org/2998223002
Cr-Commit-Position: refs/heads/master@{#19454}
This commit is contained in:
peah 2017-08-22 10:26:07 -07:00 committed by Commit Bot
parent 3e86e7eec7
commit 96b951c593
3 changed files with 19 additions and 11 deletions

View File

@ -63,6 +63,7 @@ constexpr size_t kDownsampledRenderBufferSize =
constexpr size_t kRenderDelayBufferSize =
(3 * kDownsampledRenderBufferSize) / (4 * kSubBlockSize);
constexpr size_t kMinEchoPathDelayBlocks = 5;
constexpr size_t kMaxApiCallsJitterBlocks = 30;
constexpr size_t kRenderTransferQueueSize = kMaxApiCallsJitterBlocks / 2;
static_assert(2 * kRenderTransferQueueSize >= kMaxApiCallsJitterBlocks,

View File

@ -112,20 +112,27 @@ void BlockProcessorImpl::ProcessCapture(
const size_t old_delay = render_buffer_->Delay();
const size_t new_delay = delay_controller_->GetDelay(
render_buffer_->GetDownsampledRenderBuffer(), (*capture_block)[0]);
render_buffer_->SetDelay(new_delay);
const size_t achieved_delay = render_buffer_->Delay();
// Inform the delay controller of the actually set delay to allow it to
// properly react to a non-feasible delay.
delay_controller_->SetDelay(achieved_delay);
bool delay_change;
if (new_delay >= kMinEchoPathDelayBlocks) {
render_buffer_->SetDelay(new_delay);
const size_t achieved_delay = render_buffer_->Delay();
delay_change = old_delay != achieved_delay || old_delay != new_delay ||
render_buffer_overrun_occurred_;
// Inform the delay controller of the actually set delay to allow it to
// properly react to a non-feasible delay.
delay_controller_->SetDelay(achieved_delay);
} else {
delay_controller_->Reset();
render_buffer_->Reset();
delay_change = true;
}
// Remove the echo from the capture signal.
echo_remover_->ProcessCapture(
delay_controller_->AlignmentHeadroomSamples(),
EchoPathVariability(echo_path_gain_change,
old_delay != achieved_delay ||
old_delay != new_delay ||
render_buffer_overrun_occurred_),
EchoPathVariability(echo_path_gain_change, delay_change),
capture_signal_saturation, render_buffer_->GetRenderBuffer(),
capture_block);

View File

@ -59,7 +59,7 @@ size_t ComputeNewBufferDelay(size_t current_delay,
size_t new_delay = std::max(echo_path_delay_blocks - kDelayHeadroomBlocks, 0);
// Add hysteresis.
if (new_delay == current_delay + 1 || new_delay + 1 == current_delay) {
if (new_delay == current_delay + 1) {
new_delay = current_delay;
}
@ -78,7 +78,7 @@ RenderDelayControllerImpl::RenderDelayControllerImpl(int sample_rate_hz)
RenderDelayControllerImpl::~RenderDelayControllerImpl() = default;
void RenderDelayControllerImpl::Reset() {
delay_ = 0;
delay_ = kMinEchoPathDelayBlocks;
blocks_since_last_delay_estimate_ = 300000;
echo_path_delay_samples_ = 0;
align_call_counter_ = 0;