Increase test duration to make at least one frame to come through on slow test bots and remove check in echo emulation for same purposes. Logging for echo queue should be enough. Bug: None Change-Id: I0d2d1c2a87e1a2b4cd035828443f428b0983edad Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/176300 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Commit-Queue: Artem Titov <titovartem@webrtc.org> Cr-Commit-Position: refs/heads/master@{#31377}
116 lines
3.8 KiB
C++
116 lines
3.8 KiB
C++
/*
|
|
* Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
#include "test/pc/e2e/echo/echo_emulation.h"
|
|
|
|
#include <limits>
|
|
#include <utility>
|
|
|
|
namespace webrtc {
|
|
namespace webrtc_pc_e2e {
|
|
namespace {
|
|
|
|
constexpr int kSingleBufferDurationMs = 10;
|
|
|
|
} // namespace
|
|
|
|
EchoEmulatingCapturer::EchoEmulatingCapturer(
|
|
std::unique_ptr<TestAudioDeviceModule::Capturer> capturer,
|
|
PeerConnectionE2EQualityTestFixture::EchoEmulationConfig config)
|
|
: delegate_(std::move(capturer)),
|
|
config_(config),
|
|
renderer_queue_(2 * config_.echo_delay.ms() / kSingleBufferDurationMs),
|
|
queue_input_(TestAudioDeviceModule::SamplesPerFrame(
|
|
delegate_->SamplingFrequency()) *
|
|
delegate_->NumChannels()),
|
|
queue_output_(TestAudioDeviceModule::SamplesPerFrame(
|
|
delegate_->SamplingFrequency()) *
|
|
delegate_->NumChannels()) {
|
|
renderer_thread_.Detach();
|
|
capturer_thread_.Detach();
|
|
}
|
|
|
|
void EchoEmulatingCapturer::OnAudioRendered(
|
|
rtc::ArrayView<const int16_t> data) {
|
|
RTC_DCHECK_RUN_ON(&renderer_thread_);
|
|
if (!recording_started_) {
|
|
// Because rendering can start before capturing in the beginning we can have
|
|
// a set of empty audio data frames. So we will skip them and will start
|
|
// fill the queue only after 1st non-empty audio data frame will arrive.
|
|
bool is_empty = true;
|
|
for (auto d : data) {
|
|
if (d != 0) {
|
|
is_empty = false;
|
|
break;
|
|
}
|
|
}
|
|
if (is_empty) {
|
|
return;
|
|
}
|
|
recording_started_ = true;
|
|
}
|
|
queue_input_.assign(data.begin(), data.end());
|
|
if (!renderer_queue_.Insert(&queue_input_)) {
|
|
RTC_LOG(WARNING) << "Echo queue is full";
|
|
}
|
|
}
|
|
|
|
bool EchoEmulatingCapturer::Capture(rtc::BufferT<int16_t>* buffer) {
|
|
RTC_DCHECK_RUN_ON(&capturer_thread_);
|
|
bool result = delegate_->Capture(buffer);
|
|
// Now we have to reduce input signal to avoid saturation when mixing in the
|
|
// fake echo.
|
|
for (size_t i = 0; i < buffer->size(); ++i) {
|
|
(*buffer)[i] /= 2;
|
|
}
|
|
|
|
// When we accumulated enough delay in the echo buffer we will pop from
|
|
// that buffer on each ::Capture(...) call. If the buffer become empty it
|
|
// will mean some bug, so we will crash during removing item from the queue.
|
|
if (!delay_accumulated_) {
|
|
delay_accumulated_ =
|
|
renderer_queue_.SizeAtLeast() >=
|
|
static_cast<size_t>(config_.echo_delay.ms() / kSingleBufferDurationMs);
|
|
}
|
|
|
|
if (delay_accumulated_) {
|
|
RTC_CHECK(renderer_queue_.Remove(&queue_output_));
|
|
for (size_t i = 0; i < buffer->size() && i < queue_output_.size(); ++i) {
|
|
int32_t res = (*buffer)[i] + queue_output_[i];
|
|
if (res < std::numeric_limits<int16_t>::min()) {
|
|
res = std::numeric_limits<int16_t>::min();
|
|
}
|
|
if (res > std::numeric_limits<int16_t>::max()) {
|
|
res = std::numeric_limits<int16_t>::max();
|
|
}
|
|
(*buffer)[i] = static_cast<int16_t>(res);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
EchoEmulatingRenderer::EchoEmulatingRenderer(
|
|
std::unique_ptr<TestAudioDeviceModule::Renderer> renderer,
|
|
EchoEmulatingCapturer* echo_emulating_capturer)
|
|
: delegate_(std::move(renderer)),
|
|
echo_emulating_capturer_(echo_emulating_capturer) {
|
|
RTC_DCHECK(echo_emulating_capturer_);
|
|
}
|
|
|
|
bool EchoEmulatingRenderer::Render(rtc::ArrayView<const int16_t> data) {
|
|
if (data.size() > 0) {
|
|
echo_emulating_capturer_->OnAudioRendered(data);
|
|
}
|
|
return delegate_->Render(data);
|
|
}
|
|
|
|
} // namespace webrtc_pc_e2e
|
|
} // namespace webrtc
|