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/filters/audio_renderer_impl.h" | 5 #include "media/filters/audio_renderer_impl.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "media/base/filter_host.h" | 13 #include "media/base/filter_host.h" |
14 #include "media/audio/audio_util.h" | 14 #include "media/audio/audio_util.h" |
15 | 15 |
16 namespace media { | 16 namespace media { |
17 | 17 |
18 AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink) | 18 AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink) |
19 : host_(NULL), | 19 : state_(kUninitialized), |
20 state_(kUninitialized), | |
21 pending_read_(false), | 20 pending_read_(false), |
22 received_end_of_stream_(false), | 21 received_end_of_stream_(false), |
23 rendered_end_of_stream_(false), | 22 rendered_end_of_stream_(false), |
24 audio_time_buffered_(kNoTimestamp()), | 23 audio_time_buffered_(kNoTimestamp()), |
25 current_time_(kNoTimestamp()), | 24 current_time_(kNoTimestamp()), |
26 bytes_per_frame_(0), | 25 bytes_per_frame_(0), |
27 bytes_per_second_(0), | 26 bytes_per_second_(0), |
28 stopped_(false), | 27 stopped_(false), |
29 sink_(sink), | 28 sink_(sink), |
30 is_initialized_(false), | 29 is_initialized_(false), |
31 underflow_disabled_(false), | 30 underflow_disabled_(false), |
32 read_cb_(base::Bind(&AudioRendererImpl::DecodedAudioReady, | 31 read_cb_(base::Bind(&AudioRendererImpl::DecodedAudioReady, |
33 base::Unretained(this))) { | 32 base::Unretained(this))) { |
34 } | 33 } |
35 | 34 |
36 void AudioRendererImpl::SetHost(FilterHost* host) { | |
37 DCHECK(host); | |
38 DCHECK(!host_); | |
39 host_ = host; | |
40 } | |
41 | |
42 void AudioRendererImpl::Play(const base::Closure& callback) { | 35 void AudioRendererImpl::Play(const base::Closure& callback) { |
43 { | 36 { |
44 base::AutoLock auto_lock(lock_); | 37 base::AutoLock auto_lock(lock_); |
45 DCHECK_EQ(kPaused, state_); | 38 DCHECK_EQ(kPaused, state_); |
46 state_ = kPlaying; | 39 state_ = kPlaying; |
47 callback.Run(); | 40 callback.Run(); |
48 } | 41 } |
49 | 42 |
50 if (stopped_) | 43 if (stopped_) |
51 return; | 44 return; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 void AudioRendererImpl::DoSeek() { | 133 void AudioRendererImpl::DoSeek() { |
141 earliest_end_time_ = base::Time::Now(); | 134 earliest_end_time_ = base::Time::Now(); |
142 | 135 |
143 // Pause and flush the stream when we seek to a new location. | 136 // Pause and flush the stream when we seek to a new location. |
144 sink_->Pause(true); | 137 sink_->Pause(true); |
145 } | 138 } |
146 | 139 |
147 void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder, | 140 void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder, |
148 const PipelineStatusCB& init_cb, | 141 const PipelineStatusCB& init_cb, |
149 const base::Closure& underflow_cb, | 142 const base::Closure& underflow_cb, |
150 const TimeCB& time_cb) { | 143 const TimeCB& time_cb, |
| 144 const base::Closure& ended_cb, |
| 145 const base::Closure& disabled_cb) { |
151 DCHECK(decoder); | 146 DCHECK(decoder); |
152 DCHECK(!init_cb.is_null()); | 147 DCHECK(!init_cb.is_null()); |
153 DCHECK(!underflow_cb.is_null()); | 148 DCHECK(!underflow_cb.is_null()); |
154 DCHECK(!time_cb.is_null()); | 149 DCHECK(!time_cb.is_null()); |
| 150 DCHECK(!ended_cb.is_null()); |
| 151 DCHECK(!disabled_cb.is_null()); |
155 DCHECK_EQ(kUninitialized, state_); | 152 DCHECK_EQ(kUninitialized, state_); |
156 decoder_ = decoder; | 153 decoder_ = decoder; |
157 underflow_cb_ = underflow_cb; | 154 underflow_cb_ = underflow_cb; |
158 time_cb_ = time_cb; | 155 time_cb_ = time_cb; |
| 156 ended_cb_ = ended_cb; |
| 157 disabled_cb_ = disabled_cb; |
159 | 158 |
160 // Create a callback so our algorithm can request more reads. | 159 // Create a callback so our algorithm can request more reads. |
161 base::Closure cb = base::Bind(&AudioRendererImpl::ScheduleRead_Locked, this); | 160 base::Closure cb = base::Bind(&AudioRendererImpl::ScheduleRead_Locked, this); |
162 | 161 |
163 // Construct the algorithm. | 162 // Construct the algorithm. |
164 algorithm_.reset(new AudioRendererAlgorithm()); | 163 algorithm_.reset(new AudioRendererAlgorithm()); |
165 | 164 |
166 // Initialize our algorithm with media properties, initial playback rate, | 165 // Initialize our algorithm with media properties, initial playback rate, |
167 // and a callback to request more reads from the data source. | 166 // and a callback to request more reads from the data source. |
168 ChannelLayout channel_layout = decoder_->channel_layout(); | 167 ChannelLayout channel_layout = decoder_->channel_layout(); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 // | 416 // |
418 // We use the following conditions to determine underflow: | 417 // We use the following conditions to determine underflow: |
419 // 1) Algorithm can not fill the audio callback buffer | 418 // 1) Algorithm can not fill the audio callback buffer |
420 // 2) We have NOT received an end of stream buffer | 419 // 2) We have NOT received an end of stream buffer |
421 // 3) We are in the kPlaying state | 420 // 3) We are in the kPlaying state |
422 // | 421 // |
423 // Otherwise fill the buffer with whatever data we can send to the device. | 422 // Otherwise fill the buffer with whatever data we can send to the device. |
424 if (!algorithm_->CanFillBuffer() && received_end_of_stream_ && | 423 if (!algorithm_->CanFillBuffer() && received_end_of_stream_ && |
425 !rendered_end_of_stream_ && base::Time::Now() >= earliest_end_time_) { | 424 !rendered_end_of_stream_ && base::Time::Now() >= earliest_end_time_) { |
426 rendered_end_of_stream_ = true; | 425 rendered_end_of_stream_ = true; |
427 host_->NotifyEnded(); | 426 ended_cb_.Run(); |
428 } else if (!algorithm_->CanFillBuffer() && !received_end_of_stream_ && | 427 } else if (!algorithm_->CanFillBuffer() && !received_end_of_stream_ && |
429 state_ == kPlaying && !underflow_disabled_) { | 428 state_ == kPlaying && !underflow_disabled_) { |
430 state_ = kUnderflow; | 429 state_ = kUnderflow; |
431 underflow_cb = underflow_cb_; | 430 underflow_cb = underflow_cb_; |
432 } else if (algorithm_->CanFillBuffer()) { | 431 } else if (algorithm_->CanFillBuffer()) { |
433 frames_written = algorithm_->FillBuffer(dest, requested_frames); | 432 frames_written = algorithm_->FillBuffer(dest, requested_frames); |
434 DCHECK_GT(frames_written, 0u); | 433 DCHECK_GT(frames_written, 0u); |
435 } else { | 434 } else { |
436 // We can't write any data this cycle. For example, we may have | 435 // We can't write any data this cycle. For example, we may have |
437 // sent all available data to the audio device while not reaching | 436 // sent all available data to the audio device while not reaching |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 | 499 |
501 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) { | 500 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) { |
502 if (bytes_per_second_) { | 501 if (bytes_per_second_) { |
503 return base::TimeDelta::FromMicroseconds( | 502 return base::TimeDelta::FromMicroseconds( |
504 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_); | 503 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_); |
505 } | 504 } |
506 return base::TimeDelta(); | 505 return base::TimeDelta(); |
507 } | 506 } |
508 | 507 |
509 void AudioRendererImpl::OnRenderError() { | 508 void AudioRendererImpl::OnRenderError() { |
510 host_->DisableAudioRenderer(); | 509 disabled_cb_.Run(); |
511 } | 510 } |
512 | 511 |
513 void AudioRendererImpl::DisableUnderflowForTesting() { | 512 void AudioRendererImpl::DisableUnderflowForTesting() { |
514 DCHECK(!is_initialized_); | 513 DCHECK(!is_initialized_); |
515 underflow_disabled_ = true; | 514 underflow_disabled_ = true; |
516 } | 515 } |
517 | 516 |
518 } // namespace media | 517 } // namespace media |
OLD | NEW |