| Index: media/filters/decoder_selector.cc
|
| diff --git a/media/filters/decoder_selector.cc b/media/filters/decoder_selector.cc
|
| index 3f8a25f84b3170a3e5ebe873c2ec9403dfe10710..c520eb886226c90fb3ecdcacb1d38b6e45cd64fe 100644
|
| --- a/media/filters/decoder_selector.cc
|
| +++ b/media/filters/decoder_selector.cc
|
| @@ -43,10 +43,10 @@ static bool HasValidStreamConfig(DemuxerStream* stream) {
|
| template <DemuxerStream::Type StreamType>
|
| DecoderSelector<StreamType>::DecoderSelector(
|
| const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
| - ScopedVector<Decoder> decoders,
|
| + CreateDecodersCB create_decoders_cb,
|
| MediaLog* media_log)
|
| : task_runner_(task_runner),
|
| - decoders_(std::move(decoders)),
|
| + create_decoders_cb_(std::move(create_decoders_cb)),
|
| media_log_(media_log),
|
| input_stream_(nullptr),
|
| weak_ptr_factory_(this) {}
|
| @@ -68,18 +68,17 @@ void DecoderSelector<StreamType>::SelectDecoder(
|
| StreamTraits* traits,
|
| DemuxerStream* stream,
|
| CdmContext* cdm_context,
|
| + const std::string& blacklisted_decoder,
|
| const SelectDecoderCB& select_decoder_cb,
|
| const typename Decoder::OutputCB& output_cb,
|
| const base::Closure& waiting_for_decryption_key_cb) {
|
| - DVLOG(2) << __func__;
|
| + DVLOG(2) << __func__ << ": cdm_context=" << cdm_context
|
| + << ", blacklisted_decoder=" << blacklisted_decoder;
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DCHECK(traits);
|
| DCHECK(stream);
|
| DCHECK(select_decoder_cb_.is_null());
|
|
|
| - cdm_context_ = cdm_context;
|
| - waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
|
| -
|
| // Make sure |select_decoder_cb| runs on a different execution stack.
|
| select_decoder_cb_ = BindToCurrentLoop(select_decoder_cb);
|
|
|
| @@ -91,11 +90,20 @@ void DecoderSelector<StreamType>::SelectDecoder(
|
|
|
| traits_ = traits;
|
| input_stream_ = stream;
|
| + cdm_context_ = cdm_context;
|
| + blacklisted_decoder_ = blacklisted_decoder;
|
| output_cb_ = output_cb;
|
| + waiting_for_decryption_key_cb_ = waiting_for_decryption_key_cb;
|
| +
|
| + decoders_ = create_decoders_cb_.Run();
|
| + config_ = StreamTraits::GetDecoderConfig(input_stream_);
|
|
|
| // When there is a CDM attached, always try the decrypting decoder or
|
| // demuxer-stream first.
|
| - if (cdm_context_) {
|
| + if (config_.is_encrypted()) {
|
| + DCHECK(cdm_context_);
|
| +// TODO(xhwang): This if-defined doesn't make a lot of sense. It should be
|
| +// replaced by some better checks.
|
| #if !defined(OS_ANDROID)
|
| InitializeDecryptingDecoder();
|
| #else
|
| @@ -104,11 +112,6 @@ void DecoderSelector<StreamType>::SelectDecoder(
|
| return;
|
| }
|
|
|
| - config_ = StreamTraits::GetDecoderConfig(input_stream_);
|
| -
|
| - // If the input stream is encrypted, CdmContext must be non-null.
|
| - DCHECK(!config_.is_encrypted());
|
| -
|
| InitializeDecoder();
|
| }
|
|
|
| @@ -116,9 +119,16 @@ void DecoderSelector<StreamType>::SelectDecoder(
|
| template <DemuxerStream::Type StreamType>
|
| void DecoderSelector<StreamType>::InitializeDecryptingDecoder() {
|
| DVLOG(2) << __func__;
|
| +
|
| decoder_.reset(new typename StreamTraits::DecryptingDecoderType(
|
| task_runner_, media_log_, waiting_for_decryption_key_cb_));
|
|
|
| + if (decoder_->GetDisplayName() == blacklisted_decoder_) {
|
| + DVLOG(1) << __func__ << ": Decrypting decoder is blacklisted.";
|
| + DecryptingDecoderInitDone(false);
|
| + return;
|
| + }
|
| +
|
| traits_->InitializeDecoder(
|
| decoder_.get(), StreamTraits::GetDecoderConfig(input_stream_),
|
| input_stream_->liveness() == DemuxerStream::LIVENESS_LIVE, cdm_context_,
|
| @@ -134,6 +144,7 @@ void DecoderSelector<StreamType>::DecryptingDecoderInitDone(bool success) {
|
|
|
| if (success) {
|
| DVLOG(1) << __func__ << ": " << decoder_->GetDisplayName() << " selected.";
|
| + decoders_.clear();
|
| base::ResetAndReturn(&select_decoder_cb_)
|
| .Run(std::move(decoder_), std::unique_ptr<DecryptingDemuxerStream>());
|
| return;
|
| @@ -177,11 +188,7 @@ void DecoderSelector<StreamType>::DecryptingDemuxerStreamInitDone(
|
| DCHECK(!config_.is_encrypted());
|
| } else {
|
| decrypted_stream_.reset();
|
| - config_ = StreamTraits::GetDecoderConfig(input_stream_);
|
| -
|
| - // Prefer decrypting decoder by using an encrypted config.
|
| - if (!config_.is_encrypted())
|
| - config_.SetIsEncrypted(true);
|
| + DCHECK(config_.is_encrypted());
|
| }
|
|
|
| InitializeDecoder();
|
| @@ -193,14 +200,24 @@ void DecoderSelector<StreamType>::InitializeDecoder() {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DCHECK(!decoder_);
|
|
|
| - if (decoders_.empty()) {
|
| + // Select the next non-blacklisted decoder.
|
| + while (!decoders_.empty()) {
|
| + std::unique_ptr<Decoder> decoder(decoders_.front());
|
| + decoders_.weak_erase(decoders_.begin());
|
| + // When |decrypted_stream_| is selected, the |config_| has changed so ignore
|
| + // the blacklist.
|
| + if (decrypted_stream_ ||
|
| + decoder->GetDisplayName() != blacklisted_decoder_) {
|
| + decoder_ = std::move(decoder);
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (!decoder_) {
|
| ReturnNullDecoder();
|
| return;
|
| }
|
|
|
| - decoder_.reset(decoders_.front());
|
| - decoders_.weak_erase(decoders_.begin());
|
| -
|
| traits_->InitializeDecoder(
|
| decoder_.get(), config_,
|
| input_stream_->liveness() == DemuxerStream::LIVENESS_LIVE, cdm_context_,
|
| @@ -224,6 +241,7 @@ void DecoderSelector<StreamType>::DecoderInitDone(bool success) {
|
| << " selected. DecryptingDemuxerStream "
|
| << (decrypted_stream_ ? "also" : "not") << " selected.";
|
|
|
| + decoders_.clear();
|
| base::ResetAndReturn(&select_decoder_cb_)
|
| .Run(std::move(decoder_), std::move(decrypted_stream_));
|
| }
|
| @@ -232,6 +250,7 @@ template <DemuxerStream::Type StreamType>
|
| void DecoderSelector<StreamType>::ReturnNullDecoder() {
|
| DVLOG(1) << __func__ << ": No decoder selected.";
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| + decoders_.clear();
|
| base::ResetAndReturn(&select_decoder_cb_)
|
| .Run(std::unique_ptr<Decoder>(),
|
| std::unique_ptr<DecryptingDemuxerStream>());
|
|
|