| OLD | NEW |
| 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" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
| 10 #include "base/sys_byteorder.h" | 10 #include "base/sys_byteorder.h" |
| 11 #include "content/browser/renderer_host/media/audio_input_debug_writer.h" | 11 #include "content/browser/renderer_host/media/audio_debug_file_writer.h" |
| 12 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
| 13 #include "content/public/test/test_browser_thread_bundle.h" | 13 #include "content/public/test/test_browser_thread_bundle.h" |
| 14 #include "media/base/audio_bus.h" | 14 #include "media/base/audio_bus.h" |
| 15 #include "media/base/test_helpers.h" | 15 #include "media/base/test_helpers.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 namespace content { | 18 namespace content { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 static const uint16_t kBytesPerSample = sizeof(uint16_t); | 22 static const uint16_t kBytesPerSample = sizeof(uint16_t); |
| 23 static const uint16_t kPcmEncoding = 1; | 23 static const uint16_t kPcmEncoding = 1; |
| 24 static const size_t kWavHeaderSize = 44; | 24 static const size_t kWavHeaderSize = 44; |
| 25 | 25 |
| 26 uint16_t ReadLE2(const char* buf) { | 26 uint16_t ReadLE2(const char* buf) { |
| 27 return static_cast<uint8_t>(buf[0]) | (static_cast<uint8_t>(buf[1]) << 8); | 27 return static_cast<uint8_t>(buf[0]) | (static_cast<uint8_t>(buf[1]) << 8); |
| 28 } | 28 } |
| 29 | 29 |
| 30 uint32_t ReadLE4(const char* buf) { | 30 uint32_t ReadLE4(const char* buf) { |
| 31 return static_cast<uint8_t>(buf[0]) | (static_cast<uint8_t>(buf[1]) << 8) | | 31 return static_cast<uint8_t>(buf[0]) | (static_cast<uint8_t>(buf[1]) << 8) | |
| 32 (static_cast<uint8_t>(buf[2]) << 16) | | 32 (static_cast<uint8_t>(buf[2]) << 16) | |
| 33 (static_cast<uint8_t>(buf[3]) << 24); | 33 (static_cast<uint8_t>(buf[3]) << 24); |
| 34 } | 34 } |
| 35 | 35 |
| 36 } // namespace | 36 } // namespace |
| 37 | 37 |
| 38 // <channel layout, sample rate, frames per buffer, number of buffer writes | 38 // <channel layout, sample rate, frames per buffer, number of buffer writes |
| 39 typedef std::tr1::tuple<media::ChannelLayout, int, int, int> | 39 typedef std::tr1::tuple<media::ChannelLayout, int, int, int> |
| 40 AudioInputDebugWriterTestData; | 40 AudioDebugFileWriterTestData; |
| 41 | 41 |
| 42 class AudioInputDebugWriterTest | 42 class AudioDebugFileWriterTest |
| 43 : public testing::TestWithParam<AudioInputDebugWriterTestData> { | 43 : public testing::TestWithParam<AudioDebugFileWriterTestData> { |
| 44 public: | 44 public: |
| 45 AudioInputDebugWriterTest() | 45 AudioDebugFileWriterTest() |
| 46 : thread_bundle_(content::TestBrowserThreadBundle::REAL_FILE_THREAD), | 46 : thread_bundle_(content::TestBrowserThreadBundle::REAL_FILE_THREAD), |
| 47 params_(media::AudioParameters::Format::AUDIO_PCM_LINEAR, | 47 params_(media::AudioParameters::Format::AUDIO_PCM_LINEAR, |
| 48 std::tr1::get<0>(GetParam()), | 48 std::tr1::get<0>(GetParam()), |
| 49 std::tr1::get<1>(GetParam()), | 49 std::tr1::get<1>(GetParam()), |
| 50 kBytesPerSample * 8, | 50 kBytesPerSample * 8, |
| 51 std::tr1::get<2>(GetParam())), | 51 std::tr1::get<2>(GetParam())), |
| 52 writes_(std::tr1::get<3>(GetParam())), | 52 writes_(std::tr1::get<3>(GetParam())), |
| 53 source_samples_(params_.frames_per_buffer() * params_.channels() * | 53 source_samples_(params_.frames_per_buffer() * params_.channels() * |
| 54 writes_), | 54 writes_), |
| 55 source_interleaved_(source_samples_ ? new int16_t[source_samples_] | 55 source_interleaved_(source_samples_ ? new int16_t[source_samples_] |
| 56 : nullptr) { | 56 : nullptr) { |
| 57 InitSourceInterleaved(source_interleaved_.get(), source_samples_); | 57 InitSourceInterleaved(source_interleaved_.get(), source_samples_); |
| 58 } | 58 } |
| 59 | 59 |
| 60 protected: | 60 protected: |
| 61 virtual ~AudioInputDebugWriterTest() {} | 61 virtual ~AudioDebugFileWriterTest() {} |
| 62 | 62 |
| 63 static void InitSourceInterleaved(int16_t* source_interleaved, | 63 static void InitSourceInterleaved(int16_t* source_interleaved, |
| 64 int source_samples) { | 64 int source_samples) { |
| 65 if (source_samples) { | 65 if (source_samples) { |
| 66 // equal steps to cover int16_t range of values | 66 // equal steps to cover int16_t range of values |
| 67 int16_t step = 0xffff / source_samples; | 67 int16_t step = 0xffff / source_samples; |
| 68 int16_t val = std::numeric_limits<int16_t>::min(); | 68 int16_t val = std::numeric_limits<int16_t>::min(); |
| 69 for (int i = 0; i < source_samples; ++i, val += step) | 69 for (int i = 0; i < source_samples; ++i, val += step) |
| 70 source_interleaved[i] = val; | 70 source_interleaved[i] = val; |
| 71 } | 71 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 } | 174 } |
| 175 } | 175 } |
| 176 | 176 |
| 177 void WaitForRecordingCompletion() { | 177 void WaitForRecordingCompletion() { |
| 178 media::WaitableMessageLoopEvent event; | 178 media::WaitableMessageLoopEvent event; |
| 179 | 179 |
| 180 // Post a task to BrowserThread::FILE indicating that all the writes are | 180 // Post a task to BrowserThread::FILE indicating that all the writes are |
| 181 // done. | 181 // done. |
| 182 BrowserThread::PostTask( | 182 BrowserThread::PostTask( |
| 183 BrowserThread::FILE, FROM_HERE, | 183 BrowserThread::FILE, FROM_HERE, |
| 184 base::Bind(&AudioInputDebugWriterTest::TestDoneOnFileThread, | 184 base::Bind(&AudioDebugFileWriterTest::TestDoneOnFileThread, |
| 185 base::Unretained(this), event.GetClosure())); | 185 base::Unretained(this), event.GetClosure())); |
| 186 | 186 |
| 187 // Wait for TestDoneOnFileThread() to call event's closure. | 187 // Wait for TestDoneOnFileThread() to call event's closure. |
| 188 event.RunAndWait(); | 188 event.RunAndWait(); |
| 189 } | 189 } |
| 190 | 190 |
| 191 void RecordAndVerifyOnce() { | 191 void RecordAndVerifyOnce() { |
| 192 base::FilePath file_path; | 192 base::FilePath file_path; |
| 193 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); | 193 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); |
| 194 | 194 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 207 << file_path.value().c_str() << "]."; | 207 << file_path.value().c_str() << "]."; |
| 208 } else { | 208 } else { |
| 209 EXPECT_TRUE(base::DeleteFile(file_path, false)); | 209 EXPECT_TRUE(base::DeleteFile(file_path, false)); |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 | 212 |
| 213 protected: | 213 protected: |
| 214 TestBrowserThreadBundle thread_bundle_; | 214 TestBrowserThreadBundle thread_bundle_; |
| 215 | 215 |
| 216 // Writer under test. | 216 // Writer under test. |
| 217 std::unique_ptr<AudioInputDebugWriter> input_debug_writer_; | 217 std::unique_ptr<AudioDebugFileWriter> input_debug_writer_; |
| 218 | 218 |
| 219 // AudioBus parameters. | 219 // AudioBus parameters. |
| 220 media::AudioParameters params_; | 220 media::AudioParameters params_; |
| 221 | 221 |
| 222 // Number of times to write AudioBus to the file. | 222 // Number of times to write AudioBus to the file. |
| 223 int writes_; | 223 int writes_; |
| 224 | 224 |
| 225 // Number of samples in the source data. | 225 // Number of samples in the source data. |
| 226 int source_samples_; | 226 int source_samples_; |
| 227 | 227 |
| 228 // Source data. | 228 // Source data. |
| 229 std::unique_ptr<int16_t[]> source_interleaved_; | 229 std::unique_ptr<int16_t[]> source_interleaved_; |
| 230 | 230 |
| 231 private: | 231 private: |
| 232 DISALLOW_COPY_AND_ASSIGN(AudioInputDebugWriterTest); | 232 DISALLOW_COPY_AND_ASSIGN(AudioDebugFileWriterTest); |
| 233 }; | 233 }; |
| 234 | 234 |
| 235 class AudioInputDebugWriterBehavioralTest : public AudioInputDebugWriterTest {}; | 235 class AudioDebugFileWriterBehavioralTest : public AudioDebugFileWriterTest {}; |
| 236 | 236 |
| 237 TEST_P(AudioInputDebugWriterTest, WaveRecordingTest) { | 237 TEST_P(AudioDebugFileWriterTest, WaveRecordingTest) { |
| 238 input_debug_writer_.reset(new AudioInputDebugWriter(params_)); | 238 input_debug_writer_.reset(new AudioDebugFileWriter(params_)); |
| 239 | 239 |
| 240 RecordAndVerifyOnce(); | 240 RecordAndVerifyOnce(); |
| 241 } | 241 } |
| 242 | 242 |
| 243 TEST_P(AudioInputDebugWriterBehavioralTest, | 243 TEST_P(AudioDebugFileWriterBehavioralTest, |
| 244 DeletedBeforeRecordingFinishedOnFileThread) { | 244 DeletedBeforeRecordingFinishedOnFileThread) { |
| 245 input_debug_writer_.reset(new AudioInputDebugWriter(params_)); | 245 input_debug_writer_.reset(new AudioDebugFileWriter(params_)); |
| 246 | 246 |
| 247 base::FilePath file_path; | 247 base::FilePath file_path; |
| 248 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); | 248 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); |
| 249 | 249 |
| 250 base::WaitableEvent* wait_for_deletion = | 250 base::WaitableEvent* wait_for_deletion = |
| 251 new base::WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, | 251 new base::WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, |
| 252 base::WaitableEvent::InitialState::NOT_SIGNALED); | 252 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 253 | 253 |
| 254 BrowserThread::PostTask( | 254 BrowserThread::PostTask( |
| 255 BrowserThread::FILE, FROM_HERE, | 255 BrowserThread::FILE, FROM_HERE, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 267 VerifyRecording(file_path); | 267 VerifyRecording(file_path); |
| 268 | 268 |
| 269 if (::testing::Test::HasFailure()) { | 269 if (::testing::Test::HasFailure()) { |
| 270 LOG(ERROR) << "Test failed; keeping recording(s) at [" | 270 LOG(ERROR) << "Test failed; keeping recording(s) at [" |
| 271 << file_path.value().c_str() << "]."; | 271 << file_path.value().c_str() << "]."; |
| 272 } else { | 272 } else { |
| 273 EXPECT_TRUE(base::DeleteFile(file_path, false)); | 273 EXPECT_TRUE(base::DeleteFile(file_path, false)); |
| 274 } | 274 } |
| 275 } | 275 } |
| 276 | 276 |
| 277 TEST_P(AudioInputDebugWriterBehavioralTest, FileCreationError) { | 277 TEST_P(AudioDebugFileWriterBehavioralTest, FileCreationError) { |
| 278 input_debug_writer_.reset(new AudioInputDebugWriter(params_)); | 278 input_debug_writer_.reset(new AudioDebugFileWriter(params_)); |
| 279 base::FilePath file_path; // Empty file name. | 279 base::FilePath file_path; // Empty file name. |
| 280 input_debug_writer_->Start(file_path); | 280 input_debug_writer_->Start(file_path); |
| 281 DoDebugRecording(); | 281 DoDebugRecording(); |
| 282 } | 282 } |
| 283 | 283 |
| 284 TEST_P(AudioInputDebugWriterBehavioralTest, StartStopStartStop) { | 284 TEST_P(AudioDebugFileWriterBehavioralTest, StartStopStartStop) { |
| 285 input_debug_writer_.reset(new AudioInputDebugWriter(params_)); | 285 input_debug_writer_.reset(new AudioDebugFileWriter(params_)); |
| 286 RecordAndVerifyOnce(); | 286 RecordAndVerifyOnce(); |
| 287 RecordAndVerifyOnce(); | 287 RecordAndVerifyOnce(); |
| 288 } | 288 } |
| 289 | 289 |
| 290 TEST_P(AudioInputDebugWriterBehavioralTest, DestroyNotStarted) { | 290 TEST_P(AudioDebugFileWriterBehavioralTest, DestroyNotStarted) { |
| 291 input_debug_writer_.reset(new AudioInputDebugWriter(params_)); | 291 input_debug_writer_.reset(new AudioDebugFileWriter(params_)); |
| 292 input_debug_writer_.reset(); | 292 input_debug_writer_.reset(); |
| 293 } | 293 } |
| 294 | 294 |
| 295 TEST_P(AudioInputDebugWriterBehavioralTest, DestroyStarted) { | 295 TEST_P(AudioDebugFileWriterBehavioralTest, DestroyStarted) { |
| 296 input_debug_writer_.reset(new AudioInputDebugWriter(params_)); | 296 input_debug_writer_.reset(new AudioDebugFileWriter(params_)); |
| 297 base::FilePath file_path; | 297 base::FilePath file_path; |
| 298 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); | 298 EXPECT_TRUE(base::CreateTemporaryFile(&file_path)); |
| 299 input_debug_writer_->Start(file_path); | 299 input_debug_writer_->Start(file_path); |
| 300 input_debug_writer_.reset(); | 300 input_debug_writer_.reset(); |
| 301 } | 301 } |
| 302 | 302 |
| 303 INSTANTIATE_TEST_CASE_P( | 303 INSTANTIATE_TEST_CASE_P( |
| 304 AudioInputDebugWriterTest, | 304 AudioDebugFileWriterTest, |
| 305 AudioInputDebugWriterTest, | 305 AudioDebugFileWriterTest, |
| 306 // Using 10ms frames per buffer everywhere. | 306 // Using 10ms frames per buffer everywhere. |
| 307 testing::Values( | 307 testing::Values( |
| 308 // No writes. | 308 // No writes. |
| 309 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, | 309 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, |
| 310 44100, | 310 44100, |
| 311 44100 / 100, | 311 44100 / 100, |
| 312 0), | 312 0), |
| 313 // 1 write of mono. | 313 // 1 write of mono. |
| 314 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, | 314 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, |
| 315 44100, | 315 44100, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 330 44100, | 330 44100, |
| 331 44100 / 100, | 331 44100 / 100, |
| 332 100), | 332 100), |
| 333 // 15 seconds of stereo, higher rate. | 333 // 15 seconds of stereo, higher rate. |
| 334 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO, | 334 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_STEREO, |
| 335 48000, | 335 48000, |
| 336 48000 / 100, | 336 48000 / 100, |
| 337 1500))); | 337 1500))); |
| 338 | 338 |
| 339 INSTANTIATE_TEST_CASE_P( | 339 INSTANTIATE_TEST_CASE_P( |
| 340 AudioInputDebugWriterBehavioralTest, | 340 AudioDebugFileWriterBehavioralTest, |
| 341 AudioInputDebugWriterBehavioralTest, | 341 AudioDebugFileWriterBehavioralTest, |
| 342 // Using 10ms frames per buffer everywhere. | 342 // Using 10ms frames per buffer everywhere. |
| 343 testing::Values( | 343 testing::Values( |
| 344 // No writes. | 344 // No writes. |
| 345 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, | 345 std::tr1::make_tuple(media::ChannelLayout::CHANNEL_LAYOUT_MONO, |
| 346 44100, | 346 44100, |
| 347 44100 / 100, | 347 44100 / 100, |
| 348 100))); | 348 100))); |
| 349 | 349 |
| 350 } // namespace content | 350 } // namespace content |
| OLD | NEW |