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

Side by Side Diff: media/audio/audio_output_device_unittest.cc

Issue 10834033: Move AudioDevice and AudioInputDevice to media. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments and fixed a few lint issues Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « media/audio/audio_output_device.cc ('k') | media/audio/audio_output_ipc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <vector> 5 #include <vector>
6 6
7 #include "base/at_exit.h" 7 #include "base/at_exit.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/process_util.h" 9 #include "base/process_util.h"
10 #include "base/shared_memory.h" 10 #include "base/shared_memory.h"
11 #include "base/sync_socket.h" 11 #include "base/sync_socket.h"
12 #include "base/test/test_timeouts.h" 12 #include "base/test/test_timeouts.h"
13 #include "content/common/media/audio_messages.h" 13 #include "media/audio/audio_output_device.h"
14 #include "content/renderer/media/audio_device.h"
15 #include "content/renderer/media/audio_message_filter.h"
16 #include "media/audio/audio_util.h" 14 #include "media/audio/audio_util.h"
17 #include "media/audio/sample_rates.h" 15 #include "media/audio/sample_rates.h"
18 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gmock_mutant.h" 17 #include "testing/gmock_mutant.h"
20 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
21 19
22 using base::CancelableSyncSocket; 20 using base::CancelableSyncSocket;
23 using base::SharedMemory; 21 using base::SharedMemory;
24 using base::SyncSocket; 22 using base::SyncSocket;
25 using testing::_; 23 using testing::_;
26 using testing::DoAll; 24 using testing::DoAll;
27 using testing::Invoke; 25 using testing::Invoke;
28 using testing::Return; 26 using testing::Return;
29 using testing::WithArgs; 27 using testing::WithArgs;
30 28
29 namespace media {
30
31 namespace { 31 namespace {
32 32
33 class MockRenderCallback : public media::AudioRendererSink::RenderCallback { 33 class MockRenderCallback : public AudioRendererSink::RenderCallback {
34 public: 34 public:
35 MockRenderCallback() {} 35 MockRenderCallback() {}
36 virtual ~MockRenderCallback() {} 36 virtual ~MockRenderCallback() {}
37 37
38 MOCK_METHOD3(Render, int(const std::vector<float*>& audio_data, 38 MOCK_METHOD3(Render, int(const std::vector<float*>& audio_data,
39 int number_of_frames, 39 int number_of_frames,
40 int audio_delay_milliseconds)); 40 int audio_delay_milliseconds));
41 MOCK_METHOD0(OnRenderError, void()); 41 MOCK_METHOD0(OnRenderError, void());
42 }; 42 };
43 43
44 class MockAudioMessageFilter : public AudioMessageFilter { 44 class MockAudioOutputIPC : public AudioOutputIPC {
45 public: 45 public:
46 MockAudioMessageFilter() {} 46 MockAudioOutputIPC() {}
47 virtual ~MockAudioOutputIPC() {}
48
49 MOCK_METHOD1(AddDelegate, int(AudioOutputIPCDelegate* delegate));
50 MOCK_METHOD1(RemoveDelegate, void(int stream_id));
47 51
48 MOCK_METHOD2(CreateStream, 52 MOCK_METHOD2(CreateStream,
49 void(int stream_id, const media::AudioParameters& params)); 53 void(int stream_id, const AudioParameters& params));
50 MOCK_METHOD1(PlayStream, void(int stream_id)); 54 MOCK_METHOD1(PlayStream, void(int stream_id));
51 MOCK_METHOD1(CloseStream, void(int stream_id)); 55 MOCK_METHOD1(CloseStream, void(int stream_id));
52 MOCK_METHOD2(SetVolume, void(int stream_id, double volume)); 56 MOCK_METHOD2(SetVolume, void(int stream_id, double volume));
53 MOCK_METHOD1(PauseStream, void(int stream_id)); 57 MOCK_METHOD1(PauseStream, void(int stream_id));
54 MOCK_METHOD1(FlushStream, void(int stream_id)); 58 MOCK_METHOD1(FlushStream, void(int stream_id));
55
56 protected:
57 virtual ~MockAudioMessageFilter() {}
58 }; 59 };
59 60
60 // Creates a copy of a SyncSocket handle that we can give to AudioDevice. 61 // Creates a copy of a SyncSocket handle that we can give to AudioOutputDevice.
61 // On Windows this means duplicating the pipe handle so that AudioDevice can 62 // On Windows this means duplicating the pipe handle so that AudioOutputDevice
62 // call CloseHandle() (since ownership has been transferred), but on other 63 // can call CloseHandle() (since ownership has been transferred), but on other
63 // platforms, we just copy the same socket handle since AudioDevice on those 64 // platforms, we just copy the same socket handle since AudioOutputDevice on
64 // platforms won't actually own the socket (FileDescriptor.auto_close is false). 65 // those platforms won't actually own the socket (FileDescriptor.auto_close is
66 // false).
65 bool DuplicateSocketHandle(SyncSocket::Handle socket_handle, 67 bool DuplicateSocketHandle(SyncSocket::Handle socket_handle,
66 SyncSocket::Handle* copy) { 68 SyncSocket::Handle* copy) {
67 #if defined(OS_WIN) 69 #if defined(OS_WIN)
68 HANDLE process = GetCurrentProcess(); 70 HANDLE process = GetCurrentProcess();
69 ::DuplicateHandle(process, socket_handle, process, copy, 71 ::DuplicateHandle(process, socket_handle, process, copy,
70 0, FALSE, DUPLICATE_SAME_ACCESS); 72 0, FALSE, DUPLICATE_SAME_ACCESS);
71 return *copy != NULL; 73 return *copy != NULL;
72 #else 74 #else
73 *copy = socket_handle; 75 *copy = socket_handle;
74 return *copy != -1; 76 return *copy != -1;
(...skipping 18 matching lines...) Expand all
93 for (; it != audio_data.end(); ++it) { 95 for (; it != audio_data.end(); ++it) {
94 float* channel = *it; 96 float* channel = *it;
95 for (int j = 0; j < number_of_frames; ++j) { 97 for (int j = 0; j < number_of_frames; ++j) {
96 channel[j] = 0.0f; 98 channel[j] = 0.0f;
97 } 99 }
98 } 100 }
99 } 101 }
100 102
101 } // namespace. 103 } // namespace.
102 104
103 class AudioDeviceTest : public testing::Test { 105 class AudioOutputDeviceTest : public testing::Test {
104 public: 106 public:
105 AudioDeviceTest() 107 AudioOutputDeviceTest()
106 : default_audio_parameters_(media::AudioParameters::AUDIO_PCM_LINEAR, 108 : default_audio_parameters_(AudioParameters::AUDIO_PCM_LINEAR,
107 CHANNEL_LAYOUT_STEREO, 109 CHANNEL_LAYOUT_STEREO,
108 48000, 16, 1024), 110 48000, 16, 1024),
109 stream_id_(-1) { 111 stream_id_(-1) {
110 } 112 }
111 113
112 ~AudioDeviceTest() {} 114 ~AudioOutputDeviceTest() {}
113 115
114 virtual void SetUp() OVERRIDE { 116 AudioOutputDevice* CreateAudioDevice() {
115 // This sets a global audio_message_filter pointer. AudioDevice will pick 117 return new AudioOutputDevice(
116 // up a pointer to this variable via the static AudioMessageFilter::Get() 118 &audio_output_ipc_, io_loop_.message_loop_proxy());
117 // method.
118 audio_message_filter_ = new MockAudioMessageFilter();
119 }
120
121 AudioDevice* CreateAudioDevice() {
122 return new AudioDevice(
123 audio_message_filter_, io_loop_.message_loop_proxy());
124 } 119 }
125 120
126 void set_stream_id(int stream_id) { stream_id_ = stream_id; } 121 void set_stream_id(int stream_id) { stream_id_ = stream_id; }
127 122
128 protected: 123 protected:
129 // Used to clean up TLS pointers that the test(s) will initialize. 124 // Used to clean up TLS pointers that the test(s) will initialize.
130 // Must remain the first member of this class. 125 // Must remain the first member of this class.
131 base::ShadowingAtExitManager at_exit_manager_; 126 base::ShadowingAtExitManager at_exit_manager_;
132 MessageLoopForIO io_loop_; 127 MessageLoopForIO io_loop_;
133 const media::AudioParameters default_audio_parameters_; 128 const AudioParameters default_audio_parameters_;
134 MockRenderCallback callback_; 129 MockRenderCallback callback_;
135 scoped_refptr<MockAudioMessageFilter> audio_message_filter_; 130 MockAudioOutputIPC audio_output_ipc_;
136 int stream_id_; 131 int stream_id_;
137 }; 132 };
138 133
139 // The simplest test for AudioDevice. Used to test construction of AudioDevice 134 // The simplest test for AudioOutputDevice. Used to test construction of
140 // and that the runtime environment is set up correctly. 135 // AudioOutputDevice and that the runtime environment is set up correctly.
141 TEST_F(AudioDeviceTest, Initialize) { 136 TEST_F(AudioOutputDeviceTest, Initialize) {
142 scoped_refptr<AudioDevice> audio_device(CreateAudioDevice()); 137 scoped_refptr<AudioOutputDevice> audio_device(CreateAudioDevice());
143 audio_device->Initialize(default_audio_parameters_, &callback_); 138 audio_device->Initialize(default_audio_parameters_, &callback_);
144 io_loop_.RunAllPending(); 139 io_loop_.RunAllPending();
145 } 140 }
146 141
147 // Calls Start() followed by an immediate Stop() and check for the basic message 142 // Calls Start() followed by an immediate Stop() and check for the basic message
148 // filter messages being sent in that case. 143 // filter messages being sent in that case.
149 TEST_F(AudioDeviceTest, StartStop) { 144 TEST_F(AudioOutputDeviceTest, StartStop) {
150 scoped_refptr<AudioDevice> audio_device(CreateAudioDevice()); 145 scoped_refptr<AudioOutputDevice> audio_device(CreateAudioDevice());
151 audio_device->Initialize(default_audio_parameters_, &callback_); 146 audio_device->Initialize(default_audio_parameters_, &callback_);
152 147
148 EXPECT_CALL(audio_output_ipc_, AddDelegate(audio_device.get()))
149 .WillOnce(Return(1));
150 EXPECT_CALL(audio_output_ipc_, RemoveDelegate(1)).WillOnce(Return());
151
153 audio_device->Start(); 152 audio_device->Start();
154 audio_device->Stop(); 153 audio_device->Stop();
155 154
156 EXPECT_CALL(*audio_message_filter_, CreateStream(_, _)); 155 EXPECT_CALL(audio_output_ipc_, CreateStream(_, _));
157 EXPECT_CALL(*audio_message_filter_, CloseStream(_)); 156 EXPECT_CALL(audio_output_ipc_, CloseStream(_));
158 157
159 io_loop_.RunAllPending(); 158 io_loop_.RunAllPending();
160 } 159 }
161 160
162 // Starts an audio stream, creates a shared memory section + SyncSocket pair 161 // Starts an audio stream, creates a shared memory section + SyncSocket pair
163 // that AudioDevice must use for audio data. It then sends a request for 162 // that AudioOutputDevice must use for audio data. It then sends a request for
164 // a single audio packet and quits when the packet has been sent. 163 // a single audio packet and quits when the packet has been sent.
165 TEST_F(AudioDeviceTest, CreateStream) { 164 TEST_F(AudioOutputDeviceTest, CreateStream) {
166 scoped_refptr<AudioDevice> audio_device(CreateAudioDevice()); 165 scoped_refptr<AudioOutputDevice> audio_device(CreateAudioDevice());
167 audio_device->Initialize(default_audio_parameters_, &callback_); 166 audio_device->Initialize(default_audio_parameters_, &callback_);
168 167
168 EXPECT_CALL(audio_output_ipc_, AddDelegate(audio_device.get()))
169 .WillOnce(Return(1));
170 EXPECT_CALL(audio_output_ipc_, RemoveDelegate(1)).WillOnce(Return());
171
169 audio_device->Start(); 172 audio_device->Start();
170 173
171 EXPECT_CALL(*audio_message_filter_, CreateStream(_, _)) 174 EXPECT_CALL(audio_output_ipc_, CreateStream(_, _))
172 .WillOnce(WithArgs<0>(Invoke(this, &AudioDeviceTest::set_stream_id))); 175 .WillOnce(WithArgs<0>(
176 Invoke(this, &AudioOutputDeviceTest::set_stream_id)));
177
173 178
174 EXPECT_EQ(stream_id_, -1); 179 EXPECT_EQ(stream_id_, -1);
175 io_loop_.RunAllPending(); 180 io_loop_.RunAllPending();
176 181
177 // OnCreateStream() must have been called and we should have a valid 182 // OnCreateStream() must have been called and we should have a valid
178 // stream id. 183 // stream id.
179 ASSERT_NE(stream_id_, -1); 184 ASSERT_NE(stream_id_, -1);
180 185
181 // This is where it gets a bit hacky. The shared memory contract between 186 // This is where it gets a bit hacky. The shared memory contract between
182 // AudioDevice and its browser side counter part includes a bit more than 187 // AudioOutputDevice and its browser side counter part includes a bit more
183 // just the audio data, so we must call TotalSharedMemorySizeInBytes() to get 188 // than just the audio data, so we must call TotalSharedMemorySizeInBytes()
184 // the actual size needed to fit the audio data plus the extra data. 189 // to get the actual size needed to fit the audio data plus the extra data.
185 int memory_size = media::TotalSharedMemorySizeInBytes( 190 int memory_size = TotalSharedMemorySizeInBytes(
186 default_audio_parameters_.GetBytesPerBuffer()); 191 default_audio_parameters_.GetBytesPerBuffer());
187 SharedMemory shared_memory; 192 SharedMemory shared_memory;
188 ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(memory_size)); 193 ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(memory_size));
189 memset(shared_memory.memory(), 0xff, memory_size); 194 memset(shared_memory.memory(), 0xff, memory_size);
190 195
191 CancelableSyncSocket browser_socket, renderer_socket; 196 CancelableSyncSocket browser_socket, renderer_socket;
192 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket, 197 ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket,
193 &renderer_socket)); 198 &renderer_socket));
194 199
195 // Create duplicates of the handles we pass to AudioDevice since ownership 200 // Create duplicates of the handles we pass to AudioOutputDevice since
196 // will be transferred and AudioDevice is responsible for freeing. 201 // ownership will be transferred and AudioOutputDevice is responsible for
202 // freeing.
197 SyncSocket::Handle audio_device_socket = SyncSocket::kInvalidHandle; 203 SyncSocket::Handle audio_device_socket = SyncSocket::kInvalidHandle;
198 ASSERT_TRUE(DuplicateSocketHandle(renderer_socket.handle(), 204 ASSERT_TRUE(DuplicateSocketHandle(renderer_socket.handle(),
199 &audio_device_socket)); 205 &audio_device_socket));
200 base::SharedMemoryHandle duplicated_memory_handle; 206 base::SharedMemoryHandle duplicated_memory_handle;
201 ASSERT_TRUE(shared_memory.ShareToProcess(base::GetCurrentProcessHandle(), 207 ASSERT_TRUE(shared_memory.ShareToProcess(base::GetCurrentProcessHandle(),
202 &duplicated_memory_handle)); 208 &duplicated_memory_handle));
203 209
204 // We should get a 'play' notification when we call OnStreamCreated(). 210 // We should get a 'play' notification when we call OnStreamCreated().
205 // Respond by asking for some audio data. This should ask our callback 211 // Respond by asking for some audio data. This should ask our callback
206 // to provide some audio data that AudioDevice then writes into the shared 212 // to provide some audio data that AudioOutputDevice then writes into the
207 // memory section. 213 // shared memory section.
208 EXPECT_CALL(*audio_message_filter_, PlayStream(stream_id_)) 214 EXPECT_CALL(audio_output_ipc_, PlayStream(stream_id_))
209 .WillOnce(SendPendingBytes(&browser_socket, memory_size)); 215 .WillOnce(SendPendingBytes(&browser_socket, memory_size));
210 216
211 // We expect calls to our audio renderer callback, which returns the number 217 // We expect calls to our audio renderer callback, which returns the number
212 // of frames written to the memory section. 218 // of frames written to the memory section.
213 // Here's the second place where it gets hacky: There's no way for us to 219 // Here's the second place where it gets hacky: There's no way for us to
214 // know (without using a sleep loop!) when the AudioDevice has finished 220 // know (without using a sleep loop!) when the AudioOutputDevice has finished
215 // writing the interleaved audio data into the shared memory section. 221 // writing the interleaved audio data into the shared memory section.
216 // So, for the sake of this test, we consider the call to Render a sign 222 // So, for the sake of this test, we consider the call to Render a sign
217 // of success and quit the loop. 223 // of success and quit the loop.
218 224
219 // A note on the call to ZeroAudioData(): 225 // A note on the call to ZeroAudioData():
220 // Valgrind caught a bug in AudioDevice::AudioThreadCallback::Process() 226 // Valgrind caught a bug in AudioOutputDevice::AudioThreadCallback::Process()
221 // whereby we always interleaved all the frames in the buffer regardless 227 // whereby we always interleaved all the frames in the buffer regardless
222 // of how many were actually rendered. So to keep the benefits of that 228 // of how many were actually rendered. So to keep the benefits of that
223 // test, we explicitly pass 0 in here as the number of frames to 229 // test, we explicitly pass 0 in here as the number of frames to
224 // ZeroAudioData(). Other tests might want to pass the requested number 230 // ZeroAudioData(). Other tests might want to pass the requested number
225 // by using WithArgs<1, 0>(Invoke(&ZeroAudioData)) and set the return 231 // by using WithArgs<1, 0>(Invoke(&ZeroAudioData)) and set the return
226 // value accordingly. 232 // value accordingly.
227 const int kNumberOfFramesToProcess = 0; 233 const int kNumberOfFramesToProcess = 0;
228 234
229 EXPECT_CALL(callback_, Render(_, _, _)) 235 EXPECT_CALL(callback_, Render(_, _, _))
230 .WillOnce(DoAll( 236 .WillOnce(DoAll(
231 WithArgs<0>(Invoke( 237 WithArgs<0>(Invoke(
232 testing::CreateFunctor(&ZeroAudioData, 238 testing::CreateFunctor(&ZeroAudioData,
233 kNumberOfFramesToProcess))), 239 kNumberOfFramesToProcess))),
234 QuitLoop(io_loop_.message_loop_proxy()), 240 QuitLoop(io_loop_.message_loop_proxy()),
235 Return(kNumberOfFramesToProcess))); 241 Return(kNumberOfFramesToProcess)));
236 242
237 audio_device->OnStreamCreated(duplicated_memory_handle, audio_device_socket, 243 audio_device->OnStreamCreated(duplicated_memory_handle, audio_device_socket,
238 memory_size); 244 memory_size);
239 245
240 io_loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 246 io_loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
241 TestTimeouts::action_timeout()); 247 TestTimeouts::action_timeout());
242 io_loop_.Run(); 248 io_loop_.Run();
243 249
244 // Close the stream sequence. 250 // Close the stream sequence.
245 EXPECT_CALL(*audio_message_filter_, CloseStream(stream_id_)); 251 EXPECT_CALL(audio_output_ipc_, CloseStream(stream_id_));
246 252
247 audio_device->Stop(); 253 audio_device->Stop();
248 io_loop_.RunAllPending(); 254 io_loop_.RunAllPending();
249 } 255 }
256
257 } // namespace media.
OLDNEW
« no previous file with comments | « media/audio/audio_output_device.cc ('k') | media/audio/audio_output_ipc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698