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:
parent
3e86e7eec7
commit
96b951c593
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user