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 #include "media/audio/audio_output_controller.h" | 5 #include "media/audio/audio_output_controller.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <limits> | 10 #include <limits> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
14 #include "base/numerics/safe_conversions.h" | 14 #include "base/numerics/safe_conversions.h" |
15 #include "base/task_runner_util.h" | 15 #include "base/task_runner_util.h" |
16 #include "base/threading/platform_thread.h" | 16 #include "base/threading/platform_thread.h" |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
18 #include "base/trace_event/trace_event.h" | 18 #include "base/trace_event/trace_event.h" |
19 #include "media/base/audio_timestamp_helper.h" | |
19 | 20 |
20 using base::TimeDelta; | 21 using base::TimeDelta; |
21 | 22 |
22 namespace media { | 23 namespace media { |
23 | 24 |
24 AudioOutputController::AudioOutputController( | 25 AudioOutputController::AudioOutputController( |
25 AudioManager* audio_manager, | 26 AudioManager* audio_manager, |
26 EventHandler* handler, | 27 EventHandler* handler, |
27 const AudioParameters& params, | 28 const AudioParameters& params, |
28 const std::string& output_device_id, | 29 const std::string& output_device_id, |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 void AudioOutputController::DoPlay() { | 168 void AudioOutputController::DoPlay() { |
168 DCHECK(message_loop_->BelongsToCurrentThread()); | 169 DCHECK(message_loop_->BelongsToCurrentThread()); |
169 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime"); | 170 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime"); |
170 TRACE_EVENT0("audio", "AudioOutputController::DoPlay"); | 171 TRACE_EVENT0("audio", "AudioOutputController::DoPlay"); |
171 | 172 |
172 // We can start from created or paused state. | 173 // We can start from created or paused state. |
173 if (state_ != kCreated && state_ != kPaused) | 174 if (state_ != kCreated && state_ != kPaused) |
174 return; | 175 return; |
175 | 176 |
176 // Ask for first packet. | 177 // Ask for first packet. |
177 sync_reader_->UpdatePendingBytes(0, 0); | 178 sync_reader_->PrepareNextData(base::TimeDelta(), base::TimeTicks(), 0); |
178 | 179 |
179 state_ = kPlaying; | 180 state_ = kPlaying; |
180 | 181 |
181 stream_->Start(this); | 182 stream_->Start(this); |
182 | 183 |
183 // For UMA tracking purposes, start the wedge detection timer. This allows us | 184 // For UMA tracking purposes, start the wedge detection timer. This allows us |
184 // to record statistics about the number of wedged playbacks in the field. | 185 // to record statistics about the number of wedged playbacks in the field. |
185 // | 186 // |
186 // WedgeCheck() will look to see if |on_more_io_data_called_| is true after | 187 // WedgeCheck() will look to see if |on_more_io_data_called_| is true after |
187 // the timeout expires. Care must be taken to ensure the wedge check delay is | 188 // the timeout expires. Care must be taken to ensure the wedge check delay is |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 TRACE_EVENT0("audio", "AudioOutputController::DoPause"); | 221 TRACE_EVENT0("audio", "AudioOutputController::DoPause"); |
221 | 222 |
222 StopStream(); | 223 StopStream(); |
223 | 224 |
224 if (state_ != kPaused) | 225 if (state_ != kPaused) |
225 return; | 226 return; |
226 | 227 |
227 // Let the renderer know we've stopped. Necessary to let PPAPI clients know | 228 // Let the renderer know we've stopped. Necessary to let PPAPI clients know |
228 // audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have | 229 // audio has been shutdown. TODO(dalecurtis): This stinks. PPAPI should have |
229 // a better way to know when it should exit PPB_Audio_Shared::Run(). | 230 // a better way to know when it should exit PPB_Audio_Shared::Run(). |
230 sync_reader_->UpdatePendingBytes(std::numeric_limits<uint32_t>::max(), 0); | 231 sync_reader_->PrepareNextData(base::TimeDelta::Max(), base::TimeTicks(), 0); |
231 | 232 |
232 handler_->OnPaused(); | 233 handler_->OnPaused(); |
233 } | 234 } |
234 | 235 |
235 void AudioOutputController::DoClose() { | 236 void AudioOutputController::DoClose() { |
236 DCHECK(message_loop_->BelongsToCurrentThread()); | 237 DCHECK(message_loop_->BelongsToCurrentThread()); |
237 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime"); | 238 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.CloseTime"); |
238 TRACE_EVENT0("audio", "AudioOutputController::DoClose"); | 239 TRACE_EVENT0("audio", "AudioOutputController::DoClose"); |
239 | 240 |
240 if (state_ != kClosed) { | 241 if (state_ != kClosed) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
301 | 302 |
302 // Indicate that we haven't wedged (at least not indefinitely, WedgeCheck() | 303 // Indicate that we haven't wedged (at least not indefinitely, WedgeCheck() |
303 // may have already fired if OnMoreData() took an abnormal amount of time). | 304 // may have already fired if OnMoreData() took an abnormal amount of time). |
304 // Since this thread is the only writer of |on_more_io_data_called_| once the | 305 // Since this thread is the only writer of |on_more_io_data_called_| once the |
305 // thread starts, its safe to compare and then increment. | 306 // thread starts, its safe to compare and then increment. |
306 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) | 307 if (base::AtomicRefCountIsZero(&on_more_io_data_called_)) |
307 base::AtomicRefCountInc(&on_more_io_data_called_); | 308 base::AtomicRefCountInc(&on_more_io_data_called_); |
308 | 309 |
309 sync_reader_->Read(dest); | 310 sync_reader_->Read(dest); |
310 | 311 |
311 const int total_bytes_delay = | |
312 delay.InSecondsF() * params_.GetBytesPerSecond(); | |
313 const int frames = dest->frames(); | 312 const int frames = dest->frames(); |
314 sync_reader_->UpdatePendingBytes( | 313 |
315 total_bytes_delay + frames * params_.GetBytesPerFrame(), | 314 sync_reader_->PrepareNextData(delay, delay_timestamp, prior_frames_skipped); |
chcunningham
2016/10/21 18:19:47
Why aren't you adding in the delay for the dest bu
|
chcunningham
2016/10/21 18:19:47
Nit: What do you think about "RequestMoreData"? It
Mikhail
2016/10/24 19:50:24
Agree, "RequestMoreData" is better. thanks!
|
316 prior_frames_skipped); | |
317 | 315 |
318 bool need_to_duplicate = false; | 316 bool need_to_duplicate = false; |
319 { | 317 { |
320 base::AutoLock lock(duplication_targets_lock_); | 318 base::AutoLock lock(duplication_targets_lock_); |
321 need_to_duplicate = !duplication_targets_.empty(); | 319 need_to_duplicate = !duplication_targets_.empty(); |
322 } | 320 } |
323 if (need_to_duplicate) { | 321 if (need_to_duplicate) { |
324 const base::TimeTicks reference_time = delay_timestamp + delay; | 322 const base::TimeTicks reference_time = delay_timestamp + delay; |
325 std::unique_ptr<AudioBus> copy(AudioBus::Create(params_)); | 323 std::unique_ptr<AudioBus> copy(AudioBus::Create(params_)); |
326 dest->CopyTo(copy.get()); | 324 dest->CopyTo(copy.get()); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 DCHECK(message_loop_->BelongsToCurrentThread()); | 504 DCHECK(message_loop_->BelongsToCurrentThread()); |
507 | 505 |
508 // If we should be playing and we haven't, that's a wedge. | 506 // If we should be playing and we haven't, that's a wedge. |
509 if (state_ == kPlaying) { | 507 if (state_ == kPlaying) { |
510 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", | 508 UMA_HISTOGRAM_BOOLEAN("Media.AudioOutputControllerPlaybackStartupSuccess", |
511 base::AtomicRefCountIsOne(&on_more_io_data_called_)); | 509 base::AtomicRefCountIsOne(&on_more_io_data_called_)); |
512 } | 510 } |
513 } | 511 } |
514 | 512 |
515 } // namespace media | 513 } // namespace media |
OLD | NEW |