Reland "Replacing rtc::Thread with task queue for TestAudioDeviceModule."

This is a reland of 1b871d07532c25d2f27e4db192cb9ce2229b1cee

Original change's description:
> Replacing rtc::Thread with task queue for TestAudioDeviceModule.
>
> This prepares for running it in simulated time.
>
> TBR=henrika@webrtc.org
>
> Bug: webrtc:10465
> Change-Id: I9b29b8af9aeba7f0c8209ca77294a63d8068ff1a
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/126481
> Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#27083}

TBR=henrika@webrtc.org

Bug: webrtc:10465
Change-Id: Icda8043fb5b1156129bc3b706bf8f190782b0921
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/127520
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27093}
This commit is contained in:
Sebastian Jansson
2019-03-13 08:50:42 +01:00
committed by Commit Bot
parent 793597b7c9
commit 77efcd82db
3 changed files with 67 additions and 81 deletions

View File

@ -203,6 +203,8 @@ rtc_source_set("audio_device_impl") {
":audio_device_generic",
"../../api:array_view",
"../../api:scoped_refptr",
"../../api/task_queue:global_task_queue_factory",
"../../api/task_queue:task_queue",
"../../common_audio",
"../../common_audio:common_audio_c",
"../../rtc_base:checks",
@ -212,6 +214,7 @@ rtc_source_set("audio_device_impl") {
"../../rtc_base:rtc_task_queue",
"../../rtc_base/system:arch",
"../../rtc_base/system:file_wrapper",
"../../rtc_base/task_utils:repeating_task",
"../../system_wrappers",
"../../system_wrappers:metrics",
"../utility",

View File

@ -18,6 +18,7 @@
#include "absl/memory/memory.h"
#include "api/array_view.h"
#include "api/task_queue/global_task_queue_factory.h"
#include "common_audio/wav_file.h"
#include "modules/audio_device/include/audio_device_default.h"
#include "modules/audio_device/include/test_audio_device.h"
@ -30,7 +31,8 @@
#include "rtc_base/platform_thread.h"
#include "rtc_base/random.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/thread.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/task_utils/repeating_task.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/time_utils.h"
@ -53,16 +55,17 @@ class TestAudioDeviceModuleImpl
// |renderer| is an object that receives audio data that would have been
// played out. Can be nullptr if this device is never used for playing.
// Use one of the Create... functions to get these instances.
TestAudioDeviceModuleImpl(std::unique_ptr<Capturer> capturer,
TestAudioDeviceModuleImpl(TaskQueueFactory* task_queue_factory,
std::unique_ptr<Capturer> capturer,
std::unique_ptr<Renderer> renderer,
float speed = 1)
: capturer_(std::move(capturer)),
: task_queue_factory_(task_queue_factory),
capturer_(std::move(capturer)),
renderer_(std::move(renderer)),
process_interval_us_(kFrameLengthUs / speed),
audio_callback_(nullptr),
rendering_(false),
capturing_(false),
stop_thread_(false) {
capturing_(false) {
auto good_sample_rate = [](int sr) {
return sr == 8000 || sr == 16000 || sr == 32000 || sr == 44100 ||
sr == 48000;
@ -82,20 +85,17 @@ class TestAudioDeviceModuleImpl
~TestAudioDeviceModuleImpl() override {
StopPlayout();
StopRecording();
if (thread_) {
{
rtc::CritScope cs(&lock_);
stop_thread_ = true;
}
thread_->Stop();
}
}
int32_t Init() override {
thread_ = absl::make_unique<rtc::PlatformThread>(
TestAudioDeviceModuleImpl::Run, this, "TestAudioDeviceModuleImpl",
rtc::kHighPriority);
thread_->Start();
task_queue_ =
absl::make_unique<rtc::TaskQueue>(task_queue_factory_->CreateTaskQueue(
"TestAudioDeviceModuleImpl", TaskQueueFactory::Priority::NORMAL));
RepeatingTaskHandle::Start(task_queue_->Get(), [this]() {
ProcessAudio();
return TimeDelta::us(process_interval_us_);
});
return 0;
}
@ -156,14 +156,7 @@ class TestAudioDeviceModuleImpl
private:
void ProcessAudio() {
int64_t time_us = rtc::TimeMicros();
bool logged_once = false;
for (;;) {
{
rtc::CritScope cs(&lock_);
if (stop_thread_) {
return;
}
if (capturing_) {
// Capture 10ms of audio. 2 bytes per sample.
const bool keep_capturing = capturer_->Capture(&recording_buffer_);
@ -187,40 +180,17 @@ class TestAudioDeviceModuleImpl
const int sampling_frequency = renderer_->SamplingFrequency();
audio_callback_->NeedMorePlayData(
SamplesPerFrame(sampling_frequency), 2 * renderer_->NumChannels(),
renderer_->NumChannels(), sampling_frequency,
playout_buffer_.data(), samples_out, &elapsed_time_ms,
&ntp_time_ms);
const bool keep_rendering =
renderer_->Render(rtc::ArrayView<const int16_t>(
playout_buffer_.data(), samples_out));
renderer_->NumChannels(), sampling_frequency, playout_buffer_.data(),
samples_out, &elapsed_time_ms, &ntp_time_ms);
const bool keep_rendering = renderer_->Render(
rtc::ArrayView<const int16_t>(playout_buffer_.data(), samples_out));
if (!keep_rendering) {
rendering_ = false;
done_rendering_.Set();
}
}
}
time_us += process_interval_us_;
int64_t time_left_us = time_us - rtc::TimeMicros();
if (time_left_us < 0) {
if (!logged_once) {
RTC_LOG(LS_ERROR) << "ProcessAudio is too slow";
logged_once = true;
}
} else {
while (time_left_us > 1000) {
if (rtc::Thread::SleepMs(time_left_us / 1000))
break;
time_left_us = time_us - rtc::TimeMicros();
}
}
}
}
static void Run(void* obj) {
static_cast<TestAudioDeviceModuleImpl*>(obj)->ProcessAudio();
}
TaskQueueFactory* const task_queue_factory_;
const std::unique_ptr<Capturer> capturer_ RTC_GUARDED_BY(lock_);
const std::unique_ptr<Renderer> renderer_ RTC_GUARDED_BY(lock_);
const int64_t process_interval_us_;
@ -234,9 +204,7 @@ class TestAudioDeviceModuleImpl
std::vector<int16_t> playout_buffer_ RTC_GUARDED_BY(lock_);
rtc::BufferT<int16_t> recording_buffer_ RTC_GUARDED_BY(lock_);
std::unique_ptr<rtc::PlatformThread> thread_;
bool stop_thread_ RTC_GUARDED_BY(lock_);
std::unique_ptr<rtc::TaskQueue> task_queue_;
};
// A fake capturer that generates pulses with random samples between
@ -494,8 +462,17 @@ TestAudioDeviceModule::CreateTestAudioDeviceModule(
std::unique_ptr<Capturer> capturer,
std::unique_ptr<Renderer> renderer,
float speed) {
return Create(&GlobalTaskQueueFactory(), std::move(capturer),
std::move(renderer), speed);
}
rtc::scoped_refptr<TestAudioDeviceModule> TestAudioDeviceModule::Create(
TaskQueueFactory* task_queue_factory,
std::unique_ptr<TestAudioDeviceModule::Capturer> capturer,
std::unique_ptr<TestAudioDeviceModule::Renderer> renderer,
float speed) {
return new rtc::RefCountedObject<TestAudioDeviceModuleImpl>(
std::move(capturer), std::move(renderer), speed);
task_queue_factory, std::move(capturer), std::move(renderer), speed);
}
std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer>

View File

@ -17,6 +17,7 @@
#include "api/array_view.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/task_queue_factory.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_device/include/audio_device_defines.h"
#include "rtc_base/buffer.h"
@ -82,6 +83,11 @@ class TestAudioDeviceModule : public AudioDeviceModule {
std::unique_ptr<Capturer> capturer,
std::unique_ptr<Renderer> renderer,
float speed = 1);
static rtc::scoped_refptr<TestAudioDeviceModule> Create(
TaskQueueFactory* task_queue_factory,
std::unique_ptr<Capturer> capturer,
std::unique_ptr<Renderer> renderer,
float speed = 1);
// Returns a Capturer instance that generates a signal of |num_channels|
// channels where every second frame is zero and every second frame is evenly