Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(786)

Side by Side Diff: webrtc/modules/audio_processing/aec3/block_processor.cc

Issue 2784023002: Major AEC3 render pipeline changes (Closed)
Patch Set: Disabled one more DEATH test that caused issues due to bug on bots Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 #include "webrtc/modules/audio_processing/aec3/block_processor.h" 10 #include "webrtc/modules/audio_processing/aec3/block_processor.h"
11 11
12 #include "webrtc/base/atomicops.h" 12 #include "webrtc/base/atomicops.h"
13 #include "webrtc/base/constructormagic.h" 13 #include "webrtc/base/constructormagic.h"
14 #include "webrtc/base/optional.h" 14 #include "webrtc/base/optional.h"
15 #include "webrtc/modules/audio_processing/aec3/aec3_common.h" 15 #include "webrtc/modules/audio_processing/aec3/aec3_common.h"
16 #include "webrtc/modules/audio_processing/aec3/block_processor_metrics.h" 16 #include "webrtc/modules/audio_processing/aec3/block_processor_metrics.h"
17 #include "webrtc/modules/audio_processing/aec3/echo_path_variability.h" 17 #include "webrtc/modules/audio_processing/aec3/echo_path_variability.h"
18 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" 18 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h"
19 19
20 namespace webrtc { 20 namespace webrtc {
21 namespace { 21 namespace {
22 22
23 enum class BlockProcessorApiCall { kCapture, kRender };
24
23 class BlockProcessorImpl final : public BlockProcessor { 25 class BlockProcessorImpl final : public BlockProcessor {
24 public: 26 public:
25 BlockProcessorImpl(int sample_rate_hz, 27 BlockProcessorImpl(int sample_rate_hz,
26 std::unique_ptr<RenderDelayBuffer> render_buffer, 28 std::unique_ptr<RenderDelayBuffer> render_buffer,
27 std::unique_ptr<RenderDelayController> delay_controller, 29 std::unique_ptr<RenderDelayController> delay_controller,
28 std::unique_ptr<EchoRemover> echo_remover); 30 std::unique_ptr<EchoRemover> echo_remover);
29 31
30 ~BlockProcessorImpl() override; 32 ~BlockProcessorImpl() override;
31 33
32 void ProcessCapture(bool echo_path_gain_change, 34 void ProcessCapture(bool echo_path_gain_change,
33 bool capture_signal_saturation, 35 bool capture_signal_saturation,
34 std::vector<std::vector<float>>* capture_block) override; 36 std::vector<std::vector<float>>* capture_block) override;
35 37
36 bool BufferRender(std::vector<std::vector<float>>* block) override; 38 void BufferRender(const std::vector<std::vector<float>>& block) override;
37 39
38 void UpdateEchoLeakageStatus(bool leakage_detected) override; 40 void UpdateEchoLeakageStatus(bool leakage_detected) override;
39 41
40 private: 42 private:
41 static int instance_count_; 43 static int instance_count_;
44 bool no_capture_data_received_ = true;
45 bool no_render_data_received_ = true;
42 std::unique_ptr<ApmDataDumper> data_dumper_; 46 std::unique_ptr<ApmDataDumper> data_dumper_;
43 const size_t sample_rate_hz_; 47 const size_t sample_rate_hz_;
44 std::unique_ptr<RenderDelayBuffer> render_buffer_; 48 std::unique_ptr<RenderDelayBuffer> render_buffer_;
45 std::unique_ptr<RenderDelayController> delay_controller_; 49 std::unique_ptr<RenderDelayController> delay_controller_;
46 std::unique_ptr<EchoRemover> echo_remover_; 50 std::unique_ptr<EchoRemover> echo_remover_;
47 BlockProcessorMetrics metrics_; 51 BlockProcessorMetrics metrics_;
52 bool render_buffer_overrun_occurred_ = false;
48 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl); 53 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(BlockProcessorImpl);
49 }; 54 };
50 55
51 constexpr size_t kRenderBufferSize = 250;
52 int BlockProcessorImpl::instance_count_ = 0; 56 int BlockProcessorImpl::instance_count_ = 0;
53 constexpr size_t kMaxApiJitter = 30;
54 57
55 BlockProcessorImpl::BlockProcessorImpl( 58 BlockProcessorImpl::BlockProcessorImpl(
56 int sample_rate_hz, 59 int sample_rate_hz,
57 std::unique_ptr<RenderDelayBuffer> render_buffer, 60 std::unique_ptr<RenderDelayBuffer> render_buffer,
58 std::unique_ptr<RenderDelayController> delay_controller, 61 std::unique_ptr<RenderDelayController> delay_controller,
59 std::unique_ptr<EchoRemover> echo_remover) 62 std::unique_ptr<EchoRemover> echo_remover)
60 : data_dumper_( 63 : data_dumper_(
61 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))), 64 new ApmDataDumper(rtc::AtomicOps::Increment(&instance_count_))),
62 sample_rate_hz_(sample_rate_hz), 65 sample_rate_hz_(sample_rate_hz),
63 render_buffer_(std::move(render_buffer)), 66 render_buffer_(std::move(render_buffer)),
64 delay_controller_(std::move(delay_controller)), 67 delay_controller_(std::move(delay_controller)),
65 echo_remover_(std::move(echo_remover)) { 68 echo_remover_(std::move(echo_remover)) {
66 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_)); 69 RTC_DCHECK(ValidFullBandRate(sample_rate_hz_));
67 } 70 }
68 71
69 BlockProcessorImpl::~BlockProcessorImpl() = default; 72 BlockProcessorImpl::~BlockProcessorImpl() = default;
70 73
71 void BlockProcessorImpl::ProcessCapture( 74 void BlockProcessorImpl::ProcessCapture(
72 bool echo_path_gain_change, 75 bool echo_path_gain_change,
73 bool capture_signal_saturation, 76 bool capture_signal_saturation,
74 std::vector<std::vector<float>>* capture_block) { 77 std::vector<std::vector<float>>* capture_block) {
75 RTC_DCHECK(capture_block); 78 RTC_DCHECK(capture_block);
76 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size()); 79 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), capture_block->size());
77 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size()); 80 RTC_DCHECK_EQ(kBlockSize, (*capture_block)[0].size());
81 data_dumper_->DumpRaw("aec3_processblock_call_order",
82 static_cast<int>(BlockProcessorApiCall::kCapture));
83 data_dumper_->DumpWav("aec3_processblock_capture_input", kBlockSize,
84 &(*capture_block)[0][0],
85 LowestBandRate(sample_rate_hz_), 1);
78 86
79 const size_t delay = delay_controller_->GetDelay((*capture_block)[0]); 87 // Do not start processing until render data has been buffered as that will
80 const bool render_delay_change = delay != render_buffer_->Delay(); 88 // cause the buffers to be wrongly aligned.
81 89 no_capture_data_received_ = false;
82 if (render_delay_change) { 90 if (no_render_data_received_) {
83 render_buffer_->SetDelay(delay); 91 return;
84 } 92 }
85 93
86 if (render_buffer_->IsBlockAvailable()) { 94 data_dumper_->DumpWav("aec3_processblock_capture_input2", kBlockSize,
87 auto& render_block = render_buffer_->GetNext(); 95 &(*capture_block)[0][0],
88 echo_remover_->ProcessBlock( 96 LowestBandRate(sample_rate_hz_), 1);
97
98 bool render_buffer_underrun = false;
99 if (render_buffer_overrun_occurred_) {
100 // Reset the render buffers and the alignment functionality when there has
101 // been a render buffer overrun as the buffer alignment may be noncausal.
102 delay_controller_->Reset();
103 render_buffer_->Reset();
104 } else {
105 // Update the render buffers with new render data, filling the buffers with
106 // empty blocks when there is no render data available.
107 render_buffer_underrun = !render_buffer_->UpdateBuffers();
108
109 // Compute and and apply the render delay required to achieve proper signal
110 // alignment.
111 const size_t old_delay = render_buffer_->Delay();
112 const size_t new_delay = delay_controller_->GetDelay(
113 render_buffer_->GetDownsampledRenderBuffer(), (*capture_block)[0]);
114 render_buffer_->SetDelay(new_delay);
115 const size_t achieved_delay = render_buffer_->Delay();
116
117 // Inform the delay controller of the actually set delay to allow it to
118 // properly react to a non-feasible delay.
119 delay_controller_->SetDelay(achieved_delay);
120
121 // Remove the echo from the capture signal.
122 echo_remover_->ProcessCapture(
89 delay_controller_->AlignmentHeadroomSamples(), 123 delay_controller_->AlignmentHeadroomSamples(),
90 EchoPathVariability(echo_path_gain_change, render_delay_change), 124 EchoPathVariability(echo_path_gain_change,
91 capture_signal_saturation, render_block, capture_block); 125 old_delay != achieved_delay ||
92 metrics_.UpdateCapture(false); 126 old_delay != new_delay ||
93 } else { 127 render_buffer_overrun_occurred_),
94 metrics_.UpdateCapture(true); 128 capture_signal_saturation, render_buffer_->GetRenderBuffer(),
129 capture_block);
95 } 130 }
131
132 // Update the metrics.
133 metrics_.UpdateCapture(render_buffer_underrun);
134
135 render_buffer_overrun_occurred_ = false;
96 } 136 }
97 137
98 bool BlockProcessorImpl::BufferRender(std::vector<std::vector<float>>* block) { 138 void BlockProcessorImpl::BufferRender(
99 RTC_DCHECK(block); 139 const std::vector<std::vector<float>>& block) {
100 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block->size()); 140 RTC_DCHECK_EQ(NumBandsForRate(sample_rate_hz_), block.size());
101 RTC_DCHECK_EQ(kBlockSize, (*block)[0].size()); 141 RTC_DCHECK_EQ(kBlockSize, block[0].size());
142 data_dumper_->DumpRaw("aec3_processblock_call_order",
143 static_cast<int>(BlockProcessorApiCall::kRender));
144 data_dumper_->DumpWav("aec3_processblock_render_input", kBlockSize,
145 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
102 146
103 const bool delay_controller_overrun = 147 no_render_data_received_ = false;
104 !delay_controller_->AnalyzeRender((*block)[0]); 148
105 const bool render_buffer_overrun = !render_buffer_->Insert(block); 149 // Do not start buffer render data until capture data has been received as
106 if (delay_controller_overrun || render_buffer_overrun) { 150 // that data may give a false alignment.
107 metrics_.UpdateRender(true); 151 if (no_capture_data_received_) {
108 return false; 152 return;
109 } 153 }
110 metrics_.UpdateRender(false); 154
111 return true; 155 data_dumper_->DumpWav("aec3_processblock_render_input2", kBlockSize,
156 &block[0][0], LowestBandRate(sample_rate_hz_), 1);
157
158 // Buffer the render data.
159 render_buffer_overrun_occurred_ = !render_buffer_->Insert(block);
160
161 // Update the metrics.
162 metrics_.UpdateRender(render_buffer_overrun_occurred_);
112 } 163 }
113 164
114 void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) { 165 void BlockProcessorImpl::UpdateEchoLeakageStatus(bool leakage_detected) {
115 echo_remover_->UpdateEchoLeakageStatus(leakage_detected); 166 echo_remover_->UpdateEchoLeakageStatus(leakage_detected);
116 } 167 }
117 168
118 } // namespace 169 } // namespace
119 170
120 BlockProcessor* BlockProcessor::Create(int sample_rate_hz) { 171 BlockProcessor* BlockProcessor::Create(int sample_rate_hz) {
121 std::unique_ptr<RenderDelayBuffer> render_buffer(RenderDelayBuffer::Create( 172 std::unique_ptr<RenderDelayBuffer> render_buffer(
122 kRenderBufferSize, NumBandsForRate(sample_rate_hz), kMaxApiJitter)); 173 RenderDelayBuffer::Create(NumBandsForRate(sample_rate_hz)));
123 std::unique_ptr<RenderDelayController> delay_controller( 174 std::unique_ptr<RenderDelayController> delay_controller(
124 RenderDelayController::Create(sample_rate_hz, *render_buffer)); 175 RenderDelayController::Create(sample_rate_hz));
125 std::unique_ptr<EchoRemover> echo_remover( 176 std::unique_ptr<EchoRemover> echo_remover(
126 EchoRemover::Create(sample_rate_hz)); 177 EchoRemover::Create(sample_rate_hz));
127 return Create(sample_rate_hz, std::move(render_buffer), 178 return Create(sample_rate_hz, std::move(render_buffer),
128 std::move(delay_controller), std::move(echo_remover)); 179 std::move(delay_controller), std::move(echo_remover));
129 } 180 }
130 181
131 BlockProcessor* BlockProcessor::Create( 182 BlockProcessor* BlockProcessor::Create(
132 int sample_rate_hz, 183 int sample_rate_hz,
133 std::unique_ptr<RenderDelayBuffer> render_buffer) { 184 std::unique_ptr<RenderDelayBuffer> render_buffer) {
134 std::unique_ptr<RenderDelayController> delay_controller( 185 std::unique_ptr<RenderDelayController> delay_controller(
135 RenderDelayController::Create(sample_rate_hz, *render_buffer)); 186 RenderDelayController::Create(sample_rate_hz));
136 std::unique_ptr<EchoRemover> echo_remover( 187 std::unique_ptr<EchoRemover> echo_remover(
137 EchoRemover::Create(sample_rate_hz)); 188 EchoRemover::Create(sample_rate_hz));
138 return Create(sample_rate_hz, std::move(render_buffer), 189 return Create(sample_rate_hz, std::move(render_buffer),
139 std::move(delay_controller), std::move(echo_remover)); 190 std::move(delay_controller), std::move(echo_remover));
140 } 191 }
141 192
142 BlockProcessor* BlockProcessor::Create( 193 BlockProcessor* BlockProcessor::Create(
143 int sample_rate_hz, 194 int sample_rate_hz,
144 std::unique_ptr<RenderDelayBuffer> render_buffer, 195 std::unique_ptr<RenderDelayBuffer> render_buffer,
145 std::unique_ptr<RenderDelayController> delay_controller, 196 std::unique_ptr<RenderDelayController> delay_controller,
146 std::unique_ptr<EchoRemover> echo_remover) { 197 std::unique_ptr<EchoRemover> echo_remover) {
147 return new BlockProcessorImpl(sample_rate_hz, std::move(render_buffer), 198 return new BlockProcessorImpl(sample_rate_hz, std::move(render_buffer),
148 std::move(delay_controller), 199 std::move(delay_controller),
149 std::move(echo_remover)); 200 std::move(echo_remover));
150 } 201 }
151 202
152 } // namespace webrtc 203 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698