| 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 <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 decoder_->Reset(callback); | 140 decoder_->Reset(callback); |
| 141 } | 141 } |
| 142 | 142 |
| 143 void AudioRendererImpl::Stop(const base::Closure& callback) { | 143 void AudioRendererImpl::Stop(const base::Closure& callback) { |
| 144 DCHECK(message_loop_->BelongsToCurrentThread()); | 144 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 145 DCHECK(!callback.is_null()); | 145 DCHECK(!callback.is_null()); |
| 146 | 146 |
| 147 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing | 147 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing |
| 148 // task-running guards that check |state_| with DCHECK(). | 148 // task-running guards that check |state_| with DCHECK(). |
| 149 | 149 |
| 150 if (sink_) { | 150 if (sink_.get()) { |
| 151 sink_->Stop(); | 151 sink_->Stop(); |
| 152 sink_ = NULL; | 152 sink_ = NULL; |
| 153 } | 153 } |
| 154 | 154 |
| 155 { | 155 { |
| 156 base::AutoLock auto_lock(lock_); | 156 base::AutoLock auto_lock(lock_); |
| 157 state_ = kStopped; | 157 state_ = kStopped; |
| 158 algorithm_.reset(NULL); | 158 algorithm_.reset(NULL); |
| 159 init_cb_.Reset(); | 159 init_cb_.Reset(); |
| 160 underflow_cb_.Reset(); | 160 underflow_cb_.Reset(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 DCHECK(stream); | 205 DCHECK(stream); |
| 206 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); | 206 DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); |
| 207 DCHECK(!init_cb.is_null()); | 207 DCHECK(!init_cb.is_null()); |
| 208 DCHECK(!statistics_cb.is_null()); | 208 DCHECK(!statistics_cb.is_null()); |
| 209 DCHECK(!underflow_cb.is_null()); | 209 DCHECK(!underflow_cb.is_null()); |
| 210 DCHECK(!time_cb.is_null()); | 210 DCHECK(!time_cb.is_null()); |
| 211 DCHECK(!ended_cb.is_null()); | 211 DCHECK(!ended_cb.is_null()); |
| 212 DCHECK(!disabled_cb.is_null()); | 212 DCHECK(!disabled_cb.is_null()); |
| 213 DCHECK(!error_cb.is_null()); | 213 DCHECK(!error_cb.is_null()); |
| 214 DCHECK_EQ(kUninitialized, state_); | 214 DCHECK_EQ(kUninitialized, state_); |
| 215 DCHECK(sink_); | 215 DCHECK(sink_.get()); |
| 216 | 216 |
| 217 weak_this_ = weak_factory_.GetWeakPtr(); | 217 weak_this_ = weak_factory_.GetWeakPtr(); |
| 218 init_cb_ = init_cb; | 218 init_cb_ = init_cb; |
| 219 statistics_cb_ = statistics_cb; | 219 statistics_cb_ = statistics_cb; |
| 220 underflow_cb_ = underflow_cb; | 220 underflow_cb_ = underflow_cb; |
| 221 time_cb_ = time_cb; | 221 time_cb_ = time_cb; |
| 222 ended_cb_ = ended_cb; | 222 ended_cb_ = ended_cb; |
| 223 disabled_cb_ = disabled_cb; | 223 disabled_cb_ = disabled_cb; |
| 224 error_cb_ = error_cb; | 224 error_cb_ = error_cb; |
| 225 | 225 |
| 226 decoder_selector_->SelectAudioDecoder( | 226 decoder_selector_->SelectAudioDecoder( |
| 227 stream, | 227 stream, |
| 228 statistics_cb, | 228 statistics_cb, |
| 229 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); | 229 base::Bind(&AudioRendererImpl::OnDecoderSelected, weak_this_)); |
| 230 } | 230 } |
| 231 | 231 |
| 232 void AudioRendererImpl::OnDecoderSelected( | 232 void AudioRendererImpl::OnDecoderSelected( |
| 233 scoped_ptr<AudioDecoder> decoder, | 233 scoped_ptr<AudioDecoder> decoder, |
| 234 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { | 234 scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) { |
| 235 DCHECK(message_loop_->BelongsToCurrentThread()); | 235 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 236 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); | 236 scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass()); |
| 237 | 237 |
| 238 if (state_ == kStopped) { | 238 if (state_ == kStopped) { |
| 239 DCHECK(!sink_); | 239 DCHECK(!sink_.get()); |
| 240 return; | 240 return; |
| 241 } | 241 } |
| 242 | 242 |
| 243 if (!decoder) { | 243 if (!decoder) { |
| 244 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); | 244 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); |
| 245 return; | 245 return; |
| 246 } | 246 } |
| 247 | 247 |
| 248 decoder_ = decoder.Pass(); | 248 decoder_ = decoder.Pass(); |
| 249 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); | 249 decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 // TODO(vrk): Fix this bug correctly! (crbug.com/151352) | 296 // TODO(vrk): Fix this bug correctly! (crbug.com/151352) |
| 297 if (buffer_more_audio && !preroll_aborted_) | 297 if (buffer_more_audio && !preroll_aborted_) |
| 298 algorithm_->IncreaseQueueCapacity(); | 298 algorithm_->IncreaseQueueCapacity(); |
| 299 | 299 |
| 300 state_ = kRebuffering; | 300 state_ = kRebuffering; |
| 301 } | 301 } |
| 302 } | 302 } |
| 303 | 303 |
| 304 void AudioRendererImpl::SetVolume(float volume) { | 304 void AudioRendererImpl::SetVolume(float volume) { |
| 305 DCHECK(message_loop_->BelongsToCurrentThread()); | 305 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 306 DCHECK(sink_); | 306 DCHECK(sink_.get()); |
| 307 sink_->SetVolume(volume); | 307 sink_->SetVolume(volume); |
| 308 } | 308 } |
| 309 | 309 |
| 310 void AudioRendererImpl::DecodedAudioReady( | 310 void AudioRendererImpl::DecodedAudioReady( |
| 311 AudioDecoder::Status status, | 311 AudioDecoder::Status status, |
| 312 const scoped_refptr<DataBuffer>& buffer) { | 312 const scoped_refptr<DataBuffer>& buffer) { |
| 313 DCHECK(message_loop_->BelongsToCurrentThread()); | 313 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 314 | 314 |
| 315 base::AutoLock auto_lock(lock_); | 315 base::AutoLock auto_lock(lock_); |
| 316 DCHECK(state_ == kPaused || state_ == kPrerolling || state_ == kPlaying || | 316 DCHECK(state_ == kPaused || state_ == kPrerolling || state_ == kPlaying || |
| 317 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); | 317 state_ == kUnderflow || state_ == kRebuffering || state_ == kStopped); |
| 318 | 318 |
| 319 CHECK(pending_read_); | 319 CHECK(pending_read_); |
| 320 pending_read_ = false; | 320 pending_read_ = false; |
| 321 | 321 |
| 322 if (status == AudioDecoder::kAborted) { | 322 if (status == AudioDecoder::kAborted) { |
| 323 HandleAbortedReadOrDecodeError(false); | 323 HandleAbortedReadOrDecodeError(false); |
| 324 return; | 324 return; |
| 325 } | 325 } |
| 326 | 326 |
| 327 if (status == AudioDecoder::kDecodeError) { | 327 if (status == AudioDecoder::kDecodeError) { |
| 328 HandleAbortedReadOrDecodeError(true); | 328 HandleAbortedReadOrDecodeError(true); |
| 329 return; | 329 return; |
| 330 } | 330 } |
| 331 | 331 |
| 332 DCHECK_EQ(status, AudioDecoder::kOk); | 332 DCHECK_EQ(status, AudioDecoder::kOk); |
| 333 DCHECK(buffer); | 333 DCHECK(buffer.get()); |
| 334 | 334 |
| 335 if (!splicer_->AddInput(buffer)) { | 335 if (!splicer_->AddInput(buffer)) { |
| 336 HandleAbortedReadOrDecodeError(true); | 336 HandleAbortedReadOrDecodeError(true); |
| 337 return; | 337 return; |
| 338 } | 338 } |
| 339 | 339 |
| 340 if (!splicer_->HasNextBuffer()) { | 340 if (!splicer_->HasNextBuffer()) { |
| 341 AttemptRead_Locked(); | 341 AttemptRead_Locked(); |
| 342 return; | 342 return; |
| 343 } | 343 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 break; | 429 break; |
| 430 } | 430 } |
| 431 | 431 |
| 432 return !pending_read_ && !received_end_of_stream_ && | 432 return !pending_read_ && !received_end_of_stream_ && |
| 433 !algorithm_->IsQueueFull(); | 433 !algorithm_->IsQueueFull(); |
| 434 } | 434 } |
| 435 | 435 |
| 436 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { | 436 void AudioRendererImpl::SetPlaybackRate(float playback_rate) { |
| 437 DCHECK(message_loop_->BelongsToCurrentThread()); | 437 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 438 DCHECK_GE(playback_rate, 0); | 438 DCHECK_GE(playback_rate, 0); |
| 439 DCHECK(sink_); | 439 DCHECK(sink_.get()); |
| 440 | 440 |
| 441 // We have two cases here: | 441 // We have two cases here: |
| 442 // Play: current_playback_rate == 0 && playback_rate != 0 | 442 // Play: current_playback_rate == 0 && playback_rate != 0 |
| 443 // Pause: current_playback_rate != 0 && playback_rate == 0 | 443 // Pause: current_playback_rate != 0 && playback_rate == 0 |
| 444 float current_playback_rate = algorithm_->playback_rate(); | 444 float current_playback_rate = algorithm_->playback_rate(); |
| 445 if (current_playback_rate == 0 && playback_rate != 0) | 445 if (current_playback_rate == 0 && playback_rate != 0) |
| 446 DoPlay(); | 446 DoPlay(); |
| 447 else if (current_playback_rate != 0 && playback_rate == 0) | 447 else if (current_playback_rate != 0 && playback_rate == 0) |
| 448 DoPause(); | 448 DoPause(); |
| 449 | 449 |
| 450 base::AutoLock auto_lock(lock_); | 450 base::AutoLock auto_lock(lock_); |
| 451 algorithm_->SetPlaybackRate(playback_rate); | 451 algorithm_->SetPlaybackRate(playback_rate); |
| 452 } | 452 } |
| 453 | 453 |
| 454 bool AudioRendererImpl::IsBeforePrerollTime( | 454 bool AudioRendererImpl::IsBeforePrerollTime( |
| 455 const scoped_refptr<DataBuffer>& buffer) { | 455 const scoped_refptr<DataBuffer>& buffer) { |
| 456 return (state_ == kPrerolling) && buffer && !buffer->IsEndOfStream() && | 456 return (state_ == kPrerolling) && buffer.get() && !buffer->IsEndOfStream() && |
| 457 (buffer->GetTimestamp() + buffer->GetDuration()) < preroll_timestamp_; | 457 (buffer->GetTimestamp() + buffer->GetDuration()) < preroll_timestamp_; |
| 458 } | 458 } |
| 459 | 459 |
| 460 int AudioRendererImpl::Render(AudioBus* audio_bus, | 460 int AudioRendererImpl::Render(AudioBus* audio_bus, |
| 461 int audio_delay_milliseconds) { | 461 int audio_delay_milliseconds) { |
| 462 if (actual_frames_per_buffer_ != audio_bus->frames()) { | 462 if (actual_frames_per_buffer_ != audio_bus->frames()) { |
| 463 audio_buffer_.reset( | 463 audio_buffer_.reset( |
| 464 new uint8[audio_bus->frames() * audio_parameters_.GetBytesPerFrame()]); | 464 new uint8[audio_bus->frames() * audio_parameters_.GetBytesPerFrame()]); |
| 465 actual_frames_per_buffer_ = audio_bus->frames(); | 465 actual_frames_per_buffer_ = audio_bus->frames(); |
| 466 } | 466 } |
| 467 | 467 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 case kUnderflow: | 639 case kUnderflow: |
| 640 case kRebuffering: | 640 case kRebuffering: |
| 641 case kStopped: | 641 case kStopped: |
| 642 if (status != PIPELINE_OK) | 642 if (status != PIPELINE_OK) |
| 643 error_cb_.Run(status); | 643 error_cb_.Run(status); |
| 644 return; | 644 return; |
| 645 } | 645 } |
| 646 } | 646 } |
| 647 | 647 |
| 648 } // namespace media | 648 } // namespace media |
| OLD | NEW |