| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 "base/bind.h" | |
| 6 #include "base/message_loop/message_loop.h" | |
| 7 #include "base/time/time.h" | |
| 8 #include "media/audio/audio_parameters.h" | |
| 9 #include "media/audio/fake_audio_consumer.h" | |
| 10 #include "media/audio/simple_sources.h" | |
| 11 #include "testing/gtest/include/gtest/gtest.h" | |
| 12 | |
| 13 namespace media { | |
| 14 | |
| 15 static const int kTestCallbacks = 5; | |
| 16 | |
| 17 class FakeAudioConsumerTest : public testing::Test { | |
| 18 public: | |
| 19 FakeAudioConsumerTest() | |
| 20 : params_( | |
| 21 AudioParameters::AUDIO_FAKE, CHANNEL_LAYOUT_STEREO, 44100, 8, 128), | |
| 22 fake_consumer_(message_loop_.message_loop_proxy(), params_), | |
| 23 source_(params_.channels(), 200.0, params_.sample_rate()) { | |
| 24 time_between_callbacks_ = base::TimeDelta::FromMicroseconds( | |
| 25 params_.frames_per_buffer() * base::Time::kMicrosecondsPerSecond / | |
| 26 static_cast<float>(params_.sample_rate())); | |
| 27 } | |
| 28 | |
| 29 ~FakeAudioConsumerTest() override {} | |
| 30 | |
| 31 void ConsumeData(AudioBus* audio_bus) { | |
| 32 source_.OnMoreData(audio_bus, 0); | |
| 33 } | |
| 34 | |
| 35 void RunOnAudioThread() { | |
| 36 ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); | |
| 37 fake_consumer_.Start(base::Bind( | |
| 38 &FakeAudioConsumerTest::ConsumeData, base::Unretained(this))); | |
| 39 } | |
| 40 | |
| 41 void RunOnceOnAudioThread() { | |
| 42 ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); | |
| 43 RunOnAudioThread(); | |
| 44 // Start() should immediately post a task to run the source callback, so we | |
| 45 // should end up with only a single callback being run. | |
| 46 message_loop_.PostTask(FROM_HERE, base::Bind( | |
| 47 &FakeAudioConsumerTest::EndTest, base::Unretained(this), 1)); | |
| 48 } | |
| 49 | |
| 50 void StopStartOnAudioThread() { | |
| 51 ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); | |
| 52 fake_consumer_.Stop(); | |
| 53 RunOnAudioThread(); | |
| 54 } | |
| 55 | |
| 56 void TimeCallbacksOnAudioThread(int callbacks) { | |
| 57 ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); | |
| 58 | |
| 59 if (source_.callbacks() == 0) { | |
| 60 RunOnAudioThread(); | |
| 61 start_time_ = base::TimeTicks::Now(); | |
| 62 } | |
| 63 | |
| 64 // Keep going until we've seen the requested number of callbacks. | |
| 65 if (source_.callbacks() < callbacks) { | |
| 66 message_loop_.PostDelayedTask(FROM_HERE, base::Bind( | |
| 67 &FakeAudioConsumerTest::TimeCallbacksOnAudioThread, | |
| 68 base::Unretained(this), callbacks), time_between_callbacks_ / 2); | |
| 69 } else { | |
| 70 end_time_ = base::TimeTicks::Now(); | |
| 71 EndTest(callbacks); | |
| 72 } | |
| 73 } | |
| 74 | |
| 75 void EndTest(int callbacks) { | |
| 76 ASSERT_TRUE(message_loop_.message_loop_proxy()->BelongsToCurrentThread()); | |
| 77 fake_consumer_.Stop(); | |
| 78 EXPECT_LE(callbacks, source_.callbacks()); | |
| 79 message_loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure()); | |
| 80 } | |
| 81 | |
| 82 protected: | |
| 83 base::MessageLoop message_loop_; | |
| 84 AudioParameters params_; | |
| 85 FakeAudioConsumer fake_consumer_; | |
| 86 SineWaveAudioSource source_; | |
| 87 base::TimeTicks start_time_; | |
| 88 base::TimeTicks end_time_; | |
| 89 base::TimeDelta time_between_callbacks_; | |
| 90 | |
| 91 private: | |
| 92 DISALLOW_COPY_AND_ASSIGN(FakeAudioConsumerTest); | |
| 93 }; | |
| 94 | |
| 95 // Ensure the fake audio stream runs on the audio thread and handles fires | |
| 96 // callbacks to the AudioSourceCallback. | |
| 97 TEST_F(FakeAudioConsumerTest, FakeStreamBasicCallback) { | |
| 98 message_loop_.PostTask(FROM_HERE, base::Bind( | |
| 99 &FakeAudioConsumerTest::RunOnceOnAudioThread, | |
| 100 base::Unretained(this))); | |
| 101 message_loop_.Run(); | |
| 102 } | |
| 103 | |
| 104 // Ensure the time between callbacks is sane. | |
| 105 TEST_F(FakeAudioConsumerTest, TimeBetweenCallbacks) { | |
| 106 message_loop_.PostTask(FROM_HERE, base::Bind( | |
| 107 &FakeAudioConsumerTest::TimeCallbacksOnAudioThread, | |
| 108 base::Unretained(this), kTestCallbacks)); | |
| 109 message_loop_.Run(); | |
| 110 | |
| 111 // There are only (kTestCallbacks - 1) intervals between kTestCallbacks. | |
| 112 base::TimeDelta actual_time_between_callbacks = | |
| 113 (end_time_ - start_time_) / (source_.callbacks() - 1); | |
| 114 | |
| 115 // Ensure callback time is no faster than the expected time between callbacks. | |
| 116 EXPECT_TRUE(actual_time_between_callbacks >= time_between_callbacks_); | |
| 117 | |
| 118 // Softly check if the callback time is no slower than twice the expected time | |
| 119 // between callbacks. Since this test runs on the bots we can't be too strict | |
| 120 // with the bounds. | |
| 121 if (actual_time_between_callbacks > 2 * time_between_callbacks_) | |
| 122 LOG(ERROR) << "Time between fake audio callbacks is too large!"; | |
| 123 } | |
| 124 | |
| 125 // Ensure Start()/Stop() on the stream doesn't generate too many callbacks. See | |
| 126 // http://crbug.com/159049 | |
| 127 TEST_F(FakeAudioConsumerTest, StartStopClearsCallbacks) { | |
| 128 message_loop_.PostTask(FROM_HERE, base::Bind( | |
| 129 &FakeAudioConsumerTest::TimeCallbacksOnAudioThread, | |
| 130 base::Unretained(this), kTestCallbacks)); | |
| 131 | |
| 132 // Issue a Stop() / Start() in between expected callbacks to maximize the | |
| 133 // chance of catching the FakeAudioOutputStream doing the wrong thing. | |
| 134 message_loop_.PostDelayedTask(FROM_HERE, base::Bind( | |
| 135 &FakeAudioConsumerTest::StopStartOnAudioThread, | |
| 136 base::Unretained(this)), time_between_callbacks_ / 2); | |
| 137 | |
| 138 // EndTest() will ensure the proper number of callbacks have occurred. | |
| 139 message_loop_.Run(); | |
| 140 } | |
| 141 | |
| 142 } // namespace media | |
| OLD | NEW |