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

Side by Side Diff: content/browser/renderer_host/media/audio_input_debug_writer_unittest.cc

Issue 2390153006: Audio input debug recording refactoring to reduce thread hops and simplify object ownership (Closed)
Patch Set: Created 4 years, 2 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdint.h> 5 #include <stdint.h>
6 6
7 #include "base/files/file_util.h" 7 #include "base/files/file_util.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/synchronization/waitable_event.h"
8 #include "base/sys_byteorder.h" 10 #include "base/sys_byteorder.h"
9 #include "content/browser/renderer_host/media/audio_input_debug_writer.h" 11 #include "content/browser/renderer_host/media/audio_input_debug_writer.h"
10 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
11 #include "content/public/test/test_browser_thread_bundle.h" 13 #include "content/public/test/test_browser_thread_bundle.h"
12 #include "media/base/audio_bus.h" 14 #include "media/base/audio_bus.h"
13 #include "media/base/test_helpers.h" 15 #include "media/base/test_helpers.h"
14 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
15 17
16 namespace content { 18 namespace content {
17 19
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 EXPECT_EQ(static_cast<int>(file.GetLength() - kWavHeaderSize), read); 147 EXPECT_EQ(static_cast<int>(file.GetLength() - kWavHeaderSize), read);
146 148
147 VerifyDataRecording(source_interleaved_.get(), result_interleaved.get(), 149 VerifyDataRecording(source_interleaved_.get(), result_interleaved.get(),
148 source_samples_); 150 source_samples_);
149 } 151 }
150 } 152 }
151 153
152 void TestDoneOnFileThread(const base::Closure& callback) { 154 void TestDoneOnFileThread(const base::Closure& callback) {
153 DCHECK_CURRENTLY_ON(BrowserThread::FILE); 155 DCHECK_CURRENTLY_ON(BrowserThread::FILE);
154 156
155 // |writer| must be destroyed on FILE thread.
156 input_debug_writer_.reset(nullptr);
157 callback.Run(); 157 callback.Run();
158 } 158 }
159 159
160 void DoDebugRecording(base::File file) { 160 void DoDebugRecording() {
161 if (!file.IsValid())
162 return;
163
164 input_debug_writer_.reset(
165 new AudioInputDebugWriter(std::move(file), params_));
166 // Write tasks are posted to BrowserThread::FILE. 161 // Write tasks are posted to BrowserThread::FILE.
167 for (int i = 0; i < writes_; ++i) { 162 for (int i = 0; i < writes_; ++i) {
168 std::unique_ptr<media::AudioBus> bus = media::AudioBus::Create( 163 std::unique_ptr<media::AudioBus> bus = media::AudioBus::Create(
169 params_.channels(), params_.frames_per_buffer()); 164 params_.channels(), params_.frames_per_buffer());
170 165
171 bus->FromInterleaved( 166 bus->FromInterleaved(
172 source_interleaved_.get() + 167 source_interleaved_.get() +
173 i * params_.channels() * params_.frames_per_buffer(), 168 i * params_.channels() * params_.frames_per_buffer(),
174 params_.frames_per_buffer(), kBytesPerSample); 169 params_.frames_per_buffer(), kBytesPerSample);
175 170
176 input_debug_writer_->Write(std::move(bus)); 171 input_debug_writer_->Write(std::move(bus));
177 } 172 }
173 }
178 174
175 void WaitForRecordingCompletion() {
179 media::WaitableMessageLoopEvent event; 176 media::WaitableMessageLoopEvent event;
180 177
181 // Post a task to BrowserThread::FILE indicating that all the writes are 178 // Post a task to BrowserThread::FILE indicating that all the writes are
182 // done. 179 // done.
183 BrowserThread::PostTask( 180 BrowserThread::PostTask(
184 BrowserThread::FILE, FROM_HERE, 181 BrowserThread::FILE, FROM_HERE,
185 base::Bind(&AudioInputDebugWriterTest::TestDoneOnFileThread, 182 base::Bind(&AudioInputDebugWriterTest::TestDoneOnFileThread,
186 base::Unretained(this), event.GetClosure())); 183 base::Unretained(this), event.GetClosure()));
187 184
188 // Wait for TestDoneOnFileThread() to call event's closure. 185 // Wait for TestDoneOnFileThread() to call event's closure.
189 event.RunAndWait(); 186 event.RunAndWait();
190 } 187 }
191 188
189 void RecordAndVerifyOnce() {
190 base::FilePath file_path;
191 EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
192
193 input_debug_writer_->Start(file_path);
194 EXPECT_TRUE(input_debug_writer_->IsRecording());
195
196 DoDebugRecording();
197
198 input_debug_writer_->Stop();
199 EXPECT_FALSE(input_debug_writer_->IsRecording());
200
201 WaitForRecordingCompletion();
202
203 VerifyRecording(file_path);
204
205 if (::testing::Test::HasFailure()) {
206 LOG(ERROR) << "Test failed; keeping recording(s) at ["
207 << file_path.value().c_str() << "].";
208 } else {
209 EXPECT_TRUE(base::DeleteFile(file_path, false));
210 }
211 }
212
192 protected: 213 protected:
193 TestBrowserThreadBundle thread_bundle_; 214 TestBrowserThreadBundle thread_bundle_;
194 215
195 // Writer under test. 216 // Writer under test.
196 std::unique_ptr<AudioInputDebugWriter> input_debug_writer_; 217 std::unique_ptr<AudioInputDebugWriter> input_debug_writer_;
197 218
198 // AudioBus parameters. 219 // AudioBus parameters.
199 media::AudioParameters params_; 220 media::AudioParameters params_;
200 221
201 // Number of times to write AudioBus to the file. 222 // Number of times to write AudioBus to the file.
202 int writes_; 223 int writes_;
203 224
204 // Number of samples in the source data. 225 // Number of samples in the source data.
205 int source_samples_; 226 int source_samples_;
206 227
207 // Source data. 228 // Source data.
208 std::unique_ptr<int16_t[]> source_interleaved_; 229 std::unique_ptr<int16_t[]> source_interleaved_;
209 230
210 private: 231 private:
211 DISALLOW_COPY_AND_ASSIGN(AudioInputDebugWriterTest); 232 DISALLOW_COPY_AND_ASSIGN(AudioInputDebugWriterTest);
212 }; 233 };
213 234
235 class AudioInputDebugWriterBehavioralTest : public AudioInputDebugWriterTest {};
236
214 TEST_P(AudioInputDebugWriterTest, WaveRecordingTest) { 237 TEST_P(AudioInputDebugWriterTest, WaveRecordingTest) {
238 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
239
240 RecordAndVerifyOnce();
241 }
242
243 TEST_P(AudioInputDebugWriterBehavioralTest,
244 DeletedBeforeRecordingFinishedOnFileThread) {
245 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
246
215 base::FilePath file_path; 247 base::FilePath file_path;
216 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); 248 EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
217 249
218 base::File file(file_path, 250 base::WaitableEvent* wait_for_deletion =
219 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); 251 new base::WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL,
220 EXPECT_TRUE(file.IsValid()); 252 base::WaitableEvent::InitialState::NOT_SIGNALED);
221 253
222 DoDebugRecording(std::move(file)); 254 BrowserThread::PostTask(
255 BrowserThread::FILE, FROM_HERE,
256 base::Bind(&base::WaitableEvent::Wait, base::Owned(wait_for_deletion)));
257
258 input_debug_writer_->Start(file_path);
259 EXPECT_TRUE(input_debug_writer_->IsRecording());
260
261 DoDebugRecording();
262
263 input_debug_writer_.reset();
264 wait_for_deletion->Signal();
265
266 WaitForRecordingCompletion();
223 267
224 VerifyRecording(file_path); 268 VerifyRecording(file_path);
225 269
226 if (::testing::Test::HasFailure()) { 270 if (::testing::Test::HasFailure()) {
227 LOG(ERROR) << "Test failed; keeping recording(s) at [" 271 LOG(ERROR) << "Test failed; keeping recording(s) at ["
228 << file_path.value().c_str() << "]."; 272 << file_path.value().c_str() << "].";
229 } else { 273 } else {
230 EXPECT_TRUE(base::DeleteFile(file_path, false)); 274 EXPECT_TRUE(base::DeleteFile(file_path, false));
231 } 275 }
232 } 276 }
233 277
278 TEST_P(AudioInputDebugWriterBehavioralTest, FileCreationError) {
279 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
280
281 base::FilePath file_path; // Empty file name.
282 input_debug_writer_->Start(file_path);
283 EXPECT_TRUE(input_debug_writer_->IsRecording());
284 DoDebugRecording();
285 }
286
287 TEST_P(AudioInputDebugWriterBehavioralTest, StartStopStartStop) {
288 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
289 RecordAndVerifyOnce();
290 RecordAndVerifyOnce();
291 }
292
234 INSTANTIATE_TEST_CASE_P( 293 INSTANTIATE_TEST_CASE_P(
235 AudioInputDebugWriterTest, 294 AudioInputDebugWriterTest,
236 AudioInputDebugWriterTest, 295 AudioInputDebugWriterTest,
237 // Using 10ms sframes per buffer everywhere. 296 // Using 10ms frames per buffer everywhere.
238 testing::Values( 297 testing::Values(
239 // No writes. 298 // No writes.
240 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, 299 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
241 44100, 300 44100,
242 44100 / 100, 301 44100 / 100,
243 0), 302 0),
244 // 1 write of mono. 303 // 1 write of mono.
245 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, 304 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
246 44100, 305 44100,
247 44100 / 100, 306 44100 / 100,
(...skipping 12 matching lines...) Expand all
260 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 319 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
261 44100, 320 44100,
262 44100 / 100, 321 44100 / 100,
263 100), 322 100),
264 // 15 seconds of stereo, higher rate. 323 // 15 seconds of stereo, higher rate.
265 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 324 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
266 48000, 325 48000,
267 48000 / 100, 326 48000 / 100,
268 1500))); 327 1500)));
269 328
329 INSTANTIATE_TEST_CASE_P(
330 AudioInputDebugWriterBehavioralTest,
331 AudioInputDebugWriterBehavioralTest,
332 // Using 10ms frames per buffer everywhere.
333 testing::Values(
334 // No writes.
335 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
336 44100,
337 44100 / 100,
338 100)));
339
270 } // namespace content 340 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698