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::PollAndStartIfDataReady, this), |
| 191 kPollPauseInMilliseconds); |
| 192 } else { |
| 193 StartStream(); |
| 194 } |
| 195 } |
| 196 |
| 197 void AudioOutputController::PollAndStartIfDataReady() { |
| 198 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 199 |
| 200 // Being paranoic: do nothing if we were stopped/paused |
| 201 // after DoPlay() but before DoStartStream(). |
| 202 if (state_ != kPlaying) |
| 203 return; |
| 204 |
| 205 if (--number_polling_attempts_left_ == 0 || sync_reader_->DataReady()) { |
| 206 StartStream(); |
| 207 } else { |
| 208 message_loop_->PostDelayedTask( |
| 209 FROM_HERE, |
| 210 base::Bind(&AudioOutputController::PollAndStartIfDataReady, this), |
| 211 kPollPauseInMilliseconds); |
| 212 } |
| 213 } |
| 214 |
| 215 void AudioOutputController::StartStream() { |
| 216 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 217 |
176 // We start the AudioOutputStream lazily. | 218 // We start the AudioOutputStream lazily. |
177 stream_->Start(this); | 219 stream_->Start(this); |
178 | 220 |
179 // Tell the event handler that we are now playing. | 221 // Tell the event handler that we are now playing. |
180 handler_->OnPlaying(this); | 222 handler_->OnPlaying(this); |
181 } | 223 } |
182 | 224 |
183 void AudioOutputController::DoPause() { | 225 void AudioOutputController::DoPause() { |
184 DCHECK_EQ(message_loop_, MessageLoop::current()); | 226 DCHECK_EQ(message_loop_, MessageLoop::current()); |
185 | 227 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 buffers_state.pending_bytes += buffer_.forward_bytes(); | 348 buffers_state.pending_bytes += buffer_.forward_bytes(); |
307 | 349 |
308 // If we need more data then call the event handler to ask for more data. | 350 // 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 | 351 // 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. | 352 // correct and in the worst case we are just asking more data than needed. |
311 base::AutoUnlock auto_unlock(lock_); | 353 base::AutoUnlock auto_unlock(lock_); |
312 handler_->OnMoreData(this, buffers_state); | 354 handler_->OnMoreData(this, buffers_state); |
313 } | 355 } |
314 | 356 |
315 } // namespace media | 357 } // namespace media |
OLD | NEW |