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 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ | 5 #ifndef MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ |
6 #define MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ | 6 #define MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ |
7 | 7 |
| 8 #include "base/atomic_ref_count.h" |
8 #include "base/callback.h" | 9 #include "base/callback.h" |
9 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
10 #include "base/memory/weak_ptr.h" | 11 #include "base/memory/weak_ptr.h" |
11 #include "base/synchronization/lock.h" | |
12 #include "media/audio/audio_buffers_state.h" | 12 #include "media/audio/audio_buffers_state.h" |
13 #include "media/audio/audio_io.h" | 13 #include "media/audio/audio_io.h" |
14 #include "media/audio/audio_manager.h" | 14 #include "media/audio/audio_manager.h" |
15 #include "media/audio/audio_source_diverter.h" | 15 #include "media/audio/audio_source_diverter.h" |
16 #include "media/audio/simple_sources.h" | 16 #include "media/audio/simple_sources.h" |
17 #include "media/base/media_export.h" | 17 #include "media/base/media_export.h" |
18 | 18 |
19 namespace base { | |
20 class WaitableEvent; | |
21 } // namespace base | |
22 | |
23 class MessageLoop; | 19 class MessageLoop; |
24 | 20 |
25 // An AudioOutputController controls an AudioOutputStream and provides data | 21 // An AudioOutputController controls an AudioOutputStream and provides data |
26 // to this output stream. It has an important function that it executes | 22 // to this output stream. It has an important function that it executes |
27 // audio operations like play, pause, stop, etc. on a separate thread, | 23 // audio operations like play, pause, stop, etc. on a separate thread, |
28 // namely the audio manager thread. | 24 // namely the audio manager thread. |
29 // | 25 // |
30 // All the public methods of AudioOutputController are non-blocking. | 26 // All the public methods of AudioOutputController are non-blocking. |
31 // The actual operations are performed on the audio manager thread. | 27 // The actual operations are performed on the audio manager thread. |
32 // | 28 // |
33 // Here is a state diagram for the AudioOutputController: | 29 // Here is a state transition diagram for the AudioOutputController: |
34 // | 30 // |
35 // .-----------------------> [ Closed / Error ] <------. | 31 // *[ Empty ] --> [ Created ] --> [ Starting ] --> [ Playing ] --. |
36 // | ^ | | 32 // | | | ^ | | |
37 // | | | | 33 // | | | | | | |
38 // [ Created ] --> [ Starting ] --> [ Playing ] --> [ Paused ] | 34 // | | | | v | |
39 // ^ | ^ | ^ | 35 // | | | `--------- [ Paused ] | |
40 // | | | | | | 36 // | | | | | |
41 // | | `----------------' | | 37 // | v v | | |
42 // | V | | 38 // `-----------> [ Closed ] <-------------------------' |
43 // | [ PausedWhenStarting ] ------------------------' | |
44 // | | |
45 // *[ Empty ] | |
46 // | 39 // |
47 // * Initial state | 40 // * Initial state |
48 // | 41 // |
49 // At any time after reaching the Created state but before Closed / Error, the | 42 // At any time after reaching the Created state but before Closed, the |
50 // AudioOutputController may be notified of a device change via OnDeviceChange() | 43 // AudioOutputController may be notified of a device change via |
51 // and transition to the Recreating state. If OnDeviceChange() completes | 44 // OnDeviceChange(). As the OnDeviceChange() is processed, state transitions |
52 // successfully the state will transition back to an equivalent pre-call state. | 45 // will occur, ultimately ending up in an equivalent pre-call state. E.g., if |
53 // E.g., if the state was Paused or PausedWhenStarting, the new state will be | 46 // the state was Paused, the new state will be Created, since these states are |
54 // Created, since these states are all functionally equivalent and require a | 47 // all functionally equivalent and require a Play() call to continue to the next |
55 // Play() call to continue to the next state. | 48 // state. |
56 // | 49 // |
57 // The AudioOutputStream can request data from the AudioOutputController via the | 50 // The AudioOutputStream can request data from the AudioOutputController via the |
58 // AudioSourceCallback interface. AudioOutputController uses the SyncReader | 51 // AudioSourceCallback interface. AudioOutputController uses the SyncReader |
59 // passed to it via construction to synchronously fulfill this read request. | 52 // passed to it via construction to synchronously fulfill this read request. |
60 // | 53 // |
61 // Since AudioOutputController uses AudioManager's message loop the controller | 54 // Since AudioOutputController uses AudioManager's message loop the controller |
62 // uses WeakPtr to allow safe cancellation of pending tasks. | 55 // uses WeakPtr to allow safe cancellation of pending tasks. |
63 // | 56 // |
64 | 57 |
65 namespace media { | 58 namespace media { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 // AudioSourceDiverter implementation. | 152 // AudioSourceDiverter implementation. |
160 virtual const AudioParameters& GetAudioParameters() OVERRIDE; | 153 virtual const AudioParameters& GetAudioParameters() OVERRIDE; |
161 virtual void StartDiverting(AudioOutputStream* to_stream) OVERRIDE; | 154 virtual void StartDiverting(AudioOutputStream* to_stream) OVERRIDE; |
162 virtual void StopDiverting() OVERRIDE; | 155 virtual void StopDiverting() OVERRIDE; |
163 | 156 |
164 protected: | 157 protected: |
165 // Internal state of the source. | 158 // Internal state of the source. |
166 enum State { | 159 enum State { |
167 kEmpty, | 160 kEmpty, |
168 kCreated, | 161 kCreated, |
| 162 kStarting, |
169 kPlaying, | 163 kPlaying, |
170 kStarting, | |
171 kPausedWhenStarting, | |
172 kPaused, | 164 kPaused, |
173 kClosed, | 165 kClosed, |
174 kError, | 166 kError, |
175 kRecreating, | |
176 }; | 167 }; |
177 | 168 |
178 friend class base::RefCountedThreadSafe<AudioOutputController>; | 169 friend class base::RefCountedThreadSafe<AudioOutputController>; |
179 virtual ~AudioOutputController(); | 170 virtual ~AudioOutputController(); |
180 | 171 |
181 private: | 172 private: |
182 // We are polling sync reader if data became available. | 173 // We are polling sync reader if data became available. |
183 static const int kPollNumAttempts; | 174 static const int kPollNumAttempts; |
184 static const int kPollPauseInMilliseconds; | 175 static const int kPollPauseInMilliseconds; |
185 | 176 |
186 AudioOutputController(AudioManager* audio_manager, EventHandler* handler, | 177 AudioOutputController(AudioManager* audio_manager, EventHandler* handler, |
187 const AudioParameters& params, SyncReader* sync_reader); | 178 const AudioParameters& params, SyncReader* sync_reader); |
188 | 179 |
189 // The following methods are executed on the audio manager thread. | 180 // The following methods are executed on the audio manager thread. |
190 void DoCreate(); | 181 void DoCreate(bool is_for_device_change); |
191 void DoPlay(); | 182 void DoPlay(); |
192 void PollAndStartIfDataReady(); | 183 void PollAndStartIfDataReady(); |
193 void DoPause(); | 184 void DoPause(); |
194 void DoFlush(); | 185 void DoFlush(); |
195 void DoClose(); | 186 void DoClose(); |
196 void DoSetVolume(double volume); | 187 void DoSetVolume(double volume); |
197 void DoReportError(int code); | 188 void DoReportError(int code); |
198 void DoStartDiverting(AudioOutputStream* to_stream); | 189 void DoStartDiverting(AudioOutputStream* to_stream); |
199 void DoStopDiverting(); | 190 void DoStopDiverting(); |
200 | 191 |
201 // Helper method that starts physical stream. | 192 // Helper methods that start/stop physical stream. |
202 void StartStream(); | 193 void StartStream(); |
| 194 void StopStream(); |
203 | 195 |
204 // Helper method that stops, closes, and NULLs |*stream_|. | 196 // Helper method that stops, closes, and NULLs |*stream_|. |
205 // Signals event when done if it is not NULL. | 197 void DoStopCloseAndClearStream(); |
206 void DoStopCloseAndClearStream(base::WaitableEvent *done); | 198 |
| 199 // Sanity-check that entry/exit to OnMoreIOData() by the hardware audio thread |
| 200 // happens only between AudioOutputStream::Start() and Stop(). |
| 201 void AllowEntryToOnMoreIOData(); |
| 202 void DisallowEntryToOnMoreIOData(); |
207 | 203 |
208 AudioManager* const audio_manager_; | 204 AudioManager* const audio_manager_; |
209 const AudioParameters params_; | 205 const AudioParameters params_; |
210 | 206 EventHandler* const handler_; |
211 // |handler_| may be called only if |state_| is not kClosed. | |
212 EventHandler* handler_; | |
213 | 207 |
214 // Note: It's important to invalidate the weak pointers whenever stream_ is | 208 // Note: It's important to invalidate the weak pointers whenever stream_ is |
215 // changed. See comment for weak_this_. | 209 // changed. See comment for weak_this_. |
216 AudioOutputStream* stream_; | 210 AudioOutputStream* stream_; |
217 | 211 |
218 // When non-NULL, audio is being diverted to this stream. | 212 // When non-NULL, audio is being diverted to this stream. |
219 AudioOutputStream* diverting_to_stream_; | 213 AudioOutputStream* diverting_to_stream_; |
220 | 214 |
221 // The current volume of the audio stream. | 215 // The current volume of the audio stream. |
222 double volume_; | 216 double volume_; |
223 | 217 |
224 // |state_| is written on the audio manager thread and is read on the | 218 // |state_| is written on the audio manager thread and is read on the |
225 // hardware audio thread. These operations need to be locked. But lock | 219 // hardware audio thread. These operations need to be locked. But lock |
226 // is not required for reading on the audio manager thread. | 220 // is not required for reading on the audio manager thread. |
227 State state_; | 221 State state_; |
228 | 222 |
229 // The |lock_| must be acquired whenever we access |state_| from a thread | 223 // Binary semaphore, used to ensure that only one thread enters the |
230 // other than the audio manager thread. | 224 // OnMoreIOData() method, and only when it is valid to do so. This is for |
231 base::Lock lock_; | 225 // sanity-checking the behavior of platform implementations of |
| 226 // AudioOutputStream. In other words, multiple contention is not expected, |
| 227 // nor in the design here. |
| 228 base::AtomicRefCount num_allowed_io_; |
232 | 229 |
233 // SyncReader is used only in low latency mode for synchronous reading. | 230 // SyncReader is used only in low latency mode for synchronous reading. |
234 SyncReader* sync_reader_; | 231 SyncReader* const sync_reader_; |
235 | 232 |
236 // The message loop of audio manager thread that this object runs on. | 233 // The message loop of audio manager thread that this object runs on. |
237 scoped_refptr<base::MessageLoopProxy> message_loop_; | 234 const scoped_refptr<base::MessageLoopProxy> message_loop_; |
238 | 235 |
239 // When starting stream we wait for data to become available. | 236 // When starting stream we wait for data to become available. |
240 // Number of times left. | 237 // Number of times left. |
241 int number_polling_attempts_left_; | 238 int number_polling_attempts_left_; |
242 | 239 |
243 // Used to auto-cancel the delayed tasks that are created to poll for data | 240 // Used to auto-cancel the delayed tasks that are created to poll for data |
244 // (when starting-up a stream). | 241 // (when starting-up a stream). |
245 base::WeakPtrFactory<AudioOutputController> weak_this_; | 242 base::WeakPtrFactory<AudioOutputController> weak_this_; |
246 | 243 |
247 DISALLOW_COPY_AND_ASSIGN(AudioOutputController); | 244 DISALLOW_COPY_AND_ASSIGN(AudioOutputController); |
248 }; | 245 }; |
249 | 246 |
250 } // namespace media | 247 } // namespace media |
251 | 248 |
252 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ | 249 #endif // MEDIA_AUDIO_AUDIO_OUTPUT_CONTROLLER_H_ |
OLD | NEW |