| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/decoder_stream.h" | 5 #include "media/filters/decoder_stream.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 state_(STATE_UNINITIALIZED), | 52 state_(STATE_UNINITIALIZED), |
| 53 stream_(NULL), | 53 stream_(NULL), |
| 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, | 54 decoder_selector_(new DecoderSelector<StreamType>(task_runner, |
| 55 std::move(decoders), | 55 std::move(decoders), |
| 56 media_log)), | 56 media_log)), |
| 57 decoded_frames_since_fallback_(0), | 57 decoded_frames_since_fallback_(0), |
| 58 active_splice_(false), | 58 active_splice_(false), |
| 59 decoding_eos_(false), | 59 decoding_eos_(false), |
| 60 pending_decode_requests_(0), | 60 pending_decode_requests_(0), |
| 61 duration_tracker_(8), | 61 duration_tracker_(8), |
| 62 sequence_token_(0), |
| 62 weak_factory_(this) {} | 63 weak_factory_(this) {} |
| 63 | 64 |
| 64 template <DemuxerStream::Type StreamType> | 65 template <DemuxerStream::Type StreamType> |
| 65 DecoderStream<StreamType>::~DecoderStream() { | 66 DecoderStream<StreamType>::~DecoderStream() { |
| 66 FUNCTION_DVLOG(2); | 67 FUNCTION_DVLOG(2); |
| 67 DCHECK(task_runner_->BelongsToCurrentThread()); | 68 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 68 | 69 |
| 69 decoder_selector_.reset(); | 70 decoder_selector_.reset(); |
| 70 | 71 |
| 71 if (!init_cb_.is_null()) { | 72 if (!init_cb_.is_null()) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) | 247 DCHECK(state_ == STATE_INITIALIZING || state_ == STATE_REINITIALIZING_DECODER) |
| 247 << state_; | 248 << state_; |
| 248 if (state_ == STATE_INITIALIZING) { | 249 if (state_ == STATE_INITIALIZING) { |
| 249 DCHECK(!init_cb_.is_null()); | 250 DCHECK(!init_cb_.is_null()); |
| 250 DCHECK(read_cb_.is_null()); | 251 DCHECK(read_cb_.is_null()); |
| 251 DCHECK(reset_cb_.is_null()); | 252 DCHECK(reset_cb_.is_null()); |
| 252 } else { | 253 } else { |
| 253 DCHECK(decoder_); | 254 DCHECK(decoder_); |
| 254 } | 255 } |
| 255 | 256 |
| 257 ++sequence_token_; |
| 256 previous_decoder_ = std::move(decoder_); | 258 previous_decoder_ = std::move(decoder_); |
| 257 decoded_frames_since_fallback_ = 0; | 259 decoded_frames_since_fallback_ = 0; |
| 258 decoder_ = std::move(selected_decoder); | 260 decoder_ = std::move(selected_decoder); |
| 259 if (decrypting_demuxer_stream) { | 261 if (decrypting_demuxer_stream) { |
| 260 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); | 262 decrypting_demuxer_stream_ = std::move(decrypting_demuxer_stream); |
| 261 stream_ = decrypting_demuxer_stream_.get(); | 263 stream_ = decrypting_demuxer_stream_.get(); |
| 262 } | 264 } |
| 263 | 265 |
| 264 if (!decoder_) { | 266 if (!decoder_) { |
| 265 if (state_ == STATE_INITIALIZING) { | 267 if (state_ == STATE_INITIALIZING) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 TRACE_EVENT_ASYNC_BEGIN2( | 314 TRACE_EVENT_ASYNC_BEGIN2( |
| 313 "media", GetTraceString<StreamType>(), this, "key frame", | 315 "media", GetTraceString<StreamType>(), this, "key frame", |
| 314 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", | 316 !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp (ms)", |
| 315 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); | 317 !buffer->end_of_stream() ? buffer->timestamp().InMilliseconds() : 0); |
| 316 | 318 |
| 317 if (buffer->end_of_stream()) | 319 if (buffer->end_of_stream()) |
| 318 decoding_eos_ = true; | 320 decoding_eos_ = true; |
| 319 else if (buffer->duration() != kNoTimestamp()) | 321 else if (buffer->duration() != kNoTimestamp()) |
| 320 duration_tracker_.AddSample(buffer->duration()); | 322 duration_tracker_.AddSample(buffer->duration()); |
| 321 | 323 |
| 324 if (!decoded_frames_since_fallback_ && !previous_decoder_) |
| 325 pending_buffers_.push_back(buffer); |
| 326 |
| 322 ++pending_decode_requests_; | 327 ++pending_decode_requests_; |
| 323 decoder_->Decode(buffer, | 328 decoder_->Decode(buffer, |
| 324 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, | 329 base::Bind(&DecoderStream<StreamType>::OnDecodeDone, |
| 325 weak_factory_.GetWeakPtr(), | 330 weak_factory_.GetWeakPtr(), sequence_token_, |
| 326 buffer_size, | 331 buffer_size, buffer->end_of_stream())); |
| 327 buffer->end_of_stream())); | |
| 328 } | 332 } |
| 329 | 333 |
| 330 template <DemuxerStream::Type StreamType> | 334 template <DemuxerStream::Type StreamType> |
| 331 void DecoderStream<StreamType>::FlushDecoder() { | 335 void DecoderStream<StreamType>::FlushDecoder() { |
| 332 Decode(DecoderBuffer::CreateEOSBuffer()); | 336 Decode(DecoderBuffer::CreateEOSBuffer()); |
| 333 } | 337 } |
| 334 | 338 |
| 335 template <DemuxerStream::Type StreamType> | 339 template <DemuxerStream::Type StreamType> |
| 336 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, | 340 void DecoderStream<StreamType>::OnDecodeDone(int sequence_token, |
| 341 int buffer_size, |
| 337 bool end_of_stream, | 342 bool end_of_stream, |
| 338 typename Decoder::Status status) { | 343 typename Decoder::Status status) { |
| 339 FUNCTION_DVLOG(2) << ": " << status; | 344 FUNCTION_DVLOG(2) << ": " << status; |
| 345 // Ignore stale calls from a previous decoder. |
| 346 if (sequence_token_ != sequence_token) |
| 347 return; |
| 348 |
| 340 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 349 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
| 341 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 350 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) |
| 342 << state_; | 351 << state_; |
| 343 DCHECK_GT(pending_decode_requests_, 0); | 352 DCHECK_GT(pending_decode_requests_, 0); |
| 344 | 353 |
| 345 --pending_decode_requests_; | 354 --pending_decode_requests_; |
| 346 | 355 |
| 347 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); | 356 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); |
| 348 | 357 |
| 349 if (end_of_stream) { | 358 if (end_of_stream) { |
| 350 DCHECK(!pending_decode_requests_); | 359 DCHECK(!pending_decode_requests_); |
| 351 decoding_eos_ = false; | 360 decoding_eos_ = false; |
| 352 } | 361 } |
| 353 | 362 |
| 354 if (state_ == STATE_ERROR) { | 363 if (state_ == STATE_ERROR) { |
| 355 DCHECK(read_cb_.is_null()); | 364 DCHECK(read_cb_.is_null()); |
| 356 return; | 365 return; |
| 357 } | 366 } |
| 358 | 367 |
| 359 // Drop decoding result if Reset() was called during decoding. | 368 // Drop decoding result if Reset() was called during decoding. |
| 360 // The resetting process will be handled when the decoder is reset. | 369 // The resetting process will be handled when the decoder is reset. |
| 361 if (!reset_cb_.is_null()) | 370 if (!reset_cb_.is_null()) |
| 362 return; | 371 return; |
| 363 | 372 |
| 364 switch (status) { | 373 switch (status) { |
| 365 case Decoder::kDecodeError: | 374 case Decoder::kDecodeError: |
| 375 if (!decoded_frames_since_fallback_) { |
| 376 pending_decode_requests_ = 0; |
| 377 state_ = STATE_REINITIALIZING_DECODER; |
| 378 decoder_selector_->SelectDecoder( |
| 379 stream_, nullptr, |
| 380 base::Bind(&DecoderStream<StreamType>::OnDecoderSelected, |
| 381 weak_factory_.GetWeakPtr()), |
| 382 base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady, |
| 383 weak_factory_.GetWeakPtr()), |
| 384 waiting_for_decryption_key_cb_); |
| 385 return; |
| 386 } |
| 387 |
| 366 state_ = STATE_ERROR; | 388 state_ = STATE_ERROR; |
| 367 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; | 389 MEDIA_LOG(ERROR, media_log_) << GetStreamTypeString() << " decode error"; |
| 368 ready_outputs_.clear(); | 390 ready_outputs_.clear(); |
| 369 if (!read_cb_.is_null()) | 391 if (!read_cb_.is_null()) |
| 370 SatisfyRead(DECODE_ERROR, NULL); | 392 SatisfyRead(DECODE_ERROR, NULL); |
| 371 return; | 393 return; |
| 372 | 394 |
| 373 case Decoder::kAborted: | 395 case Decoder::kAborted: |
| 374 // Decoder can return kAborted during Reset() or during destruction. | 396 // Decoder can return kAborted during Reset() or during destruction. |
| 375 return; | 397 return; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 DCHECK(ready_outputs_.empty()); | 445 DCHECK(ready_outputs_.empty()); |
| 424 SatisfyRead(OK, output); | 446 SatisfyRead(OK, output); |
| 425 return; | 447 return; |
| 426 } | 448 } |
| 427 | 449 |
| 428 // Store decoded output. | 450 // Store decoded output. |
| 429 ready_outputs_.push_back(output); | 451 ready_outputs_.push_back(output); |
| 430 | 452 |
| 431 // Destruct any previous decoder once we've decoded enough frames to ensure | 453 // Destruct any previous decoder once we've decoded enough frames to ensure |
| 432 // that it's no longer in use. | 454 // that it's no longer in use. |
| 433 if (previous_decoder_ && | 455 if (++decoded_frames_since_fallback_ > limits::kMaxVideoFrames && |
| 434 ++decoded_frames_since_fallback_ > limits::kMaxVideoFrames) { | 456 previous_decoder_) { |
| 435 previous_decoder_.reset(); | 457 previous_decoder_.reset(); |
| 436 } | 458 } |
| 437 } | 459 } |
| 438 | 460 |
| 439 template <DemuxerStream::Type StreamType> | 461 template <DemuxerStream::Type StreamType> |
| 440 void DecoderStream<StreamType>::ReadFromDemuxerStream() { | 462 void DecoderStream<StreamType>::ReadFromDemuxerStream() { |
| 441 FUNCTION_DVLOG(2); | 463 FUNCTION_DVLOG(2); |
| 442 DCHECK_EQ(state_, STATE_NORMAL); | 464 DCHECK_EQ(state_, STATE_NORMAL); |
| 443 DCHECK(CanDecodeMore()); | 465 DCHECK(CanDecodeMore()); |
| 444 DCHECK(reset_cb_.is_null()); | 466 DCHECK(reset_cb_.is_null()); |
| 445 | 467 |
| 468 if (!pending_buffers_.empty() && previous_decoder_) { |
| 469 scoped_refptr<DecoderBuffer> buffer = pending_buffers_.front(); |
| 470 pending_buffers_.pop_front(); |
| 471 Decode(buffer); |
| 472 return; |
| 473 } |
| 474 |
| 446 state_ = STATE_PENDING_DEMUXER_READ; | 475 state_ = STATE_PENDING_DEMUXER_READ; |
| 447 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, | 476 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, |
| 448 weak_factory_.GetWeakPtr())); | 477 weak_factory_.GetWeakPtr())); |
| 449 } | 478 } |
| 450 | 479 |
| 451 template <DemuxerStream::Type StreamType> | 480 template <DemuxerStream::Type StreamType> |
| 452 void DecoderStream<StreamType>::OnBufferReady( | 481 void DecoderStream<StreamType>::OnBufferReady( |
| 453 DemuxerStream::Status status, | 482 DemuxerStream::Status status, |
| 454 const scoped_refptr<DecoderBuffer>& buffer) { | 483 const scoped_refptr<DecoderBuffer>& buffer) { |
| 455 FUNCTION_DVLOG(2) << ": " << status << ", " | 484 FUNCTION_DVLOG(2) << ": " << status << ", " |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 } | 647 } |
| 619 | 648 |
| 620 // The resetting process will be continued in OnDecoderReinitialized(). | 649 // The resetting process will be continued in OnDecoderReinitialized(). |
| 621 ReinitializeDecoder(); | 650 ReinitializeDecoder(); |
| 622 } | 651 } |
| 623 | 652 |
| 624 template class DecoderStream<DemuxerStream::VIDEO>; | 653 template class DecoderStream<DemuxerStream::VIDEO>; |
| 625 template class DecoderStream<DemuxerStream::AUDIO>; | 654 template class DecoderStream<DemuxerStream::AUDIO>; |
| 626 | 655 |
| 627 } // namespace media | 656 } // namespace media |
| OLD | NEW |