| Index: media/filters/decoder_stream.cc
|
| diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
|
| index 4f712be2f2227883e37710fd9ae5a1b6b9bd9751..cedba00f43ba8fd420c22b1d71975d9911556a49 100644
|
| --- a/media/filters/decoder_stream.cc
|
| +++ b/media/filters/decoder_stream.cc
|
| @@ -80,6 +80,8 @@ void DecoderStream<StreamType>::Initialize(DemuxerStream* stream,
|
| decoder_selector_->SelectDecoder(
|
| stream, low_delay,
|
| base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
|
| + weak_factory_.GetWeakPtr()),
|
| + base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
|
| weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| @@ -113,19 +115,7 @@ void DecoderStream<StreamType>::Read(const ReadCB& read_cb) {
|
| ready_outputs_.pop_front();
|
| }
|
|
|
| - // Decoder may be in reinitializing state as result of the previous Read().
|
| - if (state_ == STATE_REINITIALIZING_DECODER)
|
| - return;
|
| -
|
| - if (!CanDecodeMore())
|
| - return;
|
| -
|
| - if (state_ == STATE_FLUSHING_DECODER) {
|
| - FlushDecoder();
|
| - return;
|
| - }
|
| -
|
| - if (state_ != STATE_PENDING_DEMUXER_READ)
|
| + if (state_ == STATE_NORMAL && CanDecodeMore())
|
| ReadFromDemuxerStream();
|
| }
|
|
|
| @@ -216,7 +206,7 @@ void DecoderStream<StreamType>::Stop(const base::Closure& closure) {
|
| template <DemuxerStream::Type StreamType>
|
| bool DecoderStream<StreamType>::CanReadWithoutStalling() const {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| - return decoder_->CanReadWithoutStalling();
|
| + return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling();
|
| }
|
|
|
| template <>
|
| @@ -226,6 +216,16 @@ bool DecoderStream<DemuxerStream::AUDIO>::CanReadWithoutStalling() const {
|
| }
|
|
|
| template <DemuxerStream::Type StreamType>
|
| +int DecoderStream<StreamType>::GetMaxDecodeRequests() const {
|
| + return decoder_->GetMaxDecodeRequests();
|
| +}
|
| +
|
| +template <>
|
| +int DecoderStream<DemuxerStream::AUDIO>::GetMaxDecodeRequests() const {
|
| + return 1;
|
| +}
|
| +
|
| +template <DemuxerStream::Type StreamType>
|
| bool DecoderStream<StreamType>::CanDecodeMore() const {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
|
|
| @@ -234,13 +234,7 @@ bool DecoderStream<StreamType>::CanDecodeMore() const {
|
| // empty.
|
| int num_decodes =
|
| static_cast<int>(ready_outputs_.size()) + pending_decode_requests_;
|
| - return num_decodes < decoder_->GetMaxDecodeRequests();
|
| -}
|
| -
|
| -template <>
|
| -bool DecoderStream<DemuxerStream::AUDIO>::CanDecodeMore() const {
|
| - DCHECK(task_runner_->BelongsToCurrentThread());
|
| - return !pending_decode_requests_ && ready_outputs_.empty();
|
| + return num_decodes < GetMaxDecodeRequests();
|
| }
|
|
|
| template <DemuxerStream::Type StreamType>
|
| @@ -290,7 +284,7 @@ void DecoderStream<StreamType>::Decode(
|
| const scoped_refptr<DecoderBuffer>& buffer) {
|
| FUNCTION_DVLOG(2);
|
| DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
|
| - DCHECK(CanDecodeMore());
|
| + DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests());
|
| DCHECK(reset_cb_.is_null());
|
| DCHECK(stop_cb_.is_null());
|
| DCHECK(buffer);
|
| @@ -300,28 +294,26 @@ void DecoderStream<StreamType>::Decode(
|
| TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this);
|
| ++pending_decode_requests_;
|
| decoder_->Decode(buffer,
|
| - base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
|
| + base::Bind(&DecoderStream<StreamType>::OnDecodeDone,
|
| weak_factory_.GetWeakPtr(),
|
| - buffer_size));
|
| + buffer_size,
|
| + buffer->end_of_stream()));
|
| }
|
|
|
| template <DemuxerStream::Type StreamType>
|
| void DecoderStream<StreamType>::FlushDecoder() {
|
| - if (pending_decode_requests_ == 0)
|
| - Decode(DecoderBuffer::CreateEOSBuffer());
|
| + Decode(DecoderBuffer::CreateEOSBuffer());
|
| }
|
|
|
| template <DemuxerStream::Type StreamType>
|
| -void DecoderStream<StreamType>::OnDecodeOutputReady(
|
| - int buffer_size,
|
| - typename Decoder::Status status,
|
| - const scoped_refptr<Output>& output) {
|
| - FUNCTION_DVLOG(2) << status << " " << output;
|
| +void DecoderStream<StreamType>::OnDecodeDone(int buffer_size,
|
| + bool end_of_stream,
|
| + typename Decoder::Status status) {
|
| + FUNCTION_DVLOG(2) << status;
|
| DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
|
| state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
|
| << state_;
|
| DCHECK(stop_cb_.is_null());
|
| - DCHECK_EQ(status == Decoder::kOk, output != NULL);
|
| DCHECK_GT(pending_decode_requests_, 0);
|
|
|
| --pending_decode_requests_;
|
| @@ -333,31 +325,54 @@ void DecoderStream<StreamType>::OnDecodeOutputReady(
|
| return;
|
| }
|
|
|
| - if (status == Decoder::kDecodeError) {
|
| - state_ = STATE_ERROR;
|
| - ready_outputs_.clear();
|
| - if (!read_cb_.is_null())
|
| - SatisfyRead(DECODE_ERROR, NULL);
|
| + // Drop decoding result if Reset() was called during decoding.
|
| + // The resetting process will be handled when the decoder is reset.
|
| + if (!reset_cb_.is_null())
|
| return;
|
| - }
|
|
|
| - if (status == Decoder::kDecryptError) {
|
| - state_ = STATE_ERROR;
|
| - ready_outputs_.clear();
|
| - if (!read_cb_.is_null())
|
| - SatisfyRead(DECRYPT_ERROR, NULL);
|
| - return;
|
| + switch (status) {
|
| + case Decoder::kDecodeError:
|
| + case Decoder::kDecryptError:
|
| + state_ = STATE_ERROR;
|
| + ready_outputs_.clear();
|
| + if (!read_cb_.is_null())
|
| + SatisfyRead(DECODE_ERROR, NULL);
|
| + break;
|
| +
|
| + case Decoder::kAborted:
|
| + // Decoder can return kAborted only when Reset is pending.
|
| + NOTREACHED();
|
| + break;
|
| +
|
| + case Decoder::kOk:
|
| + // Any successful decode counts!
|
| + if (buffer_size > 0) {
|
| + StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
|
| + }
|
| +
|
| + if (state_ == STATE_NORMAL) {
|
| + if (CanDecodeMore() && !end_of_stream)
|
| + ReadFromDemuxerStream();
|
| + } else if (state_ == STATE_FLUSHING_DECODER) {
|
| + if (!pending_decode_requests_)
|
| + ReinitializeDecoder();
|
| + }
|
| + break;
|
| }
|
| +}
|
|
|
| - if (status == Decoder::kAborted) {
|
| - if (!read_cb_.is_null())
|
| - SatisfyRead(ABORTED, NULL);
|
| - return;
|
| - }
|
| +template <DemuxerStream::Type StreamType>
|
| +void DecoderStream<StreamType>::OnDecodeOutputReady(
|
| + const scoped_refptr<Output>& output) {
|
| + FUNCTION_DVLOG(2) << output;
|
| + DCHECK(output);
|
| + DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER ||
|
| + state_ == STATE_PENDING_DEMUXER_READ || state_ == STATE_ERROR)
|
| + << state_;
|
|
|
| - // Any successful decode counts!
|
| - if (buffer_size > 0) {
|
| - StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
|
| + if (state_ == STATE_ERROR) {
|
| + DCHECK(read_cb_.is_null());
|
| + return;
|
| }
|
|
|
| // Drop decoding result if Reset() was called during decoding.
|
| @@ -365,29 +380,13 @@ void DecoderStream<StreamType>::OnDecodeOutputReady(
|
| if (!reset_cb_.is_null())
|
| return;
|
|
|
| - // Decoder flushed. Reinitialize the decoder.
|
| - if (state_ == STATE_FLUSHING_DECODER &&
|
| - status == Decoder::kOk && output->end_of_stream()) {
|
| - ReinitializeDecoder();
|
| - return;
|
| - }
|
| -
|
| - if (status == Decoder::kNotEnoughData) {
|
| - if (state_ == STATE_NORMAL)
|
| - ReadFromDemuxerStream();
|
| - else if (state_ == STATE_FLUSHING_DECODER)
|
| - FlushDecoder();
|
| + if (state_ == STATE_FLUSHING_DECODER && output->end_of_stream()) {
|
| + // ReinitializeDecoder() will be called from OnDecodeDone().
|
| return;
|
| }
|
|
|
| - DCHECK(output);
|
| -
|
| // Store decoded output.
|
| ready_outputs_.push_back(output);
|
| - scoped_refptr<Output> extra_output;
|
| - while ((extra_output = decoder_->GetDecodeOutput()) != NULL) {
|
| - ready_outputs_.push_back(extra_output);
|
| - }
|
|
|
| // Satisfy outstanding read request, if any.
|
| if (!read_cb_.is_null()) {
|
| @@ -460,7 +459,8 @@ void DecoderStream<StreamType>::OnBufferReady(
|
| }
|
|
|
| if (status == DemuxerStream::kAborted) {
|
| - SatisfyRead(DEMUXER_READ_ABORTED, NULL);
|
| + if (!read_cb_.is_null())
|
| + SatisfyRead(DEMUXER_READ_ABORTED, NULL);
|
| return;
|
| }
|
|
|
| @@ -494,6 +494,8 @@ void DecoderStream<StreamType>::ReinitializeDecoder() {
|
| StreamTraits::GetDecoderConfig(*stream_),
|
| low_delay_,
|
| base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized,
|
| + weak_factory_.GetWeakPtr()),
|
| + base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
|
| weak_factory_.GetWeakPtr()));
|
| }
|
|
|
|
|