OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 | 10 |
11 namespace media { | 11 namespace media { |
12 | 12 |
13 // Signal a pause in low-latency mode. | 13 // Signal a pause in low-latency mode. |
14 const int AudioOutputController::kPauseMark = -1; | 14 const int AudioOutputController::kPauseMark = -1; |
15 | 15 |
16 // Polling-related constants. | |
17 const int AudioOutputController::kPollNumAttempts = 3; | |
18 const int AudioOutputController::kPollPauseInMilliseconds = 3; | |
19 | |
16 AudioOutputController::AudioOutputController(EventHandler* handler, | 20 AudioOutputController::AudioOutputController(EventHandler* handler, |
17 uint32 capacity, | 21 uint32 capacity, |
18 SyncReader* sync_reader) | 22 SyncReader* sync_reader) |
19 : handler_(handler), | 23 : handler_(handler), |
20 stream_(NULL), | 24 stream_(NULL), |
21 volume_(1.0), | 25 volume_(1.0), |
22 state_(kEmpty), | 26 state_(kEmpty), |
23 buffer_(0, capacity), | 27 buffer_(0, capacity), |
24 pending_request_(false), | 28 pending_request_(false), |
25 sync_reader_(sync_reader), | 29 sync_reader_(sync_reader), |
26 message_loop_(NULL) { | 30 message_loop_(NULL), |
31 number_polling_attempts_left_(0) { | |
27 } | 32 } |
28 | 33 |
29 AudioOutputController::~AudioOutputController() { | 34 AudioOutputController::~AudioOutputController() { |
30 DCHECK_EQ(kClosed, state_); | 35 DCHECK_EQ(kClosed, state_); |
31 } | 36 } |
32 | 37 |
33 // static | 38 // static |
34 scoped_refptr<AudioOutputController> AudioOutputController::Create( | 39 scoped_refptr<AudioOutputController> AudioOutputController::Create( |
35 EventHandler* event_handler, | 40 EventHandler* event_handler, |
36 const AudioParameters& params, | 41 const AudioParameters& params, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
166 } | 171 } |
167 | 172 |
168 void AudioOutputController::DoPlay() { | 173 void AudioOutputController::DoPlay() { |
169 DCHECK_EQ(message_loop_, MessageLoop::current()); | 174 DCHECK_EQ(message_loop_, MessageLoop::current()); |
170 | 175 |
171 // We can start from created or paused state. | 176 // We can start from created or paused state. |
172 if (state_ != kCreated && state_ != kPaused) | 177 if (state_ != kCreated && state_ != kPaused) |
173 return; | 178 return; |
174 state_ = kPlaying; | 179 state_ = kPlaying; |
175 | 180 |
181 if (LowLatencyMode()) { | |
182 // Ask for first packet. | |
183 sync_reader_->UpdatePendingBytes(0); | |
184 | |
185 // Cannot start stream immediately, should give renderer some time | |
186 // to deliver data. | |
187 number_polling_attempts_left_ = kPollNumAttempts; | |
188 message_loop_->PostDelayedTask( | |
189 FROM_HERE, | |
190 base::Bind(&AudioOutputController::DoPollIfDataReady, this), | |
191 kPollPauseInMilliseconds); | |
192 } else | |
193 StartStream(); | |
194 } | |
195 | |
196 void AudioOutputController::DoPollIfDataReady() { | |
acolwell GONE FROM CHROMIUM
2011/10/12 20:14:03
PollAndStartIfDataReady() might be a little more c
enal1
2011/10/13 00:39:22
Done.
| |
197 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
198 | |
199 // Being paranoic: do nothing if we were stopped/paused | |
200 // after DoPlay() but before DoStartStream(). | |
201 if (state_ != kPlaying) | |
202 return; | |
203 | |
204 if (--number_polling_attempts_left_ == 0 || sync_reader_->DataReady()) | |
205 StartStream(); | |
206 else { | |
207 message_loop_->PostDelayedTask( | |
208 FROM_HERE, | |
209 base::Bind(&AudioOutputController::DoPollIfDataReady, this), | |
210 kPollPauseInMilliseconds); | |
211 } | |
212 } | |
213 | |
214 void AudioOutputController::StartStream() { | |
215 DCHECK_EQ(message_loop_, MessageLoop::current()); | |
216 | |
176 // We start the AudioOutputStream lazily. | 217 // We start the AudioOutputStream lazily. |
177 stream_->Start(this); | 218 stream_->Start(this); |
178 | 219 |
179 // Tell the event handler that we are now playing. | 220 // Tell the event handler that we are now playing. |
180 handler_->OnPlaying(this); | 221 handler_->OnPlaying(this); |
181 } | 222 } |
182 | 223 |
183 void AudioOutputController::DoPause() { | 224 void AudioOutputController::DoPause() { |
184 DCHECK_EQ(message_loop_, MessageLoop::current()); | 225 DCHECK_EQ(message_loop_, MessageLoop::current()); |
185 | 226 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
306 buffers_state.pending_bytes += buffer_.forward_bytes(); | 347 buffers_state.pending_bytes += buffer_.forward_bytes(); |
307 | 348 |
308 // If we need more data then call the event handler to ask for more data. | 349 // If we need more data then call the event handler to ask for more data. |
309 // It is okay that we don't lock in this block because the parameters are | 350 // It is okay that we don't lock in this block because the parameters are |
310 // correct and in the worst case we are just asking more data than needed. | 351 // correct and in the worst case we are just asking more data than needed. |
311 base::AutoUnlock auto_unlock(lock_); | 352 base::AutoUnlock auto_unlock(lock_); |
312 handler_->OnMoreData(this, buffers_state); | 353 handler_->OnMoreData(this, buffers_state); |
313 } | 354 } |
314 | 355 |
315 } // namespace media | 356 } // namespace media |
OLD | NEW |