Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(886)

Unified Diff: media/filters/decoder_selector.cc

Issue 2837613004: media: Support better decoder switching (Closed)
Patch Set: Mock*Decoder name Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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>());

Powered by Google App Engine
This is Rietveld 408576698