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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 // |pending_buffers_|. | 390 // |pending_buffers_|. |
391 DecodeInternal(DecoderBuffer::CreateEOSBuffer()); | 391 DecodeInternal(DecoderBuffer::CreateEOSBuffer()); |
392 } | 392 } |
393 | 393 |
394 template <DemuxerStream::Type StreamType> | 394 template <DemuxerStream::Type StreamType> |
395 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, | 395 void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, |
396 bool end_of_stream, | 396 bool end_of_stream, |
397 DecodeStatus status) { | 397 DecodeStatus status) { |
398 FUNCTION_DVLOG(2) << ": " << status; | 398 FUNCTION_DVLOG(2) << ": " << status; |
399 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 399 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
400 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 400 state_ == STATE_ERROR) |
401 << state_; | 401 << state_; |
402 DCHECK_GT(pending_decode_requests_, 0); | 402 DCHECK_GT(pending_decode_requests_, 0); |
403 | 403 |
404 --pending_decode_requests_; | 404 --pending_decode_requests_; |
405 | 405 |
406 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); | 406 TRACE_EVENT_ASYNC_END0("media", GetTraceString<StreamType>(), this); |
407 | 407 |
408 if (end_of_stream) { | 408 if (end_of_stream) { |
409 DCHECK(!pending_decode_requests_); | 409 DCHECK(!pending_decode_requests_); |
410 decoding_eos_ = false; | 410 decoding_eos_ = false; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 return; | 474 return; |
475 } | 475 } |
476 } | 476 } |
477 | 477 |
478 template <DemuxerStream::Type StreamType> | 478 template <DemuxerStream::Type StreamType> |
479 void DecoderStream<StreamType>::OnDecodeOutputReady( | 479 void DecoderStream<StreamType>::OnDecodeOutputReady( |
480 const scoped_refptr<Output>& output) { | 480 const scoped_refptr<Output>& output) { |
481 FUNCTION_DVLOG(2) << ": " << output->timestamp().InMilliseconds() << " ms"; | 481 FUNCTION_DVLOG(2) << ": " << output->timestamp().InMilliseconds() << " ms"; |
482 DCHECK(output.get()); | 482 DCHECK(output.get()); |
483 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || | 483 DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || |
484 state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 484 state_ == STATE_ERROR) |
485 << state_; | 485 << state_; |
486 | 486 |
487 if (state_ == STATE_ERROR) { | 487 if (state_ == STATE_ERROR) { |
488 DCHECK(read_cb_.is_null()); | 488 DCHECK(read_cb_.is_null()); |
489 return; | 489 return; |
490 } | 490 } |
491 | 491 |
492 // Drop decoding result if Reset() was called during decoding. | 492 // Drop decoding result if Reset() was called during decoding. |
493 // The resetting process will be handled when the decoder is reset. | 493 // The resetting process will be handled when the decoder is reset. |
494 if (!reset_cb_.is_null()) | 494 if (!reset_cb_.is_null()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 | 532 |
533 if (!fallback_buffers_.empty()) { | 533 if (!fallback_buffers_.empty()) { |
534 scoped_refptr<DecoderBuffer> buffer = fallback_buffers_.front(); | 534 scoped_refptr<DecoderBuffer> buffer = fallback_buffers_.front(); |
535 fallback_buffers_.pop_front(); | 535 fallback_buffers_.pop_front(); |
536 | 536 |
537 // Decode the buffer without re-appending it to |pending_buffers_|. | 537 // Decode the buffer without re-appending it to |pending_buffers_|. |
538 DecodeInternal(buffer); | 538 DecodeInternal(buffer); |
539 return; | 539 return; |
540 } | 540 } |
541 | 541 |
542 // Set a flag in addition to the state, because the state can be overwritten | 542 // We may get here when a read is already pending, ignore this. |
543 // when encountering an error. See crbug.com/597605. | 543 if (pending_demuxer_read_) |
544 DCHECK(!pending_demuxer_read_); | 544 return; |
| 545 |
545 pending_demuxer_read_ = true; | 546 pending_demuxer_read_ = true; |
546 | |
547 state_ = STATE_PENDING_DEMUXER_READ; | |
548 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, | 547 stream_->Read(base::Bind(&DecoderStream<StreamType>::OnBufferReady, |
549 weak_factory_.GetWeakPtr())); | 548 weak_factory_.GetWeakPtr())); |
550 } | 549 } |
551 | 550 |
552 template <DemuxerStream::Type StreamType> | 551 template <DemuxerStream::Type StreamType> |
553 void DecoderStream<StreamType>::OnBufferReady( | 552 void DecoderStream<StreamType>::OnBufferReady( |
554 DemuxerStream::Status status, | 553 DemuxerStream::Status status, |
555 const scoped_refptr<DecoderBuffer>& buffer) { | 554 const scoped_refptr<DecoderBuffer>& buffer) { |
556 FUNCTION_DVLOG(2) << ": " << status << ", " | 555 FUNCTION_DVLOG(2) << ": " << status << ", " |
557 << (buffer.get() ? buffer->AsHumanReadableString() | 556 << (buffer.get() ? buffer->AsHumanReadableString() |
558 : "NULL"); | 557 : "NULL"); |
559 | 558 |
560 DCHECK(task_runner_->BelongsToCurrentThread()); | 559 DCHECK(task_runner_->BelongsToCurrentThread()); |
561 DCHECK(pending_demuxer_read_); | 560 DCHECK(pending_demuxer_read_); |
562 if (decoded_frames_since_fallback_) { | 561 if (decoded_frames_since_fallback_) { |
563 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR) | 562 DCHECK(pending_demuxer_read_ || state_ == STATE_ERROR) << state_; |
564 << state_; | |
565 } else { | 563 } else { |
566 DCHECK(state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR || | 564 DCHECK(state_ == STATE_ERROR || state_ == STATE_REINITIALIZING_DECODER || |
567 state_ == STATE_REINITIALIZING_DECODER || state_ == STATE_NORMAL) | 565 state_ == STATE_NORMAL) |
568 << state_; | 566 << state_; |
569 } | 567 } |
570 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; | 568 DCHECK_EQ(buffer.get() != NULL, status == DemuxerStream::kOk) << status; |
571 | |
572 // Unset the flag. STATE_PENDING_DEMUXER_READ might have been overwritten. | |
573 // See crbug.com/597605. | |
574 pending_demuxer_read_ = false; | 569 pending_demuxer_read_ = false; |
575 | 570 |
576 // If parallel decode requests are supported, multiple read requests might | 571 // If parallel decode requests are supported, multiple read requests might |
577 // have been sent to the demuxer. The buffers might arrive while the decoder | 572 // have been sent to the demuxer. The buffers might arrive while the decoder |
578 // is reinitializing after falling back on first decode error. | 573 // is reinitializing after falling back on first decode error. |
579 if (state_ == STATE_REINITIALIZING_DECODER && | 574 if (state_ == STATE_REINITIALIZING_DECODER && |
580 !decoded_frames_since_fallback_) { | 575 !decoded_frames_since_fallback_) { |
581 switch (status) { | 576 switch (status) { |
582 case DemuxerStream::kOk: | 577 case DemuxerStream::kOk: |
583 // Save valid buffers to be consumed by the new decoder. | 578 // Save valid buffers to be consumed by the new decoder. |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 } | 784 } |
790 | 785 |
791 // The resetting process will be continued in OnDecoderReinitialized(). | 786 // The resetting process will be continued in OnDecoderReinitialized(). |
792 ReinitializeDecoder(); | 787 ReinitializeDecoder(); |
793 } | 788 } |
794 | 789 |
795 template class DecoderStream<DemuxerStream::VIDEO>; | 790 template class DecoderStream<DemuxerStream::VIDEO>; |
796 template class DecoderStream<DemuxerStream::AUDIO>; | 791 template class DecoderStream<DemuxerStream::AUDIO>; |
797 | 792 |
798 } // namespace media | 793 } // namespace media |
OLD | NEW |