| Index: media/filters/decoder_stream.cc
|
| diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc
|
| index 53cf47c18a725f3eb11ef310c195cf50dbc016aa..af3c7d1e77aaf9e142ac46310aac40a7a6dd8d9d 100644
|
| --- a/media/filters/decoder_stream.cc
|
| +++ b/media/filters/decoder_stream.cc
|
| @@ -45,7 +45,7 @@ const char* GetTraceString<DemuxerStream::AUDIO>() {
|
| template <DemuxerStream::Type StreamType>
|
| DecoderStream<StreamType>::DecoderStream(
|
| const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
| - ScopedVector<Decoder> decoders,
|
| + CreateDecodersCB create_decoders_cb,
|
| MediaLog* media_log)
|
| : traits_(media_log),
|
| task_runner_(task_runner),
|
| @@ -53,10 +53,12 @@ DecoderStream<StreamType>::DecoderStream(
|
| state_(STATE_UNINITIALIZED),
|
| stream_(NULL),
|
| cdm_context_(nullptr),
|
| - decoder_selector_(new DecoderSelector<StreamType>(task_runner,
|
| - std::move(decoders),
|
| - media_log)),
|
| + decoder_selector_(
|
| + new DecoderSelector<StreamType>(task_runner,
|
| + std::move(create_decoders_cb),
|
| + media_log)),
|
| decoder_produced_a_frame_(false),
|
| + has_fallen_back_once_on_decode_error_(false),
|
| decoding_eos_(false),
|
| pending_decode_requests_(0),
|
| duration_tracker_(8),
|
| @@ -256,9 +258,10 @@ void DecoderStream<StreamType>::SelectDecoder() {
|
| // the |cdm_context_|. This will also help prevent creating a new DDS on top
|
| // of the current DDS.
|
| CdmContext* cdm_context = decrypting_demuxer_stream_ ? nullptr : cdm_context_;
|
| + std::string blacklisted_decoder = decoder_ ? decoder_->GetDisplayName() : "";
|
|
|
| decoder_selector_->SelectDecoder(
|
| - &traits_, stream_, cdm_context,
|
| + &traits_, stream_, cdm_context, blacklisted_decoder,
|
| base::Bind(&DecoderStream<StreamType>::OnDecoderSelected,
|
| weak_factory_.GetWeakPtr()),
|
| base::Bind(&DecoderStream<StreamType>::OnDecodeOutputReady,
|
| @@ -431,7 +434,11 @@ void DecoderStream<StreamType>::OnDecodeDone(int buffer_size,
|
|
|
| switch (status) {
|
| case DecodeStatus::DECODE_ERROR:
|
| - if (!decoder_produced_a_frame_) {
|
| + // Only fall back to a new decoder after failing to decode the first
|
| + // buffer, and if we have not fallen back before.
|
| + if (!decoder_produced_a_frame_ &&
|
| + !has_fallen_back_once_on_decode_error_) {
|
| + has_fallen_back_once_on_decode_error_ = true;
|
| pending_decode_requests_ = 0;
|
|
|
| // Prevent all pending decode requests and outputs from those requests
|
| @@ -503,7 +510,7 @@ void DecoderStream<StreamType>::OnDecodeOutputReady(
|
| decoder_produced_a_frame_ = true;
|
| traits_.OnDecodeDone(output);
|
|
|
| - // |decoder_| sucessfully decoded a frame. No need to keep buffers for a
|
| + // |decoder_| successfully decoded a frame. No need to keep buffers for a
|
| // fallback decoder.
|
| // Note: |fallback_buffers_| might still have buffers, and we will keep
|
| // reading from there before requesting new buffers from |stream_|.
|
|
|