| 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" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 void AudioRendererImpl::Pause(const base::Closure& callback) { | 66 void AudioRendererImpl::Pause(const base::Closure& callback) { |
| 67 { | 67 { |
| 68 base::AutoLock auto_lock(lock_); | 68 base::AutoLock auto_lock(lock_); |
| 69 DCHECK(state_ == kPlaying || state_ == kUnderflow || | 69 DCHECK(state_ == kPlaying || state_ == kUnderflow || |
| 70 state_ == kRebuffering); | 70 state_ == kRebuffering); |
| 71 pause_cb_ = callback; | 71 pause_cb_ = callback; |
| 72 state_ = kPaused; | 72 state_ = kPaused; |
| 73 | 73 |
| 74 // Pause only when we've completed our pending read. | 74 // Pause only when we've completed our pending read. |
| 75 if (!pending_read_) { | 75 if (!pending_read_) |
| 76 pause_cb_.Run(); | 76 base::ResetAndReturn(&pause_cb_).Run(); |
| 77 pause_cb_.Reset(); | |
| 78 } | |
| 79 } | 77 } |
| 80 | 78 |
| 81 if (stopped_) | 79 if (stopped_) |
| 82 return; | 80 return; |
| 83 | 81 |
| 84 DoPause(); | 82 DoPause(); |
| 85 } | 83 } |
| 86 | 84 |
| 87 void AudioRendererImpl::DoPause() { | 85 void AudioRendererImpl::DoPause() { |
| 88 DCHECK(sink_.get()); | 86 DCHECK(sink_.get()); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 return; | 225 return; |
| 228 sink_->SetVolume(volume); | 226 sink_->SetVolume(volume); |
| 229 } | 227 } |
| 230 | 228 |
| 231 AudioRendererImpl::~AudioRendererImpl() { | 229 AudioRendererImpl::~AudioRendererImpl() { |
| 232 // Stop() should have been called and |algorithm_| should have been destroyed. | 230 // Stop() should have been called and |algorithm_| should have been destroyed. |
| 233 DCHECK(state_ == kUninitialized || state_ == kStopped); | 231 DCHECK(state_ == kUninitialized || state_ == kStopped); |
| 234 DCHECK(!algorithm_.get()); | 232 DCHECK(!algorithm_.get()); |
| 235 } | 233 } |
| 236 | 234 |
| 237 void AudioRendererImpl::DecodedAudioReady(scoped_refptr<Buffer> buffer) { | 235 void AudioRendererImpl::DecodedAudioReady(AudioDecoder::Status status, |
| 236 const scoped_refptr<Buffer>& buffer) { |
| 238 base::AutoLock auto_lock(lock_); | 237 base::AutoLock auto_lock(lock_); |
| 239 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying || | 238 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying || |
| 240 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); | 239 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); |
| 241 | 240 |
| 242 CHECK(pending_read_); | 241 CHECK(pending_read_); |
| 243 pending_read_ = false; | 242 pending_read_ = false; |
| 244 | 243 |
| 245 if (buffer && buffer->IsEndOfStream()) { | 244 if (status == AudioDecoder::kAborted) { |
| 245 HandleAbortedReadOrDecodeError(false); |
| 246 return; |
| 247 } |
| 248 |
| 249 if (status == AudioDecoder::kDecodeError) { |
| 250 HandleAbortedReadOrDecodeError(true); |
| 251 return; |
| 252 } |
| 253 |
| 254 DCHECK_EQ(status, AudioDecoder::kOk); |
| 255 DCHECK(buffer); |
| 256 |
| 257 if (buffer->IsEndOfStream()) { |
| 246 received_end_of_stream_ = true; | 258 received_end_of_stream_ = true; |
| 247 | 259 |
| 248 // Transition to kPlaying if we are currently handling an underflow since | 260 // Transition to kPlaying if we are currently handling an underflow since |
| 249 // no more data will be arriving. | 261 // no more data will be arriving. |
| 250 if (state_ == kUnderflow || state_ == kRebuffering) | 262 if (state_ == kUnderflow || state_ == kRebuffering) |
| 251 state_ = kPlaying; | 263 state_ = kPlaying; |
| 252 } | 264 } |
| 253 | 265 |
| 254 switch (state_) { | 266 switch (state_) { |
| 255 case kUninitialized: | 267 case kUninitialized: |
| 256 NOTREACHED(); | 268 NOTREACHED(); |
| 257 return; | 269 return; |
| 258 case kPaused: | 270 case kPaused: |
| 259 if (buffer && !buffer->IsEndOfStream()) | 271 if (!buffer->IsEndOfStream()) |
| 260 algorithm_->EnqueueBuffer(buffer); | 272 algorithm_->EnqueueBuffer(buffer); |
| 261 DCHECK(!pending_read_); | 273 DCHECK(!pending_read_); |
| 262 base::ResetAndReturn(&pause_cb_).Run(); | 274 base::ResetAndReturn(&pause_cb_).Run(); |
| 263 return; | 275 return; |
| 264 case kSeeking: | 276 case kSeeking: |
| 265 if (IsBeforeSeekTime(buffer)) { | 277 if (IsBeforeSeekTime(buffer)) { |
| 266 ScheduleRead_Locked(); | 278 ScheduleRead_Locked(); |
| 267 return; | 279 return; |
| 268 } | 280 } |
| 269 if (buffer && !buffer->IsEndOfStream()) { | 281 if (!buffer->IsEndOfStream()) { |
| 270 algorithm_->EnqueueBuffer(buffer); | 282 algorithm_->EnqueueBuffer(buffer); |
| 271 if (!algorithm_->IsQueueFull()) | 283 if (!algorithm_->IsQueueFull()) |
| 272 return; | 284 return; |
| 273 } | 285 } |
| 274 state_ = kPaused; | 286 state_ = kPaused; |
| 275 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); | 287 base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK); |
| 276 return; | 288 return; |
| 277 case kPlaying: | 289 case kPlaying: |
| 278 case kUnderflow: | 290 case kUnderflow: |
| 279 case kRebuffering: | 291 case kRebuffering: |
| 280 if (buffer && !buffer->IsEndOfStream()) | 292 if (!buffer->IsEndOfStream()) |
| 281 algorithm_->EnqueueBuffer(buffer); | 293 algorithm_->EnqueueBuffer(buffer); |
| 282 return; | 294 return; |
| 283 case kStopped: | 295 case kStopped: |
| 284 return; | 296 return; |
| 285 } | 297 } |
| 286 } | 298 } |
| 287 | 299 |
| 288 void AudioRendererImpl::ScheduleRead_Locked() { | 300 void AudioRendererImpl::ScheduleRead_Locked() { |
| 289 lock_.AssertAcquired(); | 301 lock_.AssertAcquired(); |
| 290 if (pending_read_ || state_ == kPaused) | 302 if (pending_read_ || state_ == kPaused) |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 | 520 |
| 509 void AudioRendererImpl::OnRenderError() { | 521 void AudioRendererImpl::OnRenderError() { |
| 510 host_->DisableAudioRenderer(); | 522 host_->DisableAudioRenderer(); |
| 511 } | 523 } |
| 512 | 524 |
| 513 void AudioRendererImpl::DisableUnderflowForTesting() { | 525 void AudioRendererImpl::DisableUnderflowForTesting() { |
| 514 DCHECK(!is_initialized_); | 526 DCHECK(!is_initialized_); |
| 515 underflow_disabled_ = true; | 527 underflow_disabled_ = true; |
| 516 } | 528 } |
| 517 | 529 |
| 530 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) { |
| 531 PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK; |
| 532 switch (state_) { |
| 533 case kUninitialized: |
| 534 NOTREACHED(); |
| 535 return; |
| 536 case kPaused: |
| 537 if (status != PIPELINE_OK) |
| 538 host_->SetError(status); |
| 539 base::ResetAndReturn(&pause_cb_).Run(); |
| 540 return; |
| 541 case kSeeking: |
| 542 state_ = kPaused; |
| 543 base::ResetAndReturn(&seek_cb_).Run(status); |
| 544 return; |
| 545 case kPlaying: |
| 546 case kUnderflow: |
| 547 case kRebuffering: |
| 548 case kStopped: |
| 549 if (status != PIPELINE_OK) |
| 550 host_->SetError(status); |
| 551 return; |
| 552 } |
| 553 } |
| 554 |
| 518 } // namespace media | 555 } // namespace media |
| OLD | NEW |