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

Side by Side Diff: media/audio/audio_output_controller.h

Issue 11882010: Clean-up and bug fixes in AudioOutputController: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove all the NDEBUG. Created 7 years, 11 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 | « no previous file | media/audio/audio_output_controller.cc » ('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 #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
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_
OLDNEW
« no previous file with comments | « no previous file | media/audio/audio_output_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698