From 1b871d07532c25d2f27e4db192cb9ce2229b1cee Mon Sep 17 00:00:00 2001 From: Sebastian Jansson Date: Tue, 12 Mar 2019 19:24:55 +0100 Subject: [PATCH] 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 Reviewed-by: Oskar Sundbom Cr-Commit-Position: refs/heads/master@{#27083} --- modules/audio_device/BUILD.gn | 3 + .../audio_device/include/test_audio_device.cc | 141 ++++++++---------- .../audio_device/include/test_audio_device.h | 6 + 3 files changed, 69 insertions(+), 81 deletions(-) diff --git a/modules/audio_device/BUILD.gn b/modules/audio_device/BUILD.gn index ef8c8866c1..e04b031b47 100644 --- a/modules/audio_device/BUILD.gn +++ b/modules/audio_device/BUILD.gn @@ -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", diff --git a/modules/audio_device/include/test_audio_device.cc b/modules/audio_device/include/test_audio_device.cc index 3cfb36f56b..9b884f0480 100644 --- a/modules/audio_device/include/test_audio_device.cc +++ b/modules/audio_device/include/test_audio_device.cc @@ -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, + TestAudioDeviceModuleImpl(TaskQueueFactory* task_queue_factory, + std::unique_ptr capturer, std::unique_ptr 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( - TestAudioDeviceModuleImpl::Run, this, "TestAudioDeviceModuleImpl", - rtc::kHighPriority); - thread_->Start(); + task_queue_ = + absl::make_unique(task_queue_factory_->CreateTaskQueue( + "TestAudioDeviceModuleImpl", TaskQueueFactory::Priority::NORMAL)); + + RepeatingTaskHandle::Start(task_queue_->Get(), [this]() { + ProcessAudio(); + return TimeDelta::us(process_interval_us_); + }); return 0; } @@ -156,71 +156,41 @@ 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_); - uint32_t new_mic_level = 0; - if (recording_buffer_.size() > 0) { - audio_callback_->RecordedDataIsAvailable( - recording_buffer_.data(), - recording_buffer_.size() / capturer_->NumChannels(), - 2 * capturer_->NumChannels(), capturer_->NumChannels(), - capturer_->SamplingFrequency(), 0, 0, 0, false, new_mic_level); - } - if (!keep_capturing) { - capturing_ = false; - done_capturing_.Set(); - } - } - if (rendering_) { - size_t samples_out = 0; - int64_t elapsed_time_ms = -1; - int64_t ntp_time_ms = -1; - 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( - playout_buffer_.data(), samples_out)); - if (!keep_rendering) { - rendering_ = false; - done_rendering_.Set(); - } - } + rtc::CritScope cs(&lock_); + if (capturing_) { + // Capture 10ms of audio. 2 bytes per sample. + const bool keep_capturing = capturer_->Capture(&recording_buffer_); + uint32_t new_mic_level = 0; + if (recording_buffer_.size() > 0) { + audio_callback_->RecordedDataIsAvailable( + recording_buffer_.data(), + recording_buffer_.size() / capturer_->NumChannels(), + 2 * capturer_->NumChannels(), capturer_->NumChannels(), + capturer_->SamplingFrequency(), 0, 0, 0, false, new_mic_level); } - 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(); - } + if (!keep_capturing) { + capturing_ = false; + done_capturing_.Set(); + } + } + if (rendering_) { + size_t samples_out = 0; + int64_t elapsed_time_ms = -1; + int64_t ntp_time_ms = -1; + 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(playout_buffer_.data(), samples_out)); + if (!keep_rendering) { + rendering_ = false; + done_rendering_.Set(); } } } - - static void Run(void* obj) { - static_cast(obj)->ProcessAudio(); - } - + TaskQueueFactory* const task_queue_factory_; const std::unique_ptr capturer_ RTC_GUARDED_BY(lock_); const std::unique_ptr renderer_ RTC_GUARDED_BY(lock_); const int64_t process_interval_us_; @@ -234,9 +204,7 @@ class TestAudioDeviceModuleImpl std::vector playout_buffer_ RTC_GUARDED_BY(lock_); rtc::BufferT recording_buffer_ RTC_GUARDED_BY(lock_); - - std::unique_ptr thread_; - bool stop_thread_ RTC_GUARDED_BY(lock_); + std::unique_ptr task_queue_; }; // A fake capturer that generates pulses with random samples between @@ -494,8 +462,19 @@ TestAudioDeviceModule::CreateTestAudioDeviceModule( std::unique_ptr capturer, std::unique_ptr renderer, float speed) { + return CreateTestAudioDeviceModule(&GlobalTaskQueueFactory(), + std::move(capturer), std::move(renderer), + speed); +} + +rtc::scoped_refptr +TestAudioDeviceModule::CreateTestAudioDeviceModule( + TaskQueueFactory* task_queue_factory, + std::unique_ptr capturer, + std::unique_ptr renderer, + float speed) { return new rtc::RefCountedObject( - std::move(capturer), std::move(renderer), speed); + task_queue_factory, std::move(capturer), std::move(renderer), speed); } std::unique_ptr diff --git a/modules/audio_device/include/test_audio_device.h b/modules/audio_device/include/test_audio_device.h index d12af8766a..1a3818ea3b 100644 --- a/modules/audio_device/include/test_audio_device.h +++ b/modules/audio_device/include/test_audio_device.h @@ -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, std::unique_ptr renderer, float speed = 1); + static rtc::scoped_refptr CreateTestAudioDeviceModule( + TaskQueueFactory* task_queue_factory, + std::unique_ptr capturer, + std::unique_ptr 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