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_base.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 AudioRendererBase::AudioRendererBase(media::AudioRendererSink* sink) | 18 AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink) |
19 : state_(kUninitialized), | 19 : state_(kUninitialized), |
20 pending_read_(false), | 20 pending_read_(false), |
21 received_end_of_stream_(false), | 21 received_end_of_stream_(false), |
22 rendered_end_of_stream_(false), | 22 rendered_end_of_stream_(false), |
23 bytes_per_frame_(0), | 23 bytes_per_frame_(0), |
24 bytes_per_second_(0), | 24 bytes_per_second_(0), |
25 stopped_(false), | 25 stopped_(false), |
26 sink_(sink), | 26 sink_(sink), |
27 is_initialized_(false), | 27 is_initialized_(false), |
28 read_cb_(base::Bind(&AudioRendererBase::DecodedAudioReady, | 28 read_cb_(base::Bind(&AudioRendererImpl::DecodedAudioReady, |
29 base::Unretained(this))) { | 29 base::Unretained(this))) { |
30 } | 30 } |
31 | 31 |
32 AudioRendererBase::~AudioRendererBase() { | 32 AudioRendererImpl::~AudioRendererImpl() { |
33 // Stop() should have been called and |algorithm_| should have been destroyed. | 33 // Stop() should have been called and |algorithm_| should have been destroyed. |
34 DCHECK(state_ == kUninitialized || state_ == kStopped); | 34 DCHECK(state_ == kUninitialized || state_ == kStopped); |
35 DCHECK(!algorithm_.get()); | 35 DCHECK(!algorithm_.get()); |
36 } | 36 } |
37 | 37 |
38 void AudioRendererBase::Play(const base::Closure& callback) { | 38 void AudioRendererImpl::Play(const base::Closure& callback) { |
39 { | 39 { |
40 base::AutoLock auto_lock(lock_); | 40 base::AutoLock auto_lock(lock_); |
41 DCHECK_EQ(kPaused, state_); | 41 DCHECK_EQ(kPaused, state_); |
42 state_ = kPlaying; | 42 state_ = kPlaying; |
43 callback.Run(); | 43 callback.Run(); |
44 } | 44 } |
45 | 45 |
46 if (stopped_) | 46 if (stopped_) |
47 return; | 47 return; |
48 | 48 |
49 if (GetPlaybackRate() != 0.0f) { | 49 if (GetPlaybackRate() != 0.0f) { |
50 DoPlay(); | 50 DoPlay(); |
51 } else { | 51 } else { |
52 DoPause(); | 52 DoPause(); |
53 } | 53 } |
54 } | 54 } |
55 | 55 |
56 void AudioRendererBase::DoPlay() { | 56 void AudioRendererImpl::DoPlay() { |
57 earliest_end_time_ = base::Time::Now(); | 57 earliest_end_time_ = base::Time::Now(); |
58 DCHECK(sink_.get()); | 58 DCHECK(sink_.get()); |
59 sink_->Play(); | 59 sink_->Play(); |
60 } | 60 } |
61 | 61 |
62 void AudioRendererBase::Pause(const base::Closure& callback) { | 62 void AudioRendererImpl::Pause(const base::Closure& callback) { |
63 { | 63 { |
64 base::AutoLock auto_lock(lock_); | 64 base::AutoLock auto_lock(lock_); |
65 DCHECK(state_ == kPlaying || state_ == kUnderflow || | 65 DCHECK(state_ == kPlaying || state_ == kUnderflow || |
66 state_ == kRebuffering); | 66 state_ == kRebuffering); |
67 pause_cb_ = callback; | 67 pause_cb_ = callback; |
68 state_ = kPaused; | 68 state_ = kPaused; |
69 | 69 |
70 // Pause only when we've completed our pending read. | 70 // Pause only when we've completed our pending read. |
71 if (!pending_read_) { | 71 if (!pending_read_) { |
72 pause_cb_.Run(); | 72 pause_cb_.Run(); |
73 pause_cb_.Reset(); | 73 pause_cb_.Reset(); |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 if (stopped_) | 77 if (stopped_) |
78 return; | 78 return; |
79 | 79 |
80 DoPause(); | 80 DoPause(); |
81 } | 81 } |
82 | 82 |
83 void AudioRendererBase::DoPause() { | 83 void AudioRendererImpl::DoPause() { |
84 DCHECK(sink_.get()); | 84 DCHECK(sink_.get()); |
85 sink_->Pause(false); | 85 sink_->Pause(false); |
86 } | 86 } |
87 | 87 |
88 void AudioRendererBase::Flush(const base::Closure& callback) { | 88 void AudioRendererImpl::Flush(const base::Closure& callback) { |
89 decoder_->Reset(callback); | 89 decoder_->Reset(callback); |
90 } | 90 } |
91 | 91 |
92 void AudioRendererBase::Stop(const base::Closure& callback) { | 92 void AudioRendererImpl::Stop(const base::Closure& callback) { |
93 if (!stopped_) { | 93 if (!stopped_) { |
94 DCHECK(sink_.get()); | 94 DCHECK(sink_.get()); |
95 sink_->Stop(); | 95 sink_->Stop(); |
96 | 96 |
97 stopped_ = true; | 97 stopped_ = true; |
98 } | 98 } |
99 { | 99 { |
100 base::AutoLock auto_lock(lock_); | 100 base::AutoLock auto_lock(lock_); |
101 state_ = kStopped; | 101 state_ = kStopped; |
102 algorithm_.reset(NULL); | 102 algorithm_.reset(NULL); |
103 time_cb_.Reset(); | 103 time_cb_.Reset(); |
104 underflow_cb_.Reset(); | 104 underflow_cb_.Reset(); |
105 } | 105 } |
106 if (!callback.is_null()) { | 106 if (!callback.is_null()) { |
107 callback.Run(); | 107 callback.Run(); |
108 } | 108 } |
109 } | 109 } |
110 | 110 |
111 void AudioRendererBase::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { | 111 void AudioRendererImpl::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { |
112 base::AutoLock auto_lock(lock_); | 112 base::AutoLock auto_lock(lock_); |
113 DCHECK_EQ(kPaused, state_); | 113 DCHECK_EQ(kPaused, state_); |
114 DCHECK(!pending_read_) << "Pending read must complete before seeking"; | 114 DCHECK(!pending_read_) << "Pending read must complete before seeking"; |
115 DCHECK(pause_cb_.is_null()); | 115 DCHECK(pause_cb_.is_null()); |
116 DCHECK(seek_cb_.is_null()); | 116 DCHECK(seek_cb_.is_null()); |
117 state_ = kSeeking; | 117 state_ = kSeeking; |
118 seek_cb_ = cb; | 118 seek_cb_ = cb; |
119 seek_timestamp_ = time; | 119 seek_timestamp_ = time; |
120 | 120 |
121 // Throw away everything and schedule our reads. | 121 // Throw away everything and schedule our reads. |
122 audio_time_buffered_ = base::TimeDelta(); | 122 audio_time_buffered_ = base::TimeDelta(); |
123 received_end_of_stream_ = false; | 123 received_end_of_stream_ = false; |
124 rendered_end_of_stream_ = false; | 124 rendered_end_of_stream_ = false; |
125 | 125 |
126 // |algorithm_| will request more reads. | 126 // |algorithm_| will request more reads. |
127 algorithm_->FlushBuffers(); | 127 algorithm_->FlushBuffers(); |
128 | 128 |
129 if (stopped_) | 129 if (stopped_) |
130 return; | 130 return; |
131 | 131 |
132 DoSeek(); | 132 DoSeek(); |
133 } | 133 } |
134 | 134 |
135 void AudioRendererBase::DoSeek() { | 135 void AudioRendererImpl::DoSeek() { |
136 earliest_end_time_ = base::Time::Now(); | 136 earliest_end_time_ = base::Time::Now(); |
137 | 137 |
138 // Pause and flush the stream when we seek to a new location. | 138 // Pause and flush the stream when we seek to a new location. |
139 sink_->Pause(true); | 139 sink_->Pause(true); |
140 } | 140 } |
141 | 141 |
142 void AudioRendererBase::Initialize(const scoped_refptr<AudioDecoder>& decoder, | 142 void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder, |
143 const PipelineStatusCB& init_cb, | 143 const PipelineStatusCB& init_cb, |
144 const base::Closure& underflow_cb, | 144 const base::Closure& underflow_cb, |
145 const TimeCB& time_cb) { | 145 const TimeCB& time_cb) { |
146 DCHECK(decoder); | 146 DCHECK(decoder); |
147 DCHECK(!init_cb.is_null()); | 147 DCHECK(!init_cb.is_null()); |
148 DCHECK(!underflow_cb.is_null()); | 148 DCHECK(!underflow_cb.is_null()); |
149 DCHECK(!time_cb.is_null()); | 149 DCHECK(!time_cb.is_null()); |
150 DCHECK_EQ(kUninitialized, state_); | 150 DCHECK_EQ(kUninitialized, state_); |
151 decoder_ = decoder; | 151 decoder_ = decoder; |
152 underflow_cb_ = underflow_cb; | 152 underflow_cb_ = underflow_cb; |
153 time_cb_ = time_cb; | 153 time_cb_ = time_cb; |
154 | 154 |
155 // Create a callback so our algorithm can request more reads. | 155 // Create a callback so our algorithm can request more reads. |
156 base::Closure cb = base::Bind(&AudioRendererBase::ScheduleRead_Locked, this); | 156 base::Closure cb = base::Bind(&AudioRendererImpl::ScheduleRead_Locked, this); |
157 | 157 |
158 // Construct the algorithm. | 158 // Construct the algorithm. |
159 algorithm_.reset(new AudioRendererAlgorithmBase()); | 159 algorithm_.reset(new AudioRendererAlgorithm()); |
160 | 160 |
161 // Initialize our algorithm with media properties, initial playback rate, | 161 // Initialize our algorithm with media properties, initial playback rate, |
162 // and a callback to request more reads from the data source. | 162 // and a callback to request more reads from the data source. |
163 ChannelLayout channel_layout = decoder_->channel_layout(); | 163 ChannelLayout channel_layout = decoder_->channel_layout(); |
164 int channels = ChannelLayoutToChannelCount(channel_layout); | 164 int channels = ChannelLayoutToChannelCount(channel_layout); |
165 int bits_per_channel = decoder_->bits_per_channel(); | 165 int bits_per_channel = decoder_->bits_per_channel(); |
166 int sample_rate = decoder_->samples_per_second(); | 166 int sample_rate = decoder_->samples_per_second(); |
167 // TODO(vrk): Add method to AudioDecoder to compute bytes per frame. | 167 // TODO(vrk): Add method to AudioDecoder to compute bytes per frame. |
168 bytes_per_frame_ = channels * bits_per_channel / 8; | 168 bytes_per_frame_ = channels * bits_per_channel / 8; |
169 | 169 |
(...skipping 23 matching lines...) Expand all Loading... |
193 sink_->Initialize(audio_parameters_, this); | 193 sink_->Initialize(audio_parameters_, this); |
194 | 194 |
195 sink_->Start(); | 195 sink_->Start(); |
196 is_initialized_ = true; | 196 is_initialized_ = true; |
197 | 197 |
198 // Finally, execute the start callback. | 198 // Finally, execute the start callback. |
199 state_ = kPaused; | 199 state_ = kPaused; |
200 init_cb.Run(PIPELINE_OK); | 200 init_cb.Run(PIPELINE_OK); |
201 } | 201 } |
202 | 202 |
203 bool AudioRendererBase::HasEnded() { | 203 bool AudioRendererImpl::HasEnded() { |
204 base::AutoLock auto_lock(lock_); | 204 base::AutoLock auto_lock(lock_); |
205 DCHECK(!rendered_end_of_stream_ || algorithm_->NeedsMoreData()); | 205 DCHECK(!rendered_end_of_stream_ || algorithm_->NeedsMoreData()); |
206 | 206 |
207 return received_end_of_stream_ && rendered_end_of_stream_; | 207 return received_end_of_stream_ && rendered_end_of_stream_; |
208 } | 208 } |
209 | 209 |
210 void AudioRendererBase::ResumeAfterUnderflow(bool buffer_more_audio) { | 210 void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) { |
211 base::AutoLock auto_lock(lock_); | 211 base::AutoLock auto_lock(lock_); |
212 if (state_ == kUnderflow) { | 212 if (state_ == kUnderflow) { |
213 if (buffer_more_audio) | 213 if (buffer_more_audio) |
214 algorithm_->IncreaseQueueCapacity(); | 214 algorithm_->IncreaseQueueCapacity(); |
215 | 215 |
216 state_ = kRebuffering; | 216 state_ = kRebuffering; |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 void AudioRendererBase::SetVolume(float volume) { | 220 void AudioRendererImpl::SetVolume(float volume) { |
221 if (stopped_) | 221 if (stopped_) |
222 return; | 222 return; |
223 sink_->SetVolume(volume); | 223 sink_->SetVolume(volume); |
224 } | 224 } |
225 | 225 |
226 void AudioRendererBase::DecodedAudioReady(scoped_refptr<Buffer> buffer) { | 226 void AudioRendererImpl::DecodedAudioReady(scoped_refptr<Buffer> buffer) { |
227 base::AutoLock auto_lock(lock_); | 227 base::AutoLock auto_lock(lock_); |
228 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying || | 228 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying || |
229 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); | 229 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); |
230 | 230 |
231 CHECK(pending_read_); | 231 CHECK(pending_read_); |
232 pending_read_ = false; | 232 pending_read_ = false; |
233 | 233 |
234 if (buffer && buffer->IsEndOfStream()) { | 234 if (buffer && buffer->IsEndOfStream()) { |
235 received_end_of_stream_ = true; | 235 received_end_of_stream_ = true; |
236 | 236 |
(...skipping 30 matching lines...) Expand all Loading... |
267 case kUnderflow: | 267 case kUnderflow: |
268 case kRebuffering: | 268 case kRebuffering: |
269 if (buffer && !buffer->IsEndOfStream()) | 269 if (buffer && !buffer->IsEndOfStream()) |
270 algorithm_->EnqueueBuffer(buffer); | 270 algorithm_->EnqueueBuffer(buffer); |
271 return; | 271 return; |
272 case kStopped: | 272 case kStopped: |
273 return; | 273 return; |
274 } | 274 } |
275 } | 275 } |
276 | 276 |
277 void AudioRendererBase::SignalEndOfStream() { | 277 void AudioRendererImpl::SignalEndOfStream() { |
278 DCHECK(received_end_of_stream_); | 278 DCHECK(received_end_of_stream_); |
279 if (!rendered_end_of_stream_) { | 279 if (!rendered_end_of_stream_) { |
280 rendered_end_of_stream_ = true; | 280 rendered_end_of_stream_ = true; |
281 host()->NotifyEnded(); | 281 host()->NotifyEnded(); |
282 } | 282 } |
283 } | 283 } |
284 | 284 |
285 void AudioRendererBase::ScheduleRead_Locked() { | 285 void AudioRendererImpl::ScheduleRead_Locked() { |
286 lock_.AssertAcquired(); | 286 lock_.AssertAcquired(); |
287 if (pending_read_ || state_ == kPaused) | 287 if (pending_read_ || state_ == kPaused) |
288 return; | 288 return; |
289 pending_read_ = true; | 289 pending_read_ = true; |
290 decoder_->Read(read_cb_); | 290 decoder_->Read(read_cb_); |
291 } | 291 } |
292 | 292 |
293 void AudioRendererBase::SetPlaybackRate(float playback_rate) { | 293 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { |
294 DCHECK_LE(0.0f, playback_rate); | 294 DCHECK_LE(0.0f, playback_rate); |
295 | 295 |
296 if (!stopped_) { | 296 if (!stopped_) { |
297 // Notify sink of new playback rate. | 297 // Notify sink of new playback rate. |
298 sink_->SetPlaybackRate(playback_rate); | 298 sink_->SetPlaybackRate(playback_rate); |
299 | 299 |
300 // We have two cases here: | 300 // We have two cases here: |
301 // Play: GetPlaybackRate() == 0.0 && playback_rate != 0.0 | 301 // Play: GetPlaybackRate() == 0.0 && playback_rate != 0.0 |
302 // Pause: GetPlaybackRate() != 0.0 && playback_rate == 0.0 | 302 // Pause: GetPlaybackRate() != 0.0 && playback_rate == 0.0 |
303 if (GetPlaybackRate() == 0.0f && playback_rate != 0.0f) { | 303 if (GetPlaybackRate() == 0.0f && playback_rate != 0.0f) { |
304 DoPlay(); | 304 DoPlay(); |
305 } else if (GetPlaybackRate() != 0.0f && playback_rate == 0.0f) { | 305 } else if (GetPlaybackRate() != 0.0f && playback_rate == 0.0f) { |
306 // Pause is easy, we can always pause. | 306 // Pause is easy, we can always pause. |
307 DoPause(); | 307 DoPause(); |
308 } | 308 } |
309 } | 309 } |
310 | 310 |
311 base::AutoLock auto_lock(lock_); | 311 base::AutoLock auto_lock(lock_); |
312 algorithm_->SetPlaybackRate(playback_rate); | 312 algorithm_->SetPlaybackRate(playback_rate); |
313 } | 313 } |
314 | 314 |
315 float AudioRendererBase::GetPlaybackRate() { | 315 float AudioRendererImpl::GetPlaybackRate() { |
316 base::AutoLock auto_lock(lock_); | 316 base::AutoLock auto_lock(lock_); |
317 return algorithm_->playback_rate(); | 317 return algorithm_->playback_rate(); |
318 } | 318 } |
319 | 319 |
320 bool AudioRendererBase::IsBeforeSeekTime(const scoped_refptr<Buffer>& buffer) { | 320 bool AudioRendererImpl::IsBeforeSeekTime(const scoped_refptr<Buffer>& buffer) { |
321 return (state_ == kSeeking) && buffer && !buffer->IsEndOfStream() && | 321 return (state_ == kSeeking) && buffer && !buffer->IsEndOfStream() && |
322 (buffer->GetTimestamp() + buffer->GetDuration()) < seek_timestamp_; | 322 (buffer->GetTimestamp() + buffer->GetDuration()) < seek_timestamp_; |
323 } | 323 } |
324 | 324 |
325 int AudioRendererBase::Render(const std::vector<float*>& audio_data, | 325 int AudioRendererImpl::Render(const std::vector<float*>& audio_data, |
326 int number_of_frames, | 326 int number_of_frames, |
327 int audio_delay_milliseconds) { | 327 int audio_delay_milliseconds) { |
328 if (stopped_ || GetPlaybackRate() == 0.0f) { | 328 if (stopped_ || GetPlaybackRate() == 0.0f) { |
329 // Output silence if stopped. | 329 // Output silence if stopped. |
330 for (size_t i = 0; i < audio_data.size(); ++i) | 330 for (size_t i = 0; i < audio_data.size(); ++i) |
331 memset(audio_data[i], 0, sizeof(float) * number_of_frames); | 331 memset(audio_data[i], 0, sizeof(float) * number_of_frames); |
332 return 0; | 332 return 0; |
333 } | 333 } |
334 | 334 |
335 // Adjust the playback delay. | 335 // Adjust the playback delay. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 if (frames_filled < number_of_frames) { | 367 if (frames_filled < number_of_frames) { |
368 int frames_to_zero = number_of_frames - frames_filled; | 368 int frames_to_zero = number_of_frames - frames_filled; |
369 memset(audio_data[channel_index] + frames_filled, | 369 memset(audio_data[channel_index] + frames_filled, |
370 0, | 370 0, |
371 sizeof(float) * frames_to_zero); | 371 sizeof(float) * frames_to_zero); |
372 } | 372 } |
373 } | 373 } |
374 return frames_filled; | 374 return frames_filled; |
375 } | 375 } |
376 | 376 |
377 uint32 AudioRendererBase::FillBuffer(uint8* dest, | 377 uint32 AudioRendererImpl::FillBuffer(uint8* dest, |
378 uint32 requested_frames, | 378 uint32 requested_frames, |
379 const base::TimeDelta& playback_delay) { | 379 const base::TimeDelta& playback_delay) { |
380 // The |audio_time_buffered_| is the ending timestamp of the last frame | 380 // The |audio_time_buffered_| is the ending timestamp of the last frame |
381 // buffered at the audio device. |playback_delay| is the amount of time | 381 // buffered at the audio device. |playback_delay| is the amount of time |
382 // buffered at the audio device. The current time can be computed by their | 382 // buffered at the audio device. The current time can be computed by their |
383 // difference. | 383 // difference. |
384 base::TimeDelta current_time = audio_time_buffered_ - playback_delay; | 384 base::TimeDelta current_time = audio_time_buffered_ - playback_delay; |
385 | 385 |
386 size_t frames_written = 0; | 386 size_t frames_written = 0; |
387 base::Closure underflow_cb; | 387 base::Closure underflow_cb; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 current_time > host()->GetTime())) { | 444 current_time > host()->GetTime())) { |
445 time_cb_.Run(current_time, audio_time_buffered_); | 445 time_cb_.Run(current_time, audio_time_buffered_); |
446 } | 446 } |
447 | 447 |
448 if (!underflow_cb.is_null()) | 448 if (!underflow_cb.is_null()) |
449 underflow_cb.Run(); | 449 underflow_cb.Run(); |
450 | 450 |
451 return frames_written; | 451 return frames_written; |
452 } | 452 } |
453 | 453 |
454 void AudioRendererBase::UpdateEarliestEndTime(int bytes_filled, | 454 void AudioRendererImpl::UpdateEarliestEndTime(int bytes_filled, |
455 base::TimeDelta request_delay, | 455 base::TimeDelta request_delay, |
456 base::Time time_now) { | 456 base::Time time_now) { |
457 if (bytes_filled != 0) { | 457 if (bytes_filled != 0) { |
458 base::TimeDelta predicted_play_time = ConvertToDuration(bytes_filled); | 458 base::TimeDelta predicted_play_time = ConvertToDuration(bytes_filled); |
459 float playback_rate = GetPlaybackRate(); | 459 float playback_rate = GetPlaybackRate(); |
460 if (playback_rate != 1.0f) { | 460 if (playback_rate != 1.0f) { |
461 predicted_play_time = base::TimeDelta::FromMicroseconds( | 461 predicted_play_time = base::TimeDelta::FromMicroseconds( |
462 static_cast<int64>(ceil(predicted_play_time.InMicroseconds() * | 462 static_cast<int64>(ceil(predicted_play_time.InMicroseconds() * |
463 playback_rate))); | 463 playback_rate))); |
464 } | 464 } |
465 earliest_end_time_ = | 465 earliest_end_time_ = |
466 std::max(earliest_end_time_, | 466 std::max(earliest_end_time_, |
467 time_now + request_delay + predicted_play_time); | 467 time_now + request_delay + predicted_play_time); |
468 } | 468 } |
469 } | 469 } |
470 | 470 |
471 base::TimeDelta AudioRendererBase::ConvertToDuration(int bytes) { | 471 base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) { |
472 if (bytes_per_second_) { | 472 if (bytes_per_second_) { |
473 return base::TimeDelta::FromMicroseconds( | 473 return base::TimeDelta::FromMicroseconds( |
474 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_); | 474 base::Time::kMicrosecondsPerSecond * bytes / bytes_per_second_); |
475 } | 475 } |
476 return base::TimeDelta(); | 476 return base::TimeDelta(); |
477 } | 477 } |
478 | 478 |
479 void AudioRendererBase::OnRenderError() { | 479 void AudioRendererImpl::OnRenderError() { |
480 host()->DisableAudioRenderer(); | 480 host()->DisableAudioRenderer(); |
481 } | 481 } |
482 | 482 |
483 } // namespace media | 483 } // namespace media |
OLD | NEW |