OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 <stddef.h> | 5 #include <stddef.h> |
6 #include <memory> | 6 #include <memory> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/bind_helpers.h" | 9 #include "base/bind_helpers.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
12 #include "media/base/audio_renderer_mixer.h" | 12 #include "media/base/audio_renderer_mixer.h" |
13 #include "media/base/audio_renderer_mixer_input.h" | 13 #include "media/base/audio_renderer_mixer_input.h" |
| 14 #include "media/base/audio_renderer_mixer_pool.h" |
14 #include "media/base/fake_audio_render_callback.h" | 15 #include "media/base/fake_audio_render_callback.h" |
15 #include "media/base/mock_audio_renderer_sink.h" | 16 #include "media/base/mock_audio_renderer_sink.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
18 | 19 |
19 namespace media { | 20 namespace media { |
20 | 21 |
21 static const int kBitsPerChannel = 16; | 22 static const int kBitsPerChannel = 16; |
22 static const int kSampleRate = 48000; | 23 static const int kSampleRate = 48000; |
23 static const int kBufferSize = 8192; | 24 static const int kBufferSize = 8192; |
| 25 static const int kRenderFrameId = 42; |
24 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; | 26 static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; |
25 static const char kDefaultDeviceId[] = ""; | 27 static const char kDefaultDeviceId[] = "default"; |
26 static const char kUnauthorizedDeviceId[] = "unauthorized"; | 28 static const char kUnauthorizedDeviceId[] = "unauthorized"; |
27 static const char kNonexistentDeviceId[] = "nonexistent"; | 29 static const char kNonexistentDeviceId[] = "nonexistent"; |
28 | 30 |
29 class AudioRendererMixerInputTest : public testing::Test { | 31 class AudioRendererMixerInputTest : public testing::Test, |
| 32 AudioRendererMixerPool { |
30 public: | 33 public: |
31 AudioRendererMixerInputTest() { | 34 AudioRendererMixerInputTest() { |
32 audio_parameters_ = AudioParameters( | 35 audio_parameters_ = AudioParameters( |
33 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, | 36 AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, kSampleRate, |
34 kBitsPerChannel, kBufferSize); | 37 kBitsPerChannel, kBufferSize); |
35 | 38 |
36 CreateMixerInput(kDefaultDeviceId); | 39 CreateMixerInput(kDefaultDeviceId); |
37 fake_callback_.reset(new FakeAudioRenderCallback(0)); | 40 fake_callback_.reset(new FakeAudioRenderCallback(0)); |
38 mixer_input_->Initialize(audio_parameters_, fake_callback_.get()); | 41 mixer_input_->Initialize(audio_parameters_, fake_callback_.get()); |
39 audio_bus_ = AudioBus::Create(audio_parameters_); | 42 audio_bus_ = AudioBus::Create(audio_parameters_); |
40 } | 43 } |
41 | 44 |
42 void CreateMixerInput(const std::string& device_id) { | 45 void CreateMixerInput(const std::string& device_id) { |
43 mixer_input_ = new AudioRendererMixerInput( | 46 mixer_input_ = new AudioRendererMixerInput(this, kRenderFrameId, device_id, |
44 base::Bind(&AudioRendererMixerInputTest::GetMixer, | 47 url::Origin()); |
45 base::Unretained(this)), | |
46 base::Bind(&AudioRendererMixerInputTest::RemoveMixer, | |
47 base::Unretained(this)), | |
48 device_id, url::Origin()); | |
49 } | 48 } |
50 | 49 |
51 AudioRendererMixer* GetMixer(const AudioParameters& params, | 50 AudioRendererMixer* GetMixer(int owner_id, |
| 51 const AudioParameters& params, |
52 const std::string& device_id, | 52 const std::string& device_id, |
53 const url::Origin& security_origin, | 53 const url::Origin& security_origin, |
54 OutputDeviceStatus* device_status) { | 54 OutputDeviceStatus* device_status) { |
55 if (device_id == kNonexistentDeviceId) { | 55 if (device_id == kNonexistentDeviceId) { |
56 if (device_status) | 56 if (device_status) |
57 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; | 57 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_FOUND; |
58 return nullptr; | 58 return nullptr; |
59 } | 59 } |
60 | 60 |
61 if (device_id == kUnauthorizedDeviceId) { | 61 if (device_id == kUnauthorizedDeviceId) { |
62 if (device_status) | 62 if (device_status) |
63 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED; | 63 *device_status = OUTPUT_DEVICE_STATUS_ERROR_NOT_AUTHORIZED; |
64 return nullptr; | 64 return nullptr; |
65 } | 65 } |
66 | 66 |
67 size_t idx = device_id.empty() ? 0 : 1; | 67 size_t idx = (device_id == kDefaultDeviceId) ? 0 : 1; |
68 if (!mixers_[idx]) { | 68 if (!mixers_[idx]) { |
69 scoped_refptr<MockAudioRendererSink> sink = new MockAudioRendererSink(); | 69 sinks_[idx] = |
70 EXPECT_CALL(*sink.get(), Start()); | 70 new MockAudioRendererSink(device_id, OUTPUT_DEVICE_STATUS_OK); |
71 EXPECT_CALL(*sink.get(), Stop()); | 71 EXPECT_CALL(*(sinks_[idx].get()), Start()); |
| 72 EXPECT_CALL(*(sinks_[idx].get()), Stop()); |
72 | 73 |
73 mixers_[idx].reset(new AudioRendererMixer(audio_parameters_, sink)); | 74 mixers_[idx].reset( |
| 75 new AudioRendererMixer(audio_parameters_, sinks_[idx].get())); |
74 } | 76 } |
75 EXPECT_CALL(*this, RemoveMixer(testing::_, device_id, testing::_)); | 77 EXPECT_CALL(*this, |
| 78 ReturnMixer(kRenderFrameId, testing::_, device_id, testing::_)); |
76 | 79 |
77 if (device_status) | 80 if (device_status) |
78 *device_status = OUTPUT_DEVICE_STATUS_OK; | 81 *device_status = OUTPUT_DEVICE_STATUS_OK; |
79 return mixers_[idx].get(); | 82 return mixers_[idx].get(); |
80 } | 83 } |
81 | 84 |
82 double ProvideInput() { | 85 double ProvideInput() { |
83 return mixer_input_->ProvideInput(audio_bus_.get(), base::TimeDelta()); | 86 return mixer_input_->ProvideInput(audio_bus_.get(), base::TimeDelta()); |
84 } | 87 } |
85 | 88 |
86 MOCK_METHOD3(RemoveMixer, | 89 MOCK_METHOD4(ReturnMixer, |
87 void(const AudioParameters&, | 90 void(int, |
| 91 const AudioParameters&, |
88 const std::string&, | 92 const std::string&, |
89 const url::Origin&)); | 93 const url::Origin&)); |
90 | 94 |
| 95 MOCK_METHOD4( |
| 96 GetOutputDeviceInfo, |
| 97 OutputDeviceInfo(int, int, const std::string&, const url::Origin&)); |
| 98 |
91 MOCK_METHOD1(SwitchCallbackCalled, void(OutputDeviceStatus)); | 99 MOCK_METHOD1(SwitchCallbackCalled, void(OutputDeviceStatus)); |
| 100 |
92 void SwitchCallback(base::RunLoop* loop, OutputDeviceStatus result) { | 101 void SwitchCallback(base::RunLoop* loop, OutputDeviceStatus result) { |
93 SwitchCallbackCalled(result); | 102 SwitchCallbackCalled(result); |
94 loop->Quit(); | 103 loop->Quit(); |
95 } | 104 } |
96 | 105 |
97 AudioRendererMixer* GetInputMixer() { return mixer_input_->mixer_; } | 106 AudioRendererMixer* GetInputMixer() { return mixer_input_->mixer_; } |
98 | 107 |
99 protected: | 108 protected: |
100 virtual ~AudioRendererMixerInputTest() {} | 109 virtual ~AudioRendererMixerInputTest() {} |
101 | 110 |
102 AudioParameters audio_parameters_; | 111 AudioParameters audio_parameters_; |
| 112 scoped_refptr<MockAudioRendererSink> sinks_[2]; |
103 std::unique_ptr<AudioRendererMixer> mixers_[2]; | 113 std::unique_ptr<AudioRendererMixer> mixers_[2]; |
104 scoped_refptr<AudioRendererMixerInput> mixer_input_; | 114 scoped_refptr<AudioRendererMixerInput> mixer_input_; |
105 std::unique_ptr<FakeAudioRenderCallback> fake_callback_; | 115 std::unique_ptr<FakeAudioRenderCallback> fake_callback_; |
106 std::unique_ptr<AudioBus> audio_bus_; | 116 std::unique_ptr<AudioBus> audio_bus_; |
107 | 117 |
108 private: | 118 private: |
109 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerInputTest); | 119 DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerInputTest); |
110 }; | 120 }; |
111 | 121 |
| 122 TEST_F(AudioRendererMixerInputTest, GetDeviceInfo) { |
| 123 ON_CALL(*this, |
| 124 GetOutputDeviceInfo(testing::_, testing::_, testing::_, testing::_)) |
| 125 .WillByDefault(testing::Return(OutputDeviceInfo())); |
| 126 EXPECT_CALL(*this, GetOutputDeviceInfo(kRenderFrameId, 0 /* session id */, |
| 127 kDefaultDeviceId, testing::_)) |
| 128 .Times(testing::Exactly(1)); |
| 129 |
| 130 // Calling GetOutputDeviceInfo() should result in the mock call, since there |
| 131 // is no mixer created yet for mixer input. |
| 132 mixer_input_->GetOutputDeviceInfo(); |
| 133 mixer_input_->Start(); |
| 134 |
| 135 // This call should be directed to the mixer and should not result in the mock |
| 136 // call. |
| 137 EXPECT_STREQ(kDefaultDeviceId, |
| 138 mixer_input_->GetOutputDeviceInfo().device_id().c_str()); |
| 139 |
| 140 mixer_input_->Stop(); |
| 141 } |
| 142 |
112 // Test that getting and setting the volume work as expected. The volume is | 143 // Test that getting and setting the volume work as expected. The volume is |
113 // returned from ProvideInput() only when playing. | 144 // returned from ProvideInput() only when playing. |
114 TEST_F(AudioRendererMixerInputTest, GetSetVolume) { | 145 TEST_F(AudioRendererMixerInputTest, GetSetVolume) { |
115 mixer_input_->Start(); | 146 mixer_input_->Start(); |
116 mixer_input_->Play(); | 147 mixer_input_->Play(); |
117 | 148 |
118 // Starting volume should be 1.0. | 149 // Starting volume should be 1.0. |
119 EXPECT_DOUBLE_EQ(ProvideInput(), 1); | 150 EXPECT_DOUBLE_EQ(ProvideInput(), 1); |
120 | 151 |
121 const double kVolume = 0.5; | 152 const double kVolume = 0.5; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 EXPECT_CALL(*this, SwitchCallbackCalled(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)); | 302 EXPECT_CALL(*this, SwitchCallbackCalled(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL)); |
272 mixer_input_->SwitchOutputDevice( | 303 mixer_input_->SwitchOutputDevice( |
273 kDefaultDeviceId, url::Origin(), | 304 kDefaultDeviceId, url::Origin(), |
274 base::Bind(&AudioRendererMixerInputTest::SwitchCallback, | 305 base::Bind(&AudioRendererMixerInputTest::SwitchCallback, |
275 base::Unretained(this), &run_loop)); | 306 base::Unretained(this), &run_loop)); |
276 mixer_input_->Stop(); | 307 mixer_input_->Stop(); |
277 run_loop.Run(); | 308 run_loop.Run(); |
278 } | 309 } |
279 | 310 |
280 } // namespace media | 311 } // namespace media |
OLD | NEW |