Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Side by Side Diff: media/filters/audio_renderer_impl.cc

Issue 65803002: Replace MessageLoopProxy with SingleThreadTaskRunner for media/filters/ + associated code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <algorithm> 9 #include <algorithm>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback.h" 12 #include "base/callback.h"
13 #include "base/callback_helpers.h" 13 #include "base/callback_helpers.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/message_loop/message_loop_proxy.h"
16 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
16 #include "base/single_thread_task_runner.h"
17 #include "media/base/audio_buffer.h" 17 #include "media/base/audio_buffer.h"
18 #include "media/base/audio_splicer.h" 18 #include "media/base/audio_splicer.h"
19 #include "media/base/bind_to_loop.h" 19 #include "media/base/bind_to_loop.h"
20 #include "media/base/demuxer_stream.h" 20 #include "media/base/demuxer_stream.h"
21 #include "media/filters/audio_decoder_selector.h" 21 #include "media/filters/audio_decoder_selector.h"
22 #include "media/filters/decrypting_demuxer_stream.h" 22 #include "media/filters/decrypting_demuxer_stream.h"
23 23
24 namespace media { 24 namespace media {
25 25
26 namespace { 26 namespace {
27 27
28 enum AudioRendererEvent { 28 enum AudioRendererEvent {
29 INITIALIZED, 29 INITIALIZED,
30 RENDER_ERROR, 30 RENDER_ERROR,
31 MAX_EVENTS 31 MAX_EVENTS
32 }; 32 };
33 33
34 void HistogramRendererEvent(AudioRendererEvent event) { 34 void HistogramRendererEvent(AudioRendererEvent event) {
35 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event, MAX_EVENTS); 35 UMA_HISTOGRAM_ENUMERATION("Media.AudioRendererEvents", event, MAX_EVENTS);
36 } 36 }
37 37
38 } // namespace 38 } // namespace
39 39
40 AudioRendererImpl::AudioRendererImpl( 40 AudioRendererImpl::AudioRendererImpl(
41 const scoped_refptr<base::MessageLoopProxy>& message_loop, 41 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
42 media::AudioRendererSink* sink, 42 media::AudioRendererSink* sink,
43 ScopedVector<AudioDecoder> decoders, 43 ScopedVector<AudioDecoder> decoders,
44 const SetDecryptorReadyCB& set_decryptor_ready_cb, 44 const SetDecryptorReadyCB& set_decryptor_ready_cb,
45 bool increase_preroll_on_underflow) 45 bool increase_preroll_on_underflow)
46 : message_loop_(message_loop), 46 : task_runner_(task_runner),
47 weak_factory_(this), 47 weak_factory_(this),
48 sink_(sink), 48 sink_(sink),
49 decoder_selector_(new AudioDecoderSelector( 49 decoder_selector_(new AudioDecoderSelector(
50 message_loop, decoders.Pass(), set_decryptor_ready_cb)), 50 task_runner, decoders.Pass(), set_decryptor_ready_cb)),
51 now_cb_(base::Bind(&base::TimeTicks::Now)), 51 now_cb_(base::Bind(&base::TimeTicks::Now)),
52 state_(kUninitialized), 52 state_(kUninitialized),
53 sink_playing_(false), 53 sink_playing_(false),
54 pending_read_(false), 54 pending_read_(false),
55 received_end_of_stream_(false), 55 received_end_of_stream_(false),
56 rendered_end_of_stream_(false), 56 rendered_end_of_stream_(false),
57 audio_time_buffered_(kNoTimestamp()), 57 audio_time_buffered_(kNoTimestamp()),
58 current_time_(kNoTimestamp()), 58 current_time_(kNoTimestamp()),
59 underflow_disabled_(false), 59 underflow_disabled_(false),
60 increase_preroll_on_underflow_(increase_preroll_on_underflow), 60 increase_preroll_on_underflow_(increase_preroll_on_underflow),
61 preroll_aborted_(false) { 61 preroll_aborted_(false) {
62 } 62 }
63 63
64 AudioRendererImpl::~AudioRendererImpl() { 64 AudioRendererImpl::~AudioRendererImpl() {
65 // Stop() should have been called and |algorithm_| should have been destroyed. 65 // Stop() should have been called and |algorithm_| should have been destroyed.
66 DCHECK(state_ == kUninitialized || state_ == kStopped); 66 DCHECK(state_ == kUninitialized || state_ == kStopped);
67 DCHECK(!algorithm_.get()); 67 DCHECK(!algorithm_.get());
68 } 68 }
69 69
70 void AudioRendererImpl::Play(const base::Closure& callback) { 70 void AudioRendererImpl::Play(const base::Closure& callback) {
71 DCHECK(message_loop_->BelongsToCurrentThread()); 71 DCHECK(task_runner_->BelongsToCurrentThread());
72 72
73 base::AutoLock auto_lock(lock_); 73 base::AutoLock auto_lock(lock_);
74 DCHECK_EQ(state_, kPaused); 74 DCHECK_EQ(state_, kPaused);
75 ChangeState_Locked(kPlaying); 75 ChangeState_Locked(kPlaying);
76 callback.Run(); 76 callback.Run();
77 earliest_end_time_ = now_cb_.Run(); 77 earliest_end_time_ = now_cb_.Run();
78 78
79 if (algorithm_->playback_rate() != 0) 79 if (algorithm_->playback_rate() != 0)
80 DoPlay_Locked(); 80 DoPlay_Locked();
81 else 81 else
82 DCHECK(!sink_playing_); 82 DCHECK(!sink_playing_);
83 } 83 }
84 84
85 void AudioRendererImpl::DoPlay_Locked() { 85 void AudioRendererImpl::DoPlay_Locked() {
86 DCHECK(message_loop_->BelongsToCurrentThread()); 86 DCHECK(task_runner_->BelongsToCurrentThread());
87 lock_.AssertAcquired(); 87 lock_.AssertAcquired();
88 earliest_end_time_ = now_cb_.Run(); 88 earliest_end_time_ = now_cb_.Run();
89 89
90 if (state_ == kPlaying && !sink_playing_) { 90 if (state_ == kPlaying && !sink_playing_) {
91 { 91 {
92 base::AutoUnlock auto_unlock(lock_); 92 base::AutoUnlock auto_unlock(lock_);
93 sink_->Play(); 93 sink_->Play();
94 } 94 }
95 95
96 sink_playing_ = true; 96 sink_playing_ = true;
97 } 97 }
98 } 98 }
99 99
100 void AudioRendererImpl::Pause(const base::Closure& callback) { 100 void AudioRendererImpl::Pause(const base::Closure& callback) {
101 DCHECK(message_loop_->BelongsToCurrentThread()); 101 DCHECK(task_runner_->BelongsToCurrentThread());
102 102
103 base::AutoLock auto_lock(lock_); 103 base::AutoLock auto_lock(lock_);
104 DCHECK(state_ == kPlaying || state_ == kUnderflow || 104 DCHECK(state_ == kPlaying || state_ == kUnderflow ||
105 state_ == kRebuffering) << "state_ == " << state_; 105 state_ == kRebuffering) << "state_ == " << state_;
106 pause_cb_ = callback; 106 pause_cb_ = callback;
107 ChangeState_Locked(kPaused); 107 ChangeState_Locked(kPaused);
108 108
109 // Pause only when we've completed our pending read. 109 // Pause only when we've completed our pending read.
110 if (!pending_read_) 110 if (!pending_read_)
111 base::ResetAndReturn(&pause_cb_).Run(); 111 base::ResetAndReturn(&pause_cb_).Run();
112 112
113 DoPause_Locked(); 113 DoPause_Locked();
114 } 114 }
115 115
116 void AudioRendererImpl::DoPause_Locked() { 116 void AudioRendererImpl::DoPause_Locked() {
117 DCHECK(message_loop_->BelongsToCurrentThread()); 117 DCHECK(task_runner_->BelongsToCurrentThread());
118 lock_.AssertAcquired(); 118 lock_.AssertAcquired();
119 119
120 if (sink_playing_) { 120 if (sink_playing_) {
121 { 121 {
122 base::AutoUnlock auto_unlock(lock_); 122 base::AutoUnlock auto_unlock(lock_);
123 sink_->Pause(); 123 sink_->Pause();
124 } 124 }
125 sink_playing_ = false; 125 sink_playing_ = false;
126 } 126 }
127 } 127 }
128 128
129 void AudioRendererImpl::Flush(const base::Closure& callback) { 129 void AudioRendererImpl::Flush(const base::Closure& callback) {
130 DCHECK(message_loop_->BelongsToCurrentThread()); 130 DCHECK(task_runner_->BelongsToCurrentThread());
131 131
132 if (decrypting_demuxer_stream_) { 132 if (decrypting_demuxer_stream_) {
133 decrypting_demuxer_stream_->Reset(base::Bind( 133 decrypting_demuxer_stream_->Reset(base::Bind(
134 &AudioRendererImpl::ResetDecoder, weak_this_, callback)); 134 &AudioRendererImpl::ResetDecoder, weak_this_, callback));
135 return; 135 return;
136 } 136 }
137 137
138 decoder_->Reset(callback); 138 decoder_->Reset(callback);
139 } 139 }
140 140
141 void AudioRendererImpl::ResetDecoder(const base::Closure& callback) { 141 void AudioRendererImpl::ResetDecoder(const base::Closure& callback) {
142 DCHECK(message_loop_->BelongsToCurrentThread()); 142 DCHECK(task_runner_->BelongsToCurrentThread());
143 decoder_->Reset(callback); 143 decoder_->Reset(callback);
144 } 144 }
145 145
146 void AudioRendererImpl::Stop(const base::Closure& callback) { 146 void AudioRendererImpl::Stop(const base::Closure& callback) {
147 DCHECK(message_loop_->BelongsToCurrentThread()); 147 DCHECK(task_runner_->BelongsToCurrentThread());
148 DCHECK(!callback.is_null()); 148 DCHECK(!callback.is_null());
149 149
150 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing 150 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
151 // task-running guards that check |state_| with DCHECK(). 151 // task-running guards that check |state_| with DCHECK().
152 152
153 if (sink_) { 153 if (sink_) {
154 sink_->Stop(); 154 sink_->Stop();
155 sink_ = NULL; 155 sink_ = NULL;
156 } 156 }
157 157
158 { 158 {
159 base::AutoLock auto_lock(lock_); 159 base::AutoLock auto_lock(lock_);
160 ChangeState_Locked(kStopped); 160 ChangeState_Locked(kStopped);
161 algorithm_.reset(NULL); 161 algorithm_.reset(NULL);
162 init_cb_.Reset(); 162 init_cb_.Reset();
163 underflow_cb_.Reset(); 163 underflow_cb_.Reset();
164 time_cb_.Reset(); 164 time_cb_.Reset();
165 } 165 }
166 166
167 callback.Run(); 167 callback.Run();
168 } 168 }
169 169
170 void AudioRendererImpl::Preroll(base::TimeDelta time, 170 void AudioRendererImpl::Preroll(base::TimeDelta time,
171 const PipelineStatusCB& cb) { 171 const PipelineStatusCB& cb) {
172 DCHECK(message_loop_->BelongsToCurrentThread()); 172 DCHECK(task_runner_->BelongsToCurrentThread());
173 173
174 base::AutoLock auto_lock(lock_); 174 base::AutoLock auto_lock(lock_);
175 DCHECK(!sink_playing_); 175 DCHECK(!sink_playing_);
176 DCHECK_EQ(state_, kPaused); 176 DCHECK_EQ(state_, kPaused);
177 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 177 DCHECK(!pending_read_) << "Pending read must complete before seeking";
178 DCHECK(pause_cb_.is_null()); 178 DCHECK(pause_cb_.is_null());
179 DCHECK(preroll_cb_.is_null()); 179 DCHECK(preroll_cb_.is_null());
180 180
181 ChangeState_Locked(kPrerolling); 181 ChangeState_Locked(kPrerolling);
182 preroll_cb_ = cb; 182 preroll_cb_ = cb;
(...skipping 14 matching lines...) Expand all
197 } 197 }
198 198
199 void AudioRendererImpl::Initialize(DemuxerStream* stream, 199 void AudioRendererImpl::Initialize(DemuxerStream* stream,
200 const PipelineStatusCB& init_cb, 200 const PipelineStatusCB& init_cb,
201 const StatisticsCB& statistics_cb, 201 const StatisticsCB& statistics_cb,
202 const base::Closure& underflow_cb, 202 const base::Closure& underflow_cb,
203 const TimeCB& time_cb, 203 const TimeCB& time_cb,
204 const base::Closure& ended_cb, 204 const base::Closure& ended_cb,
205 const base::Closure& disabled_cb, 205 const base::Closure& disabled_cb,
206 const PipelineStatusCB& error_cb) { 206 const PipelineStatusCB& error_cb) {
207 DCHECK(message_loop_->BelongsToCurrentThread()); 207 DCHECK(task_runner_->BelongsToCurrentThread());
208 DCHECK(stream); 208 DCHECK(stream);
209 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); 209 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
210 DCHECK(!init_cb.is_null()); 210 DCHECK(!init_cb.is_null());
211 DCHECK(!statistics_cb.is_null()); 211 DCHECK(!statistics_cb.is_null());
212 DCHECK(!underflow_cb.is_null()); 212 DCHECK(!underflow_cb.is_null());
213 DCHECK(!time_cb.is_null()); 213 DCHECK(!time_cb.is_null());
214 DCHECK(!ended_cb.is_null()); 214 DCHECK(!ended_cb.is_null());
215 DCHECK(!disabled_cb.is_null()); 215 DCHECK(!disabled_cb.is_null());
216 DCHECK(!error_cb.is_null()); 216 DCHECK(!error_cb.is_null());
217 DCHECK_EQ(kUninitialized, state_); 217 DCHECK_EQ(kUninitialized, state_);
(...skipping 10 matching lines...) Expand all
228 228
229 decoder_selector_->SelectAudioDecoder( 229 decoder_selector_->SelectAudioDecoder(
230 stream, 230 stream,
231 statistics_cb, 231 statistics_cb,
232 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); 232 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_));
233 } 233 }
234 234
235 void AudioRendererImpl::OnDecoderSelected( 235 void AudioRendererImpl::OnDecoderSelected(
236 scoped_ptr<AudioDecoder> decoder, 236 scoped_ptr<AudioDecoder> decoder,
237 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 237 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
238 DCHECK(message_loop_->BelongsToCurrentThread()); 238 DCHECK(task_runner_->BelongsToCurrentThread());
239 239
240 base::AutoLock auto_lock(lock_); 240 base::AutoLock auto_lock(lock_);
241 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); 241 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass());
242 242
243 if (state_ == kStopped) { 243 if (state_ == kStopped) {
244 DCHECK(!sink_); 244 DCHECK(!sink_);
245 return; 245 return;
246 } 246 }
247 247
248 if (!decoder) { 248 if (!decoder) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 // Some sinks play on start... 285 // Some sinks play on start...
286 sink_->Pause(); 286 sink_->Pause();
287 } 287 }
288 288
289 DCHECK(!sink_playing_); 289 DCHECK(!sink_playing_);
290 290
291 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 291 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
292 } 292 }
293 293
294 void AudioRendererImpl::ResumeAfterUnderflow() { 294 void AudioRendererImpl::ResumeAfterUnderflow() {
295 DCHECK(message_loop_->BelongsToCurrentThread()); 295 DCHECK(task_runner_->BelongsToCurrentThread());
296 base::AutoLock auto_lock(lock_); 296 base::AutoLock auto_lock(lock_);
297 if (state_ == kUnderflow) { 297 if (state_ == kUnderflow) {
298 // The "&& preroll_aborted_" is a hack. If preroll is aborted, then we 298 // The "&& preroll_aborted_" is a hack. If preroll is aborted, then we
299 // shouldn't even reach the kUnderflow state to begin with. But for now 299 // shouldn't even reach the kUnderflow state to begin with. But for now
300 // we're just making sure that the audio buffer capacity (i.e. the 300 // we're just making sure that the audio buffer capacity (i.e. the
301 // number of bytes that need to be buffered for preroll to complete) 301 // number of bytes that need to be buffered for preroll to complete)
302 // does not increase due to an aborted preroll. 302 // does not increase due to an aborted preroll.
303 // TODO(vrk): Fix this bug correctly! (crbug.com/151352) 303 // TODO(vrk): Fix this bug correctly! (crbug.com/151352)
304 if (increase_preroll_on_underflow_ && !preroll_aborted_) 304 if (increase_preroll_on_underflow_ && !preroll_aborted_)
305 algorithm_->IncreaseQueueCapacity(); 305 algorithm_->IncreaseQueueCapacity();
306 306
307 ChangeState_Locked(kRebuffering); 307 ChangeState_Locked(kRebuffering);
308 } 308 }
309 } 309 }
310 310
311 void AudioRendererImpl::SetVolume(float volume) { 311 void AudioRendererImpl::SetVolume(float volume) {
312 DCHECK(message_loop_->BelongsToCurrentThread()); 312 DCHECK(task_runner_->BelongsToCurrentThread());
313 DCHECK(sink_); 313 DCHECK(sink_);
314 sink_->SetVolume(volume); 314 sink_->SetVolume(volume);
315 } 315 }
316 316
317 void AudioRendererImpl::DecodedAudioReady( 317 void AudioRendererImpl::DecodedAudioReady(
318 AudioDecoder::Status status, 318 AudioDecoder::Status status,
319 const scoped_refptr<AudioBuffer>& buffer) { 319 const scoped_refptr<AudioBuffer>& buffer) {
320 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; 320 DVLOG(1) << __FUNCTION__ << "(" << status << ")";
321 DCHECK(message_loop_->BelongsToCurrentThread()); 321 DCHECK(task_runner_->BelongsToCurrentThread());
322 322
323 base::AutoLock auto_lock(lock_); 323 base::AutoLock auto_lock(lock_);
324 DCHECK(state_ == kPaused || state_ == kPrerolling || state_ == kPlaying || 324 DCHECK(state_ == kPaused || state_ == kPrerolling || state_ == kPlaying ||
325 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); 325 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped);
326 326
327 CHECK(pending_read_); 327 CHECK(pending_read_);
328 pending_read_ = false; 328 pending_read_ = false;
329 329
330 if (status == AudioDecoder::kAborted) { 330 if (status == AudioDecoder::kAborted) {
331 HandleAbortedReadOrDecodeError(false); 331 HandleAbortedReadOrDecodeError(false);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 } 409 }
410 return false; 410 return false;
411 } 411 }
412 412
413 void AudioRendererImpl::AttemptRead() { 413 void AudioRendererImpl::AttemptRead() {
414 base::AutoLock auto_lock(lock_); 414 base::AutoLock auto_lock(lock_);
415 AttemptRead_Locked(); 415 AttemptRead_Locked();
416 } 416 }
417 417
418 void AudioRendererImpl::AttemptRead_Locked() { 418 void AudioRendererImpl::AttemptRead_Locked() {
419 DCHECK(message_loop_->BelongsToCurrentThread()); 419 DCHECK(task_runner_->BelongsToCurrentThread());
420 lock_.AssertAcquired(); 420 lock_.AssertAcquired();
421 421
422 if (!CanRead_Locked()) 422 if (!CanRead_Locked())
423 return; 423 return;
424 424
425 pending_read_ = true; 425 pending_read_ = true;
426 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); 426 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_));
427 } 427 }
428 428
429 bool AudioRendererImpl::CanRead_Locked() { 429 bool AudioRendererImpl::CanRead_Locked() {
(...skipping 11 matching lines...) Expand all
441 case kRebuffering: 441 case kRebuffering:
442 break; 442 break;
443 } 443 }
444 444
445 return !pending_read_ && !received_end_of_stream_ && 445 return !pending_read_ && !received_end_of_stream_ &&
446 !algorithm_->IsQueueFull(); 446 !algorithm_->IsQueueFull();
447 } 447 }
448 448
449 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { 449 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
450 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; 450 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
451 DCHECK(message_loop_->BelongsToCurrentThread()); 451 DCHECK(task_runner_->BelongsToCurrentThread());
452 DCHECK_GE(playback_rate, 0); 452 DCHECK_GE(playback_rate, 0);
453 DCHECK(sink_); 453 DCHECK(sink_);
454 454
455 base::AutoLock auto_lock(lock_); 455 base::AutoLock auto_lock(lock_);
456 456
457 // We have two cases here: 457 // We have two cases here:
458 // Play: current_playback_rate == 0 && playback_rate != 0 458 // Play: current_playback_rate == 0 && playback_rate != 0
459 // Pause: current_playback_rate != 0 && playback_rate == 0 459 // Pause: current_playback_rate != 0 && playback_rate == 0
460 float current_playback_rate = algorithm_->playback_rate(); 460 float current_playback_rate = algorithm_->playback_rate();
461 if (current_playback_rate == 0 && playback_rate != 0) 461 if (current_playback_rate == 0 && playback_rate != 0)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 ChangeState_Locked(kUnderflow); 526 ChangeState_Locked(kUnderflow);
527 underflow_cb = underflow_cb_; 527 underflow_cb = underflow_cb_;
528 } else { 528 } else {
529 // We can't write any data this cycle. For example, we may have 529 // We can't write any data this cycle. For example, we may have
530 // sent all available data to the audio device while not reaching 530 // sent all available data to the audio device while not reaching
531 // |earliest_end_time_|. 531 // |earliest_end_time_|.
532 } 532 }
533 } 533 }
534 534
535 if (CanRead_Locked()) { 535 if (CanRead_Locked()) {
536 message_loop_->PostTask(FROM_HERE, base::Bind( 536 task_runner_->PostTask(FROM_HERE, base::Bind(
537 &AudioRendererImpl::AttemptRead, weak_this_)); 537 &AudioRendererImpl::AttemptRead, weak_this_));
538 } 538 }
539 539
540 // The |audio_time_buffered_| is the ending timestamp of the last frame 540 // The |audio_time_buffered_| is the ending timestamp of the last frame
541 // buffered at the audio device. |playback_delay| is the amount of time 541 // buffered at the audio device. |playback_delay| is the amount of time
542 // buffered at the audio device. The current time can be computed by their 542 // buffered at the audio device. The current time can be computed by their
543 // difference. 543 // difference.
544 if (audio_time_buffered_ != kNoTimestamp()) { 544 if (audio_time_buffered_ != kNoTimestamp()) {
545 // Adjust the delay according to playback rate. 545 // Adjust the delay according to playback rate.
546 base::TimeDelta adjusted_playback_delay = 546 base::TimeDelta adjusted_playback_delay =
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 } 640 }
641 } 641 }
642 642
643 void AudioRendererImpl::ChangeState_Locked(State new_state) { 643 void AudioRendererImpl::ChangeState_Locked(State new_state) {
644 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; 644 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
645 lock_.AssertAcquired(); 645 lock_.AssertAcquired();
646 state_ = new_state; 646 state_ = new_state;
647 } 647 }
648 648
649 } // namespace media 649 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698