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

Side by Side Diff: third_party/WebKit/Source/platform/audio/PushPullFIFOSmokeTest.cpp

Issue 2777903005: Add WebThread in AudioDestination to support AudioWorkletThread (Closed)
Patch Set: Added Unit Test for multi-thread support 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
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "platform/audio/PushPullFIFO.h"
6
7 #include <memory>
8 #include <vector>
9 #include "platform/CrossThreadFunctional.h"
10 #include "platform/WaitableEvent.h"
11 #include "platform/WebTaskRunner.h"
12 #include "platform/audio/AudioUtilities.h"
13 #include "platform/testing/UnitTestHelpers.h"
14 #include "platform/wtf/Functional.h"
15 #include "platform/wtf/PtrUtil.h"
16 #include "public/platform/Platform.h"
17 #include "public/platform/WebThread.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace blink {
21
22 namespace {
23
24 // To forcibly stop the message loop.
25 // TODO(hongchan): move this hack into Test class.
26 void FinishTest() {
27 LOG(INFO) << "FinishTest";
28 testing::ExitRunLoop();
29 }
30
31 // To wait for spawned threads to finish their tasks.
32 // TODO(hongchan): move this hack into Test class.
33 void HoldTestForDuration(double duration_ms) {
34 LOG(INFO) << "HoldTestForDuration";
35 Platform::Current()->CurrentThread()->GetWebTaskRunner()->PostDelayedTask(
36 BLINK_FROM_HERE,
37 WTF::Bind(&FinishTest),
38 duration_ms);
39 testing::EnterRunLoop();
40 }
41
42 // Base FIFOClient with an extra thread for looping and jitter control. The
43 // child class must define a specific task to run on the thread.
44 class FIFOClient {
45 public:
46 FIFOClient(PushPullFIFO* fifo, size_t jitter_range_ms)
47 : fifo_(fifo),
48 jitter_range_ms_(jitter_range_ms),
49 client_thread_(WTF::WrapUnique(
50 Platform::Current()->CreateThread("client thread"))) {}
51
52 void Start(double duration_ms, double interval_ms) {
53 duration_ms_ = duration_ms;
54 interval_ms_ = interval_ms;
55 client_thread_->GetWebTaskRunner()->PostTask(
56 BLINK_FROM_HERE,
57 CrossThreadBind(&FIFOClient::RunTaskOnOwnThread,
58 CrossThreadUnretained(this)));
59 }
60
61 virtual void RunTask() = 0;
62 virtual void Stop() = 0;
63
64 protected:
65 RefPtr<AudioBus> bus_;
66 PushPullFIFO* fifo_;
67 double elapesd_ms_ = 0;
68
69 private:
70 void RunTaskOnOwnThread() {
71 double interval_with_jitter = interval_ms_
72 + (static_cast<double>(std::rand()) / RAND_MAX) * jitter_range_ms_;
Raymond Toy 2017/04/21 16:26:57 Maybe use std::uniform_real_distribution to genera
hongchan 2017/04/21 20:44:02 Hmm, I think the variable names quite accurate and
73 elapesd_ms_ += interval_with_jitter;
Raymond Toy 2017/04/21 16:26:57 elapesd_ms should probably be elapsed_ms
hongchan 2017/04/21 20:44:01 Done.
74 RunTask();
75 if (elapesd_ms_ < duration_ms_) {
76 client_thread_->GetWebTaskRunner()->PostDelayedTask(
77 BLINK_FROM_HERE,
78 CrossThreadBind(&FIFOClient::RunTaskOnOwnThread,
79 CrossThreadUnretained(this)),
80 interval_with_jitter);
Raymond Toy 2017/04/21 16:26:57 The documentation for PostDelayedTask says the del
hongchan 2017/04/21 20:44:02 Not sure if it would matters for anything, but thi
81 } else {
82 Stop();
83 }
84 }
85
86 double duration_ms_;
87 double interval_ms_;
88 double jitter_range_ms_;
89 std::unique_ptr<WebThread> client_thread_;
90 };
91
92 // FIFO-pulling client (consumer). This mimics the audio device thread.
93 class PullClient : public FIFOClient {
94 public:
95 PullClient(PushPullFIFO* fifo, size_t frames_to_pull, double jitter_range_ms)
96 : FIFOClient(fifo, jitter_range_ms),
97 frames_to_pull_(frames_to_pull) {
98 bus_ = AudioBus::Create(fifo_->NumberOfChannels(), frames_to_pull_);
99 }
100
101 void RunTask() override {
102 LOG(INFO) << "PullClient::RunTask (" << elapesd_ms_ << ")";
103 fifo_->Pull(bus_.Get(), frames_to_pull_);
104 }
105
106 void Stop() override {
107 LOG(INFO) << "PullClient::Stop (" << elapesd_ms_ << ")";
108 }
109
110 private:
111 size_t frames_to_pull_;
112 };
113
114 // FIFO-pushing client (producer). This mimics the WebAudio rendering thread.
115 class PushClient : public FIFOClient {
116 public:
117 PushClient(PushPullFIFO* fifo, size_t frames_to_push, double jitter_range_ms)
118 : FIFOClient(fifo, jitter_range_ms) {
119 bus_ = AudioBus::Create(fifo_->NumberOfChannels(), frames_to_push);
120 }
121
122 void RunTask() override {
123 LOG(INFO) << "PushClient::RunTask (" << elapesd_ms_ << ")";
124 fifo_->Push(bus_.Get());
125 }
126
127 void Stop() override {
128 LOG(INFO) << "PushClient::Stop (" << elapesd_ms_ << ")";
129 }
130 };
131
132 class PushPullFIFOSmokeTest : public ::testing::Test {};
133
134 // TODO(hongchan): parameterize this sample test.
135 TEST_F(PushPullFIFOSmokeTest, SmokeTest) {
136 const double sample_rate = 48000;
137 const size_t fifo_length = 8192;
138 const size_t pull_buffer_size = 1024;
139 const double pull_interval_ms = pull_buffer_size / sample_rate * 1000;
Raymond Toy 2017/04/21 16:26:57 pull_buffer_size / sample_rate * 1000 isn't exactl
hongchan 2017/04/21 20:44:02 As we discussed offline, this does not really matt
140 const double pull_jitter_range_ms = 5;
Raymond Toy 2017/04/21 16:26:57 Why 5? Please comment on valid values and reason
hongchan 2017/04/21 20:44:02 Multiple test cases with various parameters were a
141 const size_t push_buffer_size = AudioUtilities::kRenderQuantumFrames;
142 const double push_interval_ms = push_buffer_size / sample_rate * 1000;
143 const double push_jitter_range_ms = 8;
144 const unsigned number_of_channels = 2;
145
146 const double test_duration_ms = 1000;
Raymond Toy 2017/04/21 16:26:57 Is this long enough? I think this means that there
hongchan 2017/04/21 20:44:02 Multiple test cases with various parameters were a
147
148 std::unique_ptr<PushPullFIFO> test_fifo =
149 WTF::WrapUnique(new PushPullFIFO(number_of_channels, fifo_length));
150
151 std::unique_ptr<PullClient> pull_client = WTF::WrapUnique(
152 new PullClient(test_fifo.get(), pull_buffer_size, pull_jitter_range_ms));
153 std::unique_ptr<PushClient> push_client = WTF::WrapUnique(
154 new PushClient(test_fifo.get(), push_buffer_size, push_jitter_range_ms));
155
156 pull_client->Start(test_duration_ms, pull_interval_ms);
157 push_client->Start(test_duration_ms, push_interval_ms);
158
159 // Give a bit more time for clients to finish the task.
160 HoldTestForDuration(test_duration_ms + 250);
161 }
162
163 } // namespace
164
165 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698