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

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

Issue 4661001: Simplified AudioOutputStream interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 10 years, 1 month 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_controller.h ('k') | media/audio/audio_output_controller_unittest.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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "media/audio/audio_output_controller.h" 5 #include "media/audio/audio_output_controller.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 8
9 // The following parameters limit the request buffer and packet size from the
10 // renderer to avoid renderer from requesting too much memory.
11 static const uint32 kMegabytes = 1024 * 1024;
12 static const uint32 kMaxHardwareBufferSize = 2 * kMegabytes;
13 // Signal a pause in low-latency mode. 9 // Signal a pause in low-latency mode.
14 static const int kPauseMark = -1; 10 static const int kPauseMark = -1;
15 11
16 namespace { 12 namespace {
17 // Return true if the parameters for creating an audio stream is valid. 13 // Return true if the parameters for creating an audio stream is valid.
18 // Return false otherwise. 14 // Return false otherwise.
19 static bool CheckParameters(AudioParameters params, 15 static bool CheckParameters(AudioParameters params) {
20 uint32 hardware_buffer_size) {
21 if (!params.IsValid()) 16 if (!params.IsValid())
22 return false; 17 return false;
23 if (hardware_buffer_size <= 0 ||
24 hardware_buffer_size > kMaxHardwareBufferSize)
25 return false;
26 return true; 18 return true;
27 } 19 }
28 20
29 } // namespace 21 } // namespace
30 22
31 namespace media { 23 namespace media {
32 24
33 AudioOutputController::AudioOutputController(EventHandler* handler, 25 AudioOutputController::AudioOutputController(EventHandler* handler,
34 uint32 capacity, 26 uint32 capacity,
35 SyncReader* sync_reader) 27 SyncReader* sync_reader)
36 : handler_(handler), 28 : handler_(handler),
37 stream_(NULL), 29 stream_(NULL),
38 volume_(1.0), 30 volume_(1.0),
39 state_(kEmpty), 31 state_(kEmpty),
40 buffer_(0, capacity), 32 buffer_(0, capacity),
41 pending_request_(false), 33 pending_request_(false),
42 sync_reader_(sync_reader), 34 sync_reader_(sync_reader),
43 message_loop_(NULL) { 35 message_loop_(NULL) {
44 } 36 }
45 37
46 AudioOutputController::~AudioOutputController() { 38 AudioOutputController::~AudioOutputController() {
47 DCHECK(kClosed == state_); 39 DCHECK(kClosed == state_);
48 } 40 }
49 41
50 // static 42 // static
51 scoped_refptr<AudioOutputController> AudioOutputController::Create( 43 scoped_refptr<AudioOutputController> AudioOutputController::Create(
52 EventHandler* event_handler, 44 EventHandler* event_handler,
53 AudioParameters params, 45 AudioParameters params,
54 uint32 hardware_buffer_size,
55 uint32 buffer_capacity) { 46 uint32 buffer_capacity) {
56 47
57 if (!CheckParameters(params, hardware_buffer_size)) 48 if (!CheckParameters(params))
58 return NULL; 49 return NULL;
59 50
60 // Starts the audio controller thread. 51 // Starts the audio controller thread.
61 scoped_refptr<AudioOutputController> controller(new AudioOutputController( 52 scoped_refptr<AudioOutputController> controller(new AudioOutputController(
62 event_handler, buffer_capacity, NULL)); 53 event_handler, buffer_capacity, NULL));
63 54
64 controller->message_loop_ = 55 controller->message_loop_ =
65 AudioManager::GetAudioManager()->GetMessageLoop(); 56 AudioManager::GetAudioManager()->GetMessageLoop();
66 controller->message_loop_->PostTask( 57 controller->message_loop_->PostTask(
67 FROM_HERE, 58 FROM_HERE,
68 NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate, 59 NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate,
69 params, hardware_buffer_size)); 60 params));
70 return controller; 61 return controller;
71 } 62 }
72 63
73 // static 64 // static
74 scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency( 65 scoped_refptr<AudioOutputController> AudioOutputController::CreateLowLatency(
75 EventHandler* event_handler, 66 EventHandler* event_handler,
76 AudioParameters params, 67 AudioParameters params,
77 uint32 hardware_buffer_size,
78 SyncReader* sync_reader) { 68 SyncReader* sync_reader) {
79 69
80 DCHECK(sync_reader); 70 DCHECK(sync_reader);
81 71
82 if (!CheckParameters(params, hardware_buffer_size)) 72 if (!CheckParameters(params))
83 return NULL; 73 return NULL;
84 74
85 // Starts the audio controller thread. 75 // Starts the audio controller thread.
86 scoped_refptr<AudioOutputController> controller(new AudioOutputController( 76 scoped_refptr<AudioOutputController> controller(new AudioOutputController(
87 event_handler, 0, sync_reader)); 77 event_handler, 0, sync_reader));
88 78
89 controller->message_loop_ = 79 controller->message_loop_ =
90 AudioManager::GetAudioManager()->GetMessageLoop(); 80 AudioManager::GetAudioManager()->GetMessageLoop();
91 controller->message_loop_->PostTask( 81 controller->message_loop_->PostTask(
92 FROM_HERE, 82 FROM_HERE,
93 NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate, 83 NewRunnableMethod(controller.get(), &AudioOutputController::DoCreate,
94 params, hardware_buffer_size)); 84 params));
95 return controller; 85 return controller;
96 } 86 }
97 87
98 void AudioOutputController::Play() { 88 void AudioOutputController::Play() {
99 DCHECK(message_loop_); 89 DCHECK(message_loop_);
100 message_loop_->PostTask( 90 message_loop_->PostTask(
101 FROM_HERE, 91 FROM_HERE,
102 NewRunnableMethod(this, &AudioOutputController::DoPlay)); 92 NewRunnableMethod(this, &AudioOutputController::DoPlay));
103 } 93 }
104 94
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 pending_request_ = false; 127 pending_request_ = false;
138 // If |size| is set to 0, it indicates that the audio source doesn't have 128 // If |size| is set to 0, it indicates that the audio source doesn't have
139 // more data right now, and so it doesn't make sense to send additional 129 // more data right now, and so it doesn't make sense to send additional
140 // request. 130 // request.
141 if (size) { 131 if (size) {
142 buffer_.Append(data, size); 132 buffer_.Append(data, size);
143 SubmitOnMoreData_Locked(); 133 SubmitOnMoreData_Locked();
144 } 134 }
145 } 135 }
146 136
147 void AudioOutputController::DoCreate(AudioParameters params, 137 void AudioOutputController::DoCreate(AudioParameters params) {
148 uint32 hardware_buffer_size) {
149 DCHECK_EQ(message_loop_, MessageLoop::current()); 138 DCHECK_EQ(message_loop_, MessageLoop::current());
150 139
151 // Close() can be called before DoCreate() is executed. 140 // Close() can be called before DoCreate() is executed.
152 if (state_ == kClosed) 141 if (state_ == kClosed)
153 return; 142 return;
154 DCHECK(state_ == kEmpty); 143 DCHECK(state_ == kEmpty);
155 144
156 stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream(params); 145 stream_ = AudioManager::GetAudioManager()->MakeAudioOutputStream(params);
157 if (!stream_) { 146 if (!stream_) {
158 // TODO(hclam): Define error types. 147 // TODO(hclam): Define error types.
159 handler_->OnError(this, 0); 148 handler_->OnError(this, 0);
160 return; 149 return;
161 } 150 }
162 151
163 if (!stream_->Open(hardware_buffer_size)) { 152 if (!stream_->Open()) {
164 stream_->Close(); 153 stream_->Close();
165 stream_ = NULL; 154 stream_ = NULL;
166 155
167 // TODO(hclam): Define error types. 156 // TODO(hclam): Define error types.
168 handler_->OnError(this, 0); 157 handler_->OnError(this, 0);
169 return; 158 return;
170 } 159 }
160
171 // We have successfully opened the stream. Set the initial volume. 161 // We have successfully opened the stream. Set the initial volume.
172 stream_->SetVolume(volume_); 162 stream_->SetVolume(volume_);
173 163
174 // Finally set the state to kCreated. 164 // Finally set the state to kCreated.
175 state_ = kCreated; 165 state_ = kCreated;
176 166
177 // And then report we have been created. 167 // And then report we have been created.
178 handler_->OnCreated(this); 168 handler_->OnCreated(this);
179 169
180 // If in normal latency mode then start buffering. 170 // If in normal latency mode then start buffering.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 if (state_ != kClosed) { 229 if (state_ != kClosed) {
240 // |stream_| can be null if creating the device failed in DoCreate(). 230 // |stream_| can be null if creating the device failed in DoCreate().
241 if (stream_) { 231 if (stream_) {
242 stream_->Stop(); 232 stream_->Stop();
243 stream_->Close(); 233 stream_->Close();
244 // After stream is closed it is destroyed, so don't keep a reference to 234 // After stream is closed it is destroyed, so don't keep a reference to
245 // it. 235 // it.
246 stream_ = NULL; 236 stream_ = NULL;
247 } 237 }
248 238
239 if (LowLatencyMode()) {
240 sync_reader_->Close();
241 }
242
249 state_ = kClosed; 243 state_ = kClosed;
250 } 244 }
251 245
252 closed_task->Run(); 246 closed_task->Run();
253 delete closed_task; 247 delete closed_task;
254 } 248 }
255 249
256 void AudioOutputController::DoSetVolume(double volume) { 250 void AudioOutputController::DoSetVolume(double volume) {
257 DCHECK_EQ(message_loop_, MessageLoop::current()); 251 DCHECK_EQ(message_loop_, MessageLoop::current());
258 252
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 SubmitOnMoreData_Locked(); 286 SubmitOnMoreData_Locked();
293 return size; 287 return size;
294 } 288 }
295 289
296 // Low latency mode. 290 // Low latency mode.
297 uint32 size = sync_reader_->Read(dest, max_size); 291 uint32 size = sync_reader_->Read(dest, max_size);
298 sync_reader_->UpdatePendingBytes(buffers_state.total_bytes() + size); 292 sync_reader_->UpdatePendingBytes(buffers_state.total_bytes() + size);
299 return size; 293 return size;
300 } 294 }
301 295
302 void AudioOutputController::OnClose(AudioOutputStream* stream) {
303 DCHECK_EQ(message_loop_, MessageLoop::current());
304
305 // Push source doesn't need to know the stream so just pass in NULL.
306 if (LowLatencyMode()) {
307 sync_reader_->Close();
308 }
309 }
310
311 void AudioOutputController::OnError(AudioOutputStream* stream, int code) { 296 void AudioOutputController::OnError(AudioOutputStream* stream, int code) {
312 // Handle error on the audio controller thread. 297 // Handle error on the audio controller thread.
313 message_loop_->PostTask( 298 message_loop_->PostTask(
314 FROM_HERE, 299 FROM_HERE,
315 NewRunnableMethod(this, &AudioOutputController::DoReportError, code)); 300 NewRunnableMethod(this, &AudioOutputController::DoReportError, code));
316 } 301 }
317 302
318 void AudioOutputController::SubmitOnMoreData_Locked() { 303 void AudioOutputController::SubmitOnMoreData_Locked() {
319 lock_.AssertAcquired(); 304 lock_.AssertAcquired();
320 305
321 if (buffer_.forward_bytes() > buffer_.forward_capacity()) 306 if (buffer_.forward_bytes() > buffer_.forward_capacity())
322 return; 307 return;
323 308
324 if (pending_request_) 309 if (pending_request_)
325 return; 310 return;
326 pending_request_ = true; 311 pending_request_ = true;
327 312
328 AudioBuffersState buffers_state = buffers_state_; 313 AudioBuffersState buffers_state = buffers_state_;
329 buffers_state.pending_bytes += buffer_.forward_bytes(); 314 buffers_state.pending_bytes += buffer_.forward_bytes();
330 315
331 // If we need more data then call the event handler to ask for more data. 316 // If we need more data then call the event handler to ask for more data.
332 // It is okay that we don't lock in this block because the parameters are 317 // It is okay that we don't lock in this block because the parameters are
333 // correct and in the worst case we are just asking more data than needed. 318 // correct and in the worst case we are just asking more data than needed.
334 AutoUnlock auto_unlock(lock_); 319 AutoUnlock auto_unlock(lock_);
335 handler_->OnMoreData(this, buffers_state); 320 handler_->OnMoreData(this, buffers_state);
336 } 321 }
337 322
338 } // namespace media 323 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698