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

Unified Diff: webrtc/modules/audio_processing/aec3/render_delay_buffer.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 side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_processing/aec3/render_delay_buffer.cc
diff --git a/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc b/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc
index 5cb6352f741e34f46bb33d49c7567849a9d569a7..f012e00f295612596f79e42f4c41c662f5778fd6 100644
--- a/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc
+++ b/webrtc/modules/audio_processing/aec3/render_delay_buffer.cc
@@ -16,89 +16,191 @@
#include "webrtc/base/checks.h"
#include "webrtc/base/constructormagic.h"
#include "webrtc/modules/audio_processing/aec3/aec3_common.h"
+#include "webrtc/modules/audio_processing/aec3/block_processor.h"
+#include "webrtc/modules/audio_processing/aec3/decimator_by_4.h"
+#include "webrtc/modules/audio_processing/aec3/fft_data.h"
+#include "webrtc/system_wrappers/include/logging.h"
namespace webrtc {
namespace {
+class ApiCallJitterBuffer {
+ public:
+ explicit ApiCallJitterBuffer(size_t num_bands) {
+ buffer_.fill(std::vector<std::vector<float>>(
+ num_bands, std::vector<float>(kBlockSize, 0.f)));
+ }
+
+ ~ApiCallJitterBuffer() = default;
+
+ void Reset() {
+ size_ = 0;
+ last_insert_index_ = 0;
+ }
+
+ void Insert(const std::vector<std::vector<float>>& block) {
+ RTC_DCHECK_LT(size_, buffer_.size());
+ last_insert_index_ = (last_insert_index_ + 1) % buffer_.size();
+ RTC_DCHECK_EQ(buffer_[last_insert_index_].size(), block.size());
+ RTC_DCHECK_EQ(buffer_[last_insert_index_][0].size(), block[0].size());
+ for (size_t k = 0; k < block.size(); ++k) {
+ std::copy(block[k].begin(), block[k].end(),
+ buffer_[last_insert_index_][k].begin());
+ }
+ ++size_;
+ }
+
+ void Remove(std::vector<std::vector<float>>* block) {
+ RTC_DCHECK_LT(0, size_);
+ --size_;
+ const size_t extract_index =
+ (last_insert_index_ - size_ + buffer_.size()) % buffer_.size();
+ for (size_t k = 0; k < block->size(); ++k) {
+ std::copy(buffer_[extract_index][k].begin(),
+ buffer_[extract_index][k].end(), (*block)[k].begin());
+ }
+ }
+
+ size_t Size() const { return size_; }
+ bool Full() const { return size_ >= (buffer_.size()); }
+ bool Empty() const { return size_ == 0; }
+
+ private:
+ std::array<std::vector<std::vector<float>>, kMaxApiCallsJitterBlocks> buffer_;
+ size_t size_ = 0;
+ int last_insert_index_ = 0;
+};
+
class RenderDelayBufferImpl final : public RenderDelayBuffer {
public:
- RenderDelayBufferImpl(size_t size_blocks,
- size_t num_bands,
- size_t max_api_jitter_blocks);
+ explicit RenderDelayBufferImpl(size_t num_bands);
~RenderDelayBufferImpl() override;
- bool Insert(std::vector<std::vector<float>>* block) override;
- const std::vector<std::vector<float>>& GetNext() override;
+ void Reset() override;
+ bool Insert(const std::vector<std::vector<float>>& block) override;
+ bool UpdateBuffers() override;
void SetDelay(size_t delay) override;
size_t Delay() const override { return delay_; }
- size_t MaxDelay() const override {
- return buffer_.size() - max_api_jitter_blocks_;
+
+ const RenderBuffer& GetRenderBuffer() const override { return fft_buffer_; }
+
+ const DownsampledRenderBuffer& GetDownsampledRenderBuffer() const override {
+ return downsampled_render_buffer_;
}
- bool IsBlockAvailable() const override { return insert_surplus_ > 0; }
- size_t MaxApiJitter() const override { return max_api_jitter_blocks_; }
private:
- const size_t max_api_jitter_blocks_;
- std::vector<std::vector<std::vector<float>>> buffer_;
- size_t last_insert_index_ = 0;
+ const Aec3Optimization optimization_;
+ std::array<std::vector<std::vector<float>>, kRenderDelayBufferSize> buffer_;
size_t delay_ = 0;
- size_t insert_surplus_ = 0;
-
+ size_t last_insert_index_ = 0;
+ RenderBuffer fft_buffer_;
+ DownsampledRenderBuffer downsampled_render_buffer_;
+ DecimatorBy4 render_decimator_;
+ ApiCallJitterBuffer api_call_jitter_buffer_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RenderDelayBufferImpl);
};
-RenderDelayBufferImpl::RenderDelayBufferImpl(size_t size_blocks,
- size_t num_bands,
- size_t max_api_jitter_blocks)
- : max_api_jitter_blocks_(max_api_jitter_blocks),
- buffer_(size_blocks + max_api_jitter_blocks_,
- std::vector<std::vector<float>>(
+RenderDelayBufferImpl::RenderDelayBufferImpl(size_t num_bands)
+ : optimization_(DetectOptimization()),
+ fft_buffer_(optimization_,
num_bands,
- std::vector<float>(kBlockSize, 0.f))) {}
+ std::max(30, kAdaptiveFilterLength),
+ std::vector<size_t>(1, kAdaptiveFilterLength)),
+ api_call_jitter_buffer_(num_bands) {
+ buffer_.fill(std::vector<std::vector<float>>(
+ num_bands, std::vector<float>(kBlockSize, 0.f)));
+
+ RTC_DCHECK_LT(buffer_.size(), downsampled_render_buffer_.buffer.size());
+}
RenderDelayBufferImpl::~RenderDelayBufferImpl() = default;
-bool RenderDelayBufferImpl::Insert(std::vector<std::vector<float>>* block) {
- RTC_DCHECK_EQ(block->size(), buffer_[0].size());
- RTC_DCHECK_EQ((*block)[0].size(), buffer_[0][0].size());
+void RenderDelayBufferImpl::Reset() {
+ // Empty all data in the buffers.
+ delay_ = 0;
+ last_insert_index_ = 0;
+ downsampled_render_buffer_.position = 0;
+ downsampled_render_buffer_.buffer.fill(0.f);
+ fft_buffer_.Clear();
+ api_call_jitter_buffer_.Reset();
+}
+
+bool RenderDelayBufferImpl::Insert(
+ const std::vector<std::vector<float>>& block) {
+ RTC_DCHECK_EQ(block.size(), buffer_[0].size());
+ RTC_DCHECK_EQ(block[0].size(), buffer_[0][0].size());
- if (insert_surplus_ == max_api_jitter_blocks_) {
+ if (api_call_jitter_buffer_.Full()) {
+ // Report buffer overrun and let the caller handle the overrun.
return false;
}
- last_insert_index_ = (last_insert_index_ + 1) % buffer_.size();
- block->swap(buffer_[last_insert_index_]);
-
- ++insert_surplus_;
+ api_call_jitter_buffer_.Insert(block);
return true;
}
-const std::vector<std::vector<float>>& RenderDelayBufferImpl::GetNext() {
- RTC_DCHECK(IsBlockAvailable());
- const size_t extract_index_ =
- (last_insert_index_ - delay_ - insert_surplus_ + 1 + buffer_.size()) %
- buffer_.size();
- RTC_DCHECK_LE(0, extract_index_);
- RTC_DCHECK_GT(buffer_.size(), extract_index_);
+bool RenderDelayBufferImpl::UpdateBuffers() {
+ bool underrun = true;
+ // Update the buffers with a new block if such is available, otherwise repeat
+ // the previous block.
+ if (api_call_jitter_buffer_.Size() > 0) {
+ last_insert_index_ = (last_insert_index_ + 1) % buffer_.size();
+ api_call_jitter_buffer_.Remove(&buffer_[last_insert_index_]);
- RTC_DCHECK_LT(0, insert_surplus_);
- --insert_surplus_;
+ underrun = false;
+ }
- return buffer_[extract_index_];
+ downsampled_render_buffer_.position =
+ (downsampled_render_buffer_.position - kSubBlockSize +
+ downsampled_render_buffer_.buffer.size()) %
+ downsampled_render_buffer_.buffer.size();
+
+ std::array<float, kSubBlockSize> render_downsampled;
+ render_decimator_.Decimate(buffer_[last_insert_index_][0],
+ render_downsampled);
+ std::copy(render_downsampled.rbegin(), render_downsampled.rend(),
+ downsampled_render_buffer_.buffer.begin() +
+ downsampled_render_buffer_.position);
+
+ fft_buffer_.Insert(
+ buffer_[(last_insert_index_ - delay_ + buffer_.size()) % buffer_.size()]);
+ return !underrun;
}
void RenderDelayBufferImpl::SetDelay(size_t delay) {
- RTC_DCHECK_GE(MaxDelay(), delay);
- delay_ = delay;
+ if (delay_ == delay) {
+ return;
+ }
+
+ // If there is a new delay set, clear the fft buffer.
+ fft_buffer_.Clear();
+
+ const size_t max_delay = buffer_.size() - 1;
+ if (max_delay < delay) {
+ // If the desired delay is larger than the delay buffer, shorten the delay
+ // buffer size to achieve the desired alignment with the available buffer
+ // size.
+ const size_t delay_decrease = delay - max_delay;
+ RTC_DCHECK_LT(delay_decrease, buffer_.size());
+
+ downsampled_render_buffer_.position =
+ (downsampled_render_buffer_.position + kSubBlockSize * delay_decrease) %
+ downsampled_render_buffer_.buffer.size();
+
+ last_insert_index_ =
+ (last_insert_index_ + buffer_.size() - delay_decrease) % buffer_.size();
+
+ RTC_DCHECK_EQ(max_delay, delay_ - delay_decrease);
+ delay_ = max_delay;
+ } else {
+ delay_ = delay;
+ }
}
} // namespace
-RenderDelayBuffer* RenderDelayBuffer::Create(size_t size_blocks,
- size_t num_bands,
- size_t max_api_jitter_blocks) {
- return new RenderDelayBufferImpl(size_blocks, num_bands,
- max_api_jitter_blocks);
+RenderDelayBuffer* RenderDelayBuffer::Create(size_t num_bands) {
+ return new RenderDelayBufferImpl(num_bands);
}
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698