| Index: media/filters/decoder_stream.cc
|
| ===================================================================
|
| --- media/filters/decoder_stream.cc (revision 277175)
|
| +++ media/filters/decoder_stream.cc (working copy)
|
| @@ -80,8 +80,6 @@
|
| decoder_selector_->SelectDecoder(
|
| stream, low_delay,
|
| base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
|
| - weak_factory_.GetWeakPtr()),
|
| - base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
|
| weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| @@ -115,7 +113,19 @@
|
| ready_outputs_.pop_front();
|
| }
|
|
|
| - if (state_ == STATE_NORMAL && CanDecodeMore())
|
| + // 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)
|
| ReadFromDemuxerStream();
|
| }
|
|
|
| @@ -206,7 +216,7 @@
|
| template <DemuxerStream::Type StreamType>
|
| bool DecoderStream<StreamType>::CanReadWithoutStalling() const {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| - return !ready_outputs_.empty() || decoder_->CanReadWithoutStalling();
|
| + return decoder_->CanReadWithoutStalling();
|
| }
|
|
|
| template <>
|
| @@ -216,16 +226,6 @@
|
| }
|
|
|
| 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,9 +234,15 @@
|
| // empty.
|
| int num_decodes =
|
| static_cast<int>(ready_outputs_.size()) + pending_decode_requests_;
|
| - return num_decodes < GetMaxDecodeRequests();
|
| + return num_decodes < decoder_->GetMaxDecodeRequests();
|
| }
|
|
|
| +template <>
|
| +bool DecoderStream<DemuxerStream::AUDIO>::CanDecodeMore() const {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + return !pending_decode_requests_ && ready_outputs_.empty();
|
| +}
|
| +
|
| template <DemuxerStream::Type StreamType>
|
| void DecoderStream<StreamType>::OnDecoderSelected(
|
| scoped_ptr<Decoder> selected_decoder,
|
| @@ -284,7 +290,7 @@
|
| const scoped_refptr<DecoderBuffer>& buffer) {
|
| FUNCTION_DVLOG(2);
|
| DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER) << state_;
|
| - DCHECK_LT(pending_decode_requests_, GetMaxDecodeRequests());
|
| + DCHECK(CanDecodeMore());
|
| DCHECK(reset_cb_.is_null());
|
| DCHECK(stop_cb_.is_null());
|
| DCHECK(buffer);
|
| @@ -294,26 +300,28 @@
|
| TRACE_EVENT_ASYNC_BEGIN0("media", GetTraceString<StreamType>(), this);
|
| ++pending_decode_requests_;
|
| decoder_->Decode(buffer,
|
| - base::Bind(&DecoderStream<StreamType>::OnDecodeDone,
|
| + base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
|
| weak_factory_.GetWeakPtr(),
|
| - buffer_size,
|
| - buffer->end_of_stream()));
|
| + buffer_size));
|
| }
|
|
|
| template <DemuxerStream::Type StreamType>
|
| void DecoderStream<StreamType>::FlushDecoder() {
|
| - Decode(DecoderBuffer::CreateEOSBuffer());
|
| + if (pending_decode_requests_ == 0)
|
| + Decode(DecoderBuffer::CreateEOSBuffer());
|
| }
|
|
|
| template <DemuxerStream::Type StreamType>
|
| -void DecoderStream<StreamType>::OnDecodeDone(int buffer_size,
|
| - bool end_of_stream,
|
| - typename Decoder::Status status) {
|
| - FUNCTION_DVLOG(2) << status;
|
| +void DecoderStream<StreamType>::OnDecodeOutputReady(
|
| + int buffer_size,
|
| + typename Decoder::Status status,
|
| + const scoped_refptr<Output>& output) {
|
| + FUNCTION_DVLOG(2) << status << " " << output;
|
| 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_;
|
| @@ -325,68 +333,61 @@
|
| return;
|
| }
|
|
|
| - // 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())
|
| + if (status == Decoder::kDecodeError) {
|
| + state_ = STATE_ERROR;
|
| + ready_outputs_.clear();
|
| + if (!read_cb_.is_null())
|
| + SatisfyRead(DECODE_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::kDecryptError) {
|
| + state_ = STATE_ERROR;
|
| + ready_outputs_.clear();
|
| + if (!read_cb_.is_null())
|
| + SatisfyRead(DECRYPT_ERROR, 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_;
|
| -
|
| - if (state_ == STATE_ERROR) {
|
| - DCHECK(read_cb_.is_null());
|
| + if (status == Decoder::kAborted) {
|
| + if (!read_cb_.is_null())
|
| + SatisfyRead(ABORTED, NULL);
|
| return;
|
| }
|
|
|
| + // Any successful decode counts!
|
| + if (buffer_size > 0) {
|
| + StreamTraits::ReportStatistics(statistics_cb_, buffer_size);
|
| + }
|
| +
|
| // 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 (state_ == STATE_FLUSHING_DECODER && output->end_of_stream()) {
|
| - // ReinitializeDecoder() will be called from OnDecodeDone().
|
| + // 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();
|
| + 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()) {
|
| @@ -459,8 +460,7 @@
|
| }
|
|
|
| if (status == DemuxerStream::kAborted) {
|
| - if (!read_cb_.is_null())
|
| - SatisfyRead(DEMUXER_READ_ABORTED, NULL);
|
| + SatisfyRead(DEMUXER_READ_ABORTED, NULL);
|
| return;
|
| }
|
|
|
| @@ -494,8 +494,6 @@
|
| StreamTraits::GetDecoderConfig(*stream_),
|
| low_delay_,
|
| base::Bind(&DecoderStream<StreamType>::OnDecoderReinitialized,
|
| - weak_factory_.GetWeakPtr()),
|
| - base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
|
| weak_factory_.GetWeakPtr()));
|
| }
|
|
|
|
|