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

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: review comments addressed 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
195 DoDebugRecording();
196
197 input_debug_writer_->Stop();
198
199 WaitForRecordingCompletion();
200
201 VerifyRecording(file_path);
202
203 if (::testing::Test::HasFailure()) {
204 LOG(ERROR) << "Test failed; keeping recording(s) at ["
205 << file_path.value().c_str() << "].";
206 } else {
207 EXPECT_TRUE(base::DeleteFile(file_path, false));
208 }
209 }
210
192 protected: 211 protected:
193 TestBrowserThreadBundle thread_bundle_; 212 TestBrowserThreadBundle thread_bundle_;
194 213
195 // Writer under test. 214 // Writer under test.
196 std::unique_ptr<AudioInputDebugWriter> input_debug_writer_; 215 std::unique_ptr<AudioInputDebugWriter> input_debug_writer_;
197 216
198 // AudioBus parameters. 217 // AudioBus parameters.
199 media::AudioParameters params_; 218 media::AudioParameters params_;
200 219
201 // Number of times to write AudioBus to the file. 220 // Number of times to write AudioBus to the file.
202 int writes_; 221 int writes_;
203 222
204 // Number of samples in the source data. 223 // Number of samples in the source data.
205 int source_samples_; 224 int source_samples_;
206 225
207 // Source data. 226 // Source data.
208 std::unique_ptr<int16_t[]> source_interleaved_; 227 std::unique_ptr<int16_t[]> source_interleaved_;
209 228
210 private: 229 private:
211 DISALLOW_COPY_AND_ASSIGN(AudioInputDebugWriterTest); 230 DISALLOW_COPY_AND_ASSIGN(AudioInputDebugWriterTest);
212 }; 231 };
213 232
233 class AudioInputDebugWriterBehavioralTest : public AudioInputDebugWriterTest {};
234
214 TEST_P(AudioInputDebugWriterTest, WaveRecordingTest) { 235 TEST_P(AudioInputDebugWriterTest, WaveRecordingTest) {
236 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
237
238 RecordAndVerifyOnce();
239 }
240
241 TEST_P(AudioInputDebugWriterBehavioralTest,
242 DeletedBeforeRecordingFinishedOnFileThread) {
243 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
244
215 base::FilePath file_path; 245 base::FilePath file_path;
216 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); 246 EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
217 247
218 base::File file(file_path, 248 base::WaitableEvent* wait_for_deletion =
219 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); 249 new base::WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL,
220 EXPECT_TRUE(file.IsValid()); 250 base::WaitableEvent::InitialState::NOT_SIGNALED);
221 251
222 DoDebugRecording(std::move(file)); 252 BrowserThread::PostTask(
253 BrowserThread::FILE, FROM_HERE,
254 base::Bind(&base::WaitableEvent::Wait, base::Owned(wait_for_deletion)));
255
256 input_debug_writer_->Start(file_path);
257
258 DoDebugRecording();
259
260 input_debug_writer_.reset();
261 wait_for_deletion->Signal();
262
263 WaitForRecordingCompletion();
223 264
224 VerifyRecording(file_path); 265 VerifyRecording(file_path);
225 266
226 if (::testing::Test::HasFailure()) { 267 if (::testing::Test::HasFailure()) {
227 LOG(ERROR) << "Test failed; keeping recording(s) at [" 268 LOG(ERROR) << "Test failed; keeping recording(s) at ["
228 << file_path.value().c_str() << "]."; 269 << file_path.value().c_str() << "].";
229 } else { 270 } else {
230 EXPECT_TRUE(base::DeleteFile(file_path, false)); 271 EXPECT_TRUE(base::DeleteFile(file_path, false));
231 } 272 }
232 } 273 }
233 274
275 TEST_P(AudioInputDebugWriterBehavioralTest, FileCreationError) {
276 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
277
278 base::FilePath file_path; // Empty file name.
279 input_debug_writer_->Start(file_path);
280 DoDebugRecording();
281 }
282
283 TEST_P(AudioInputDebugWriterBehavioralTest, StartStopStartStop) {
284 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
285 RecordAndVerifyOnce();
286 RecordAndVerifyOnce();
287 }
288
289 TEST_P(AudioInputDebugWriterBehavioralTest, DestroyNotStarted) {
290 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
291 input_debug_writer_.reset();
292 }
293
294 TEST_P(AudioInputDebugWriterBehavioralTest, DestroyStarted) {
295 input_debug_writer_.reset(new AudioInputDebugWriter(params_));
296 base::FilePath file_path;
297 EXPECT_TRUE(base::CreateTemporaryFile(&file_path));
298 input_debug_writer_->Start(file_path);
299 input_debug_writer_.reset();
300 }
301
234 INSTANTIATE_TEST_CASE_P( 302 INSTANTIATE_TEST_CASE_P(
235 AudioInputDebugWriterTest, 303 AudioInputDebugWriterTest,
236 AudioInputDebugWriterTest, 304 AudioInputDebugWriterTest,
237 // Using 10ms sframes per buffer everywhere. 305 // Using 10ms frames per buffer everywhere.
238 testing::Values( 306 testing::Values(
239 // No writes. 307 // No writes.
240 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, 308 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
241 44100, 309 44100,
242 44100 / 100, 310 44100 / 100,
243 0), 311 0),
244 // 1 write of mono. 312 // 1 write of mono.
245 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, 313 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
246 44100, 314 44100,
247 44100 / 100, 315 44100 / 100,
(...skipping 12 matching lines...) Expand all
260 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 328 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
261 44100, 329 44100,
262 44100 / 100, 330 44100 / 100,
263 100), 331 100),
264 // 15 seconds of stereo, higher rate. 332 // 15 seconds of stereo, higher rate.
265 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO, 333 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO,
266 48000, 334 48000,
267 48000 / 100, 335 48000 / 100,
268 1500))); 336 1500)));
269 337
338 INSTANTIATE_TEST_CASE_P(
339 AudioInputDebugWriterBehavioralTest,
340 AudioInputDebugWriterBehavioralTest,
341 // Using 10ms frames per buffer everywhere.
342 testing::Values(
343 // No writes.
344 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO,
345 44100,
346 44100 / 100,
347 100)));
348
270 } // namespace content 349 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698