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

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: rebase Created 7 years 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
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/decrypting_audio_decoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 : message_loop_(message_loop), 45 : task_runner_(task_runner),
46 weak_factory_(this), 46 weak_factory_(this),
47 sink_(sink), 47 sink_(sink),
48 decoder_selector_(new AudioDecoderSelector( 48 decoder_selector_(new AudioDecoderSelector(
49 message_loop, decoders.Pass(), set_decryptor_ready_cb)), 49 task_runner, decoders.Pass(), set_decryptor_ready_cb)),
50 now_cb_(base::Bind(&base::TimeTicks::Now)), 50 now_cb_(base::Bind(&base::TimeTicks::Now)),
51 state_(kUninitialized), 51 state_(kUninitialized),
52 sink_playing_(false), 52 sink_playing_(false),
53 pending_read_(false), 53 pending_read_(false),
54 received_end_of_stream_(false), 54 received_end_of_stream_(false),
55 rendered_end_of_stream_(false), 55 rendered_end_of_stream_(false),
56 audio_time_buffered_(kNoTimestamp()), 56 audio_time_buffered_(kNoTimestamp()),
57 current_time_(kNoTimestamp()), 57 current_time_(kNoTimestamp()),
58 underflow_disabled_(false), 58 underflow_disabled_(false),
59 preroll_aborted_(false) { 59 preroll_aborted_(false) {
60 } 60 }
61 61
62 AudioRendererImpl::~AudioRendererImpl() { 62 AudioRendererImpl::~AudioRendererImpl() {
63 // Stop() should have been called and |algorithm_| should have been destroyed. 63 // Stop() should have been called and |algorithm_| should have been destroyed.
64 DCHECK(state_ == kUninitialized || state_ == kStopped); 64 DCHECK(state_ == kUninitialized || state_ == kStopped);
65 DCHECK(!algorithm_.get()); 65 DCHECK(!algorithm_.get());
66 } 66 }
67 67
68 void AudioRendererImpl::Play(const base::Closure& callback) { 68 void AudioRendererImpl::Play(const base::Closure& callback) {
69 DCHECK(message_loop_->BelongsToCurrentThread()); 69 DCHECK(task_runner_->BelongsToCurrentThread());
70 70
71 base::AutoLock auto_lock(lock_); 71 base::AutoLock auto_lock(lock_);
72 DCHECK_EQ(state_, kPaused); 72 DCHECK_EQ(state_, kPaused);
73 ChangeState_Locked(kPlaying); 73 ChangeState_Locked(kPlaying);
74 callback.Run(); 74 callback.Run();
75 earliest_end_time_ = now_cb_.Run(); 75 earliest_end_time_ = now_cb_.Run();
76 76
77 if (algorithm_->playback_rate() != 0) 77 if (algorithm_->playback_rate() != 0)
78 DoPlay_Locked(); 78 DoPlay_Locked();
79 else 79 else
80 DCHECK(!sink_playing_); 80 DCHECK(!sink_playing_);
81 } 81 }
82 82
83 void AudioRendererImpl::DoPlay_Locked() { 83 void AudioRendererImpl::DoPlay_Locked() {
84 DCHECK(message_loop_->BelongsToCurrentThread()); 84 DCHECK(task_runner_->BelongsToCurrentThread());
85 lock_.AssertAcquired(); 85 lock_.AssertAcquired();
86 earliest_end_time_ = now_cb_.Run(); 86 earliest_end_time_ = now_cb_.Run();
87 87
88 if ((state_ == kPlaying || state_ == kRebuffering || state_ == kUnderflow) && 88 if ((state_ == kPlaying || state_ == kRebuffering || state_ == kUnderflow) &&
89 !sink_playing_) { 89 !sink_playing_) {
90 { 90 {
91 base::AutoUnlock auto_unlock(lock_); 91 base::AutoUnlock auto_unlock(lock_);
92 sink_->Play(); 92 sink_->Play();
93 } 93 }
94 94
95 sink_playing_ = true; 95 sink_playing_ = true;
96 } 96 }
97 } 97 }
98 98
99 void AudioRendererImpl::Pause(const base::Closure& callback) { 99 void AudioRendererImpl::Pause(const base::Closure& callback) {
100 DCHECK(message_loop_->BelongsToCurrentThread()); 100 DCHECK(task_runner_->BelongsToCurrentThread());
101 101
102 base::AutoLock auto_lock(lock_); 102 base::AutoLock auto_lock(lock_);
103 DCHECK(state_ == kPlaying || state_ == kUnderflow || 103 DCHECK(state_ == kPlaying || state_ == kUnderflow ||
104 state_ == kRebuffering) << "state_ == " << state_; 104 state_ == kRebuffering) << "state_ == " << state_;
105 ChangeState_Locked(kPaused); 105 ChangeState_Locked(kPaused);
106 106
107 DoPause_Locked(); 107 DoPause_Locked();
108 108
109 callback.Run(); 109 callback.Run();
110 } 110 }
111 111
112 void AudioRendererImpl::DoPause_Locked() { 112 void AudioRendererImpl::DoPause_Locked() {
113 DCHECK(message_loop_->BelongsToCurrentThread()); 113 DCHECK(task_runner_->BelongsToCurrentThread());
114 lock_.AssertAcquired(); 114 lock_.AssertAcquired();
115 115
116 if (sink_playing_) { 116 if (sink_playing_) {
117 { 117 {
118 base::AutoUnlock auto_unlock(lock_); 118 base::AutoUnlock auto_unlock(lock_);
119 sink_->Pause(); 119 sink_->Pause();
120 } 120 }
121 sink_playing_ = false; 121 sink_playing_ = false;
122 } 122 }
123 } 123 }
124 124
125 void AudioRendererImpl::Flush(const base::Closure& callback) { 125 void AudioRendererImpl::Flush(const base::Closure& callback) {
126 DCHECK(message_loop_->BelongsToCurrentThread()); 126 DCHECK(task_runner_->BelongsToCurrentThread());
127 127
128 base::AutoLock auto_lock(lock_); 128 base::AutoLock auto_lock(lock_);
129 DCHECK_EQ(state_, kPaused); 129 DCHECK_EQ(state_, kPaused);
130 DCHECK(flush_cb_.is_null()); 130 DCHECK(flush_cb_.is_null());
131 131
132 flush_cb_ = callback; 132 flush_cb_ = callback;
133 133
134 if (pending_read_) { 134 if (pending_read_) {
135 ChangeState_Locked(kFlushing); 135 ChangeState_Locked(kFlushing);
136 return; 136 return;
137 } 137 }
138 138
139 DoFlush_Locked(); 139 DoFlush_Locked();
140 } 140 }
141 141
142 void AudioRendererImpl::DoFlush_Locked() { 142 void AudioRendererImpl::DoFlush_Locked() {
143 DCHECK(message_loop_->BelongsToCurrentThread()); 143 DCHECK(task_runner_->BelongsToCurrentThread());
144 lock_.AssertAcquired(); 144 lock_.AssertAcquired();
145 145
146 DCHECK(!pending_read_); 146 DCHECK(!pending_read_);
147 DCHECK_EQ(state_, kPaused); 147 DCHECK_EQ(state_, kPaused);
148 148
149 if (decrypting_demuxer_stream_) { 149 if (decrypting_demuxer_stream_) {
150 decrypting_demuxer_stream_->Reset(BindToCurrentLoop( 150 decrypting_demuxer_stream_->Reset(BindToCurrentLoop(
151 base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_))); 151 base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_)));
152 return; 152 return;
153 } 153 }
154 154
155 ResetDecoder(); 155 ResetDecoder();
156 } 156 }
157 157
158 void AudioRendererImpl::ResetDecoder() { 158 void AudioRendererImpl::ResetDecoder() {
159 DCHECK(message_loop_->BelongsToCurrentThread()); 159 DCHECK(task_runner_->BelongsToCurrentThread());
160 decoder_->Reset(BindToCurrentLoop( 160 decoder_->Reset(BindToCurrentLoop(
161 base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_))); 161 base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_)));
162 } 162 }
163 163
164 void AudioRendererImpl::ResetDecoderDone() { 164 void AudioRendererImpl::ResetDecoderDone() {
165 base::AutoLock auto_lock(lock_); 165 base::AutoLock auto_lock(lock_);
166 if (state_ == kStopped) 166 if (state_ == kStopped)
167 return; 167 return;
168 168
169 DCHECK_EQ(state_, kPaused); 169 DCHECK_EQ(state_, kPaused);
170 DCHECK(!flush_cb_.is_null()); 170 DCHECK(!flush_cb_.is_null());
171 171
172 audio_time_buffered_ = kNoTimestamp(); 172 audio_time_buffered_ = kNoTimestamp();
173 current_time_ = kNoTimestamp(); 173 current_time_ = kNoTimestamp();
174 received_end_of_stream_ = false; 174 received_end_of_stream_ = false;
175 rendered_end_of_stream_ = false; 175 rendered_end_of_stream_ = false;
176 preroll_aborted_ = false; 176 preroll_aborted_ = false;
177 177
178 earliest_end_time_ = now_cb_.Run(); 178 earliest_end_time_ = now_cb_.Run();
179 splicer_->Reset(); 179 splicer_->Reset();
180 algorithm_->FlushBuffers(); 180 algorithm_->FlushBuffers();
181 181
182 base::ResetAndReturn(&flush_cb_).Run(); 182 base::ResetAndReturn(&flush_cb_).Run();
183 } 183 }
184 184
185 void AudioRendererImpl::Stop(const base::Closure& callback) { 185 void AudioRendererImpl::Stop(const base::Closure& callback) {
186 DCHECK(message_loop_->BelongsToCurrentThread()); 186 DCHECK(task_runner_->BelongsToCurrentThread());
187 DCHECK(!callback.is_null()); 187 DCHECK(!callback.is_null());
188 188
189 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing 189 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
190 // task-running guards that check |state_| with DCHECK(). 190 // task-running guards that check |state_| with DCHECK().
191 191
192 if (sink_) { 192 if (sink_) {
193 sink_->Stop(); 193 sink_->Stop();
194 sink_ = NULL; 194 sink_ = NULL;
195 } 195 }
196 196
197 { 197 {
198 base::AutoLock auto_lock(lock_); 198 base::AutoLock auto_lock(lock_);
199 ChangeState_Locked(kStopped); 199 ChangeState_Locked(kStopped);
200 algorithm_.reset(NULL); 200 algorithm_.reset(NULL);
201 init_cb_.Reset(); 201 init_cb_.Reset();
202 underflow_cb_.Reset(); 202 underflow_cb_.Reset();
203 time_cb_.Reset(); 203 time_cb_.Reset();
204 flush_cb_.Reset(); 204 flush_cb_.Reset();
205 } 205 }
206 206
207 callback.Run(); 207 callback.Run();
208 } 208 }
209 209
210 void AudioRendererImpl::Preroll(base::TimeDelta time, 210 void AudioRendererImpl::Preroll(base::TimeDelta time,
211 const PipelineStatusCB& cb) { 211 const PipelineStatusCB& cb) {
212 DCHECK(message_loop_->BelongsToCurrentThread()); 212 DCHECK(task_runner_->BelongsToCurrentThread());
213 213
214 base::AutoLock auto_lock(lock_); 214 base::AutoLock auto_lock(lock_);
215 DCHECK(!sink_playing_); 215 DCHECK(!sink_playing_);
216 DCHECK_EQ(state_, kPaused); 216 DCHECK_EQ(state_, kPaused);
217 DCHECK(!pending_read_) << "Pending read must complete before seeking"; 217 DCHECK(!pending_read_) << "Pending read must complete before seeking";
218 DCHECK(preroll_cb_.is_null()); 218 DCHECK(preroll_cb_.is_null());
219 219
220 ChangeState_Locked(kPrerolling); 220 ChangeState_Locked(kPrerolling);
221 preroll_cb_ = cb; 221 preroll_cb_ = cb;
222 preroll_timestamp_ = time; 222 preroll_timestamp_ = time;
223 223
224 AttemptRead_Locked(); 224 AttemptRead_Locked();
225 } 225 }
226 226
227 void AudioRendererImpl::Initialize(DemuxerStream* stream, 227 void AudioRendererImpl::Initialize(DemuxerStream* stream,
228 const PipelineStatusCB& init_cb, 228 const PipelineStatusCB& init_cb,
229 const StatisticsCB& statistics_cb, 229 const StatisticsCB& statistics_cb,
230 const base::Closure& underflow_cb, 230 const base::Closure& underflow_cb,
231 const TimeCB& time_cb, 231 const TimeCB& time_cb,
232 const base::Closure& ended_cb, 232 const base::Closure& ended_cb,
233 const base::Closure& disabled_cb, 233 const base::Closure& disabled_cb,
234 const PipelineStatusCB& error_cb) { 234 const PipelineStatusCB& error_cb) {
235 DCHECK(message_loop_->BelongsToCurrentThread()); 235 DCHECK(task_runner_->BelongsToCurrentThread());
236 DCHECK(stream); 236 DCHECK(stream);
237 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); 237 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
238 DCHECK(!init_cb.is_null()); 238 DCHECK(!init_cb.is_null());
239 DCHECK(!statistics_cb.is_null()); 239 DCHECK(!statistics_cb.is_null());
240 DCHECK(!underflow_cb.is_null()); 240 DCHECK(!underflow_cb.is_null());
241 DCHECK(!time_cb.is_null()); 241 DCHECK(!time_cb.is_null());
242 DCHECK(!ended_cb.is_null()); 242 DCHECK(!ended_cb.is_null());
243 DCHECK(!disabled_cb.is_null()); 243 DCHECK(!disabled_cb.is_null());
244 DCHECK(!error_cb.is_null()); 244 DCHECK(!error_cb.is_null());
245 DCHECK_EQ(kUninitialized, state_); 245 DCHECK_EQ(kUninitialized, state_);
(...skipping 10 matching lines...) Expand all
256 256
257 decoder_selector_->SelectAudioDecoder( 257 decoder_selector_->SelectAudioDecoder(
258 stream, 258 stream,
259 statistics_cb, 259 statistics_cb,
260 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); 260 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_));
261 } 261 }
262 262
263 void AudioRendererImpl::OnDecoderSelected( 263 void AudioRendererImpl::OnDecoderSelected(
264 scoped_ptr<AudioDecoder> decoder, 264 scoped_ptr<AudioDecoder> decoder,
265 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { 265 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
266 DCHECK(message_loop_->BelongsToCurrentThread()); 266 DCHECK(task_runner_->BelongsToCurrentThread());
267 267
268 base::AutoLock auto_lock(lock_); 268 base::AutoLock auto_lock(lock_);
269 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); 269 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass());
270 270
271 if (state_ == kStopped) { 271 if (state_ == kStopped) {
272 DCHECK(!sink_); 272 DCHECK(!sink_);
273 return; 273 return;
274 } 274 }
275 275
276 if (!decoder) { 276 if (!decoder) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 // Some sinks play on start... 313 // Some sinks play on start...
314 sink_->Pause(); 314 sink_->Pause();
315 } 315 }
316 316
317 DCHECK(!sink_playing_); 317 DCHECK(!sink_playing_);
318 318
319 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 319 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
320 } 320 }
321 321
322 void AudioRendererImpl::ResumeAfterUnderflow() { 322 void AudioRendererImpl::ResumeAfterUnderflow() {
323 DCHECK(message_loop_->BelongsToCurrentThread()); 323 DCHECK(task_runner_->BelongsToCurrentThread());
324 base::AutoLock auto_lock(lock_); 324 base::AutoLock auto_lock(lock_);
325 if (state_ == kUnderflow) { 325 if (state_ == kUnderflow) {
326 // The "!preroll_aborted_" is a hack. If preroll is aborted, then we 326 // The "!preroll_aborted_" is a hack. If preroll is aborted, then we
327 // shouldn't even reach the kUnderflow state to begin with. But for now 327 // shouldn't even reach the kUnderflow state to begin with. But for now
328 // we're just making sure that the audio buffer capacity (i.e. the 328 // we're just making sure that the audio buffer capacity (i.e. the
329 // number of bytes that need to be buffered for preroll to complete) 329 // number of bytes that need to be buffered for preroll to complete)
330 // does not increase due to an aborted preroll. 330 // does not increase due to an aborted preroll.
331 // TODO(vrk): Fix this bug correctly! (crbug.com/151352) 331 // TODO(vrk): Fix this bug correctly! (crbug.com/151352)
332 if (!preroll_aborted_) 332 if (!preroll_aborted_)
333 algorithm_->IncreaseQueueCapacity(); 333 algorithm_->IncreaseQueueCapacity();
334 334
335 ChangeState_Locked(kRebuffering); 335 ChangeState_Locked(kRebuffering);
336 } 336 }
337 } 337 }
338 338
339 void AudioRendererImpl::SetVolume(float volume) { 339 void AudioRendererImpl::SetVolume(float volume) {
340 DCHECK(message_loop_->BelongsToCurrentThread()); 340 DCHECK(task_runner_->BelongsToCurrentThread());
341 DCHECK(sink_); 341 DCHECK(sink_);
342 sink_->SetVolume(volume); 342 sink_->SetVolume(volume);
343 } 343 }
344 344
345 void AudioRendererImpl::DecodedAudioReady( 345 void AudioRendererImpl::DecodedAudioReady(
346 AudioDecoder::Status status, 346 AudioDecoder::Status status,
347 const scoped_refptr<AudioBuffer>& buffer) { 347 const scoped_refptr<AudioBuffer>& buffer) {
348 DVLOG(1) << __FUNCTION__ << "(" << status << ")"; 348 DVLOG(1) << __FUNCTION__ << "(" << status << ")";
349 DCHECK(message_loop_->BelongsToCurrentThread()); 349 DCHECK(task_runner_->BelongsToCurrentThread());
350 350
351 base::AutoLock auto_lock(lock_); 351 base::AutoLock auto_lock(lock_);
352 DCHECK(state_ != kUninitialized); 352 DCHECK(state_ != kUninitialized);
353 353
354 CHECK(pending_read_); 354 CHECK(pending_read_);
355 pending_read_ = false; 355 pending_read_ = false;
356 356
357 if (status == AudioDecoder::kAborted) { 357 if (status == AudioDecoder::kAborted) {
358 HandleAbortedReadOrDecodeError(false); 358 HandleAbortedReadOrDecodeError(false);
359 return; 359 return;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 } 456 }
457 return false; 457 return false;
458 } 458 }
459 459
460 void AudioRendererImpl::AttemptRead() { 460 void AudioRendererImpl::AttemptRead() {
461 base::AutoLock auto_lock(lock_); 461 base::AutoLock auto_lock(lock_);
462 AttemptRead_Locked(); 462 AttemptRead_Locked();
463 } 463 }
464 464
465 void AudioRendererImpl::AttemptRead_Locked() { 465 void AudioRendererImpl::AttemptRead_Locked() {
466 DCHECK(message_loop_->BelongsToCurrentThread()); 466 DCHECK(task_runner_->BelongsToCurrentThread());
467 lock_.AssertAcquired(); 467 lock_.AssertAcquired();
468 468
469 if (!CanRead_Locked()) 469 if (!CanRead_Locked())
470 return; 470 return;
471 471
472 pending_read_ = true; 472 pending_read_ = true;
473 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_)); 473 decoder_->Read(base::Bind(&AudioRendererImpl::DecodedAudioReady, weak_this_));
474 } 474 }
475 475
476 bool AudioRendererImpl::CanRead_Locked() { 476 bool AudioRendererImpl::CanRead_Locked() {
(...skipping 12 matching lines...) Expand all
489 case kRebuffering: 489 case kRebuffering:
490 break; 490 break;
491 } 491 }
492 492
493 return !pending_read_ && !received_end_of_stream_ && 493 return !pending_read_ && !received_end_of_stream_ &&
494 !algorithm_->IsQueueFull(); 494 !algorithm_->IsQueueFull();
495 } 495 }
496 496
497 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { 497 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
498 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")"; 498 DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
499 DCHECK(message_loop_->BelongsToCurrentThread()); 499 DCHECK(task_runner_->BelongsToCurrentThread());
500 DCHECK_GE(playback_rate, 0); 500 DCHECK_GE(playback_rate, 0);
501 DCHECK(sink_); 501 DCHECK(sink_);
502 502
503 base::AutoLock auto_lock(lock_); 503 base::AutoLock auto_lock(lock_);
504 504
505 // We have two cases here: 505 // We have two cases here:
506 // Play: current_playback_rate == 0 && playback_rate != 0 506 // Play: current_playback_rate == 0 && playback_rate != 0
507 // Pause: current_playback_rate != 0 && playback_rate == 0 507 // Pause: current_playback_rate != 0 && playback_rate == 0
508 float current_playback_rate = algorithm_->playback_rate(); 508 float current_playback_rate = algorithm_->playback_rate();
509 if (current_playback_rate == 0 && playback_rate != 0) 509 if (current_playback_rate == 0 && playback_rate != 0)
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 ChangeState_Locked(kUnderflow); 574 ChangeState_Locked(kUnderflow);
575 underflow_cb = underflow_cb_; 575 underflow_cb = underflow_cb_;
576 } else { 576 } else {
577 // We can't write any data this cycle. For example, we may have 577 // We can't write any data this cycle. For example, we may have
578 // sent all available data to the audio device while not reaching 578 // sent all available data to the audio device while not reaching
579 // |earliest_end_time_|. 579 // |earliest_end_time_|.
580 } 580 }
581 } 581 }
582 582
583 if (CanRead_Locked()) { 583 if (CanRead_Locked()) {
584 message_loop_->PostTask(FROM_HERE, base::Bind( 584 task_runner_->PostTask(FROM_HERE, base::Bind(
585 &AudioRendererImpl::AttemptRead, weak_this_)); 585 &AudioRendererImpl::AttemptRead, weak_this_));
586 } 586 }
587 587
588 // The |audio_time_buffered_| is the ending timestamp of the last frame 588 // The |audio_time_buffered_| is the ending timestamp of the last frame
589 // buffered at the audio device. |playback_delay| is the amount of time 589 // buffered at the audio device. |playback_delay| is the amount of time
590 // buffered at the audio device. The current time can be computed by their 590 // buffered at the audio device. The current time can be computed by their
591 // difference. 591 // difference.
592 if (audio_time_buffered_ != kNoTimestamp()) { 592 if (audio_time_buffered_ != kNoTimestamp()) {
593 // Adjust the delay according to playback rate. 593 // Adjust the delay according to playback rate.
594 base::TimeDelta adjusted_playback_delay = 594 base::TimeDelta adjusted_playback_delay =
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 } 700 }
701 } 701 }
702 702
703 void AudioRendererImpl::ChangeState_Locked(State new_state) { 703 void AudioRendererImpl::ChangeState_Locked(State new_state) {
704 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state; 704 DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
705 lock_.AssertAcquired(); 705 lock_.AssertAcquired();
706 state_ = new_state; 706 state_ = new_state;
707 } 707 }
708 708
709 } // namespace media 709 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/audio_renderer_impl.h ('k') | media/filters/decrypting_audio_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698