| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/filters/decoder_selector.h" | 5 #include "media/filters/decoder_selector.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 return stream->audio_decoder_config().IsValidConfig(); | 33 return stream->audio_decoder_config().IsValidConfig(); |
| 34 case DemuxerStream::VIDEO: | 34 case DemuxerStream::VIDEO: |
| 35 return stream->video_decoder_config().IsValidConfig(); | 35 return stream->video_decoder_config().IsValidConfig(); |
| 36 case DemuxerStream::TEXT: | 36 case DemuxerStream::TEXT: |
| 37 case DemuxerStream::UNKNOWN: | 37 case DemuxerStream::UNKNOWN: |
| 38 NOTREACHED(); | 38 NOTREACHED(); |
| 39 } | 39 } |
| 40 return false; | 40 return false; |
| 41 } | 41 } |
| 42 | 42 |
| 43 static bool IsStreamEncrypted(DemuxerStream* stream) { | |
| 44 switch (stream->type()) { | |
| 45 case DemuxerStream::AUDIO: | |
| 46 return stream->audio_decoder_config().is_encrypted(); | |
| 47 case DemuxerStream::VIDEO: | |
| 48 return stream->video_decoder_config().is_encrypted(); | |
| 49 case DemuxerStream::TEXT: | |
| 50 case DemuxerStream::UNKNOWN: | |
| 51 NOTREACHED(); | |
| 52 } | |
| 53 return false; | |
| 54 } | |
| 55 | |
| 56 template <DemuxerStream::Type StreamType> | 43 template <DemuxerStream::Type StreamType> |
| 57 DecoderSelector<StreamType>::DecoderSelector( | 44 DecoderSelector<StreamType>::DecoderSelector( |
| 58 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 45 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 59 ScopedVector<Decoder> decoders, | 46 ScopedVector<Decoder> decoders, |
| 60 const scoped_refptr<MediaLog>& media_log) | 47 const scoped_refptr<MediaLog>& media_log) |
| 61 : task_runner_(task_runner), | 48 : task_runner_(task_runner), |
| 62 decoders_(std::move(decoders)), | 49 decoders_(std::move(decoders)), |
| 63 media_log_(media_log), | 50 media_log_(media_log), |
| 64 input_stream_(nullptr), | 51 input_stream_(nullptr), |
| 65 weak_ptr_factory_(this) {} | 52 weak_ptr_factory_(this) {} |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 if (!HasValidStreamConfig(stream)) { | 86 if (!HasValidStreamConfig(stream)) { |
| 100 DLOG(ERROR) << "Invalid stream config."; | 87 DLOG(ERROR) << "Invalid stream config."; |
| 101 ReturnNullDecoder(); | 88 ReturnNullDecoder(); |
| 102 return; | 89 return; |
| 103 } | 90 } |
| 104 | 91 |
| 105 traits_ = traits; | 92 traits_ = traits; |
| 106 input_stream_ = stream; | 93 input_stream_ = stream; |
| 107 output_cb_ = output_cb; | 94 output_cb_ = output_cb; |
| 108 | 95 |
| 109 if (!IsStreamEncrypted(input_stream_)) { | 96 // When there is a CDM attached, always try the decrypting decoder or |
| 110 InitializeDecoder(); | 97 // demuxer-stream first. |
| 98 if (cdm_context_) { |
| 99 #if !defined(OS_ANDROID) |
| 100 InitializeDecryptingDecoder(); |
| 101 #else |
| 102 InitializeDecryptingDemuxerStream(); |
| 103 #endif |
| 111 return; | 104 return; |
| 112 } | 105 } |
| 113 | 106 |
| 114 // This could be null during fallback after decoder reinitialization failure. | 107 config_ = StreamTraits::GetDecoderConfig(input_stream_); |
| 115 // See DecoderStream<StreamType>::OnDecoderReinitialized(). | |
| 116 if (!cdm_context_) { | |
| 117 ReturnNullDecoder(); | |
| 118 return; | |
| 119 } | |
| 120 | 108 |
| 121 #if !defined(OS_ANDROID) | 109 // If the input stream is encrypted, CdmContext must be non-null. |
| 122 InitializeDecryptingDecoder(); | 110 DCHECK(!config_.is_encrypted()); |
| 123 #else | 111 |
| 124 InitializeDecryptingDemuxerStream(); | 112 InitializeDecoder(); |
| 125 #endif | |
| 126 } | 113 } |
| 127 | 114 |
| 128 #if !defined(OS_ANDROID) | 115 #if !defined(OS_ANDROID) |
| 129 template <DemuxerStream::Type StreamType> | 116 template <DemuxerStream::Type StreamType> |
| 130 void DecoderSelector<StreamType>::InitializeDecryptingDecoder() { | 117 void DecoderSelector<StreamType>::InitializeDecryptingDecoder() { |
| 131 DVLOG(2) << __func__; | 118 DVLOG(2) << __func__; |
| 132 decoder_.reset(new typename StreamTraits::DecryptingDecoderType( | 119 decoder_.reset(new typename StreamTraits::DecryptingDecoderType( |
| 133 task_runner_, media_log_, waiting_for_decryption_key_cb_)); | 120 task_runner_, media_log_, waiting_for_decryption_key_cb_)); |
| 134 | 121 |
| 135 traits_->InitializeDecoder( | 122 traits_->InitializeDecoder( |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 base::Bind(&DecoderSelector<StreamType>::DecryptingDemuxerStreamInitDone, | 157 base::Bind(&DecoderSelector<StreamType>::DecryptingDemuxerStreamInitDone, |
| 171 weak_ptr_factory_.GetWeakPtr())); | 158 weak_ptr_factory_.GetWeakPtr())); |
| 172 } | 159 } |
| 173 | 160 |
| 174 template <DemuxerStream::Type StreamType> | 161 template <DemuxerStream::Type StreamType> |
| 175 void DecoderSelector<StreamType>::DecryptingDemuxerStreamInitDone( | 162 void DecoderSelector<StreamType>::DecryptingDemuxerStreamInitDone( |
| 176 PipelineStatus status) { | 163 PipelineStatus status) { |
| 177 DVLOG(2) << __func__ | 164 DVLOG(2) << __func__ |
| 178 << ": status=" << MediaLog::PipelineStatusToString(status); | 165 << ": status=" << MediaLog::PipelineStatusToString(status); |
| 179 DCHECK(task_runner_->BelongsToCurrentThread()); | 166 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 167 DCHECK(cdm_context_); |
| 180 | 168 |
| 181 // If DecryptingDemuxerStream initialization succeeded, we'll use it to do | 169 // If DecryptingDemuxerStream initialization succeeded, we'll use it to do |
| 182 // decryption and use a decoder to decode the clear stream. Otherwise, we'll | 170 // decryption and use a decoder to decode the clear stream. Otherwise, we'll |
| 183 // try to see whether any decoder can decrypt-and-decode the encrypted stream | 171 // try to see whether any decoder can decrypt-and-decode the encrypted stream |
| 184 // directly. So in both cases, we'll initialize the decoders. | 172 // directly. So in both cases, we'll initialize the decoders. |
| 185 | 173 |
| 186 if (status == PIPELINE_OK) { | 174 if (status == PIPELINE_OK) { |
| 187 input_stream_ = decrypted_stream_.get(); | 175 input_stream_ = decrypted_stream_.get(); |
| 188 DCHECK(!IsStreamEncrypted(input_stream_)); | 176 config_ = StreamTraits::GetDecoderConfig(input_stream_); |
| 177 DCHECK(!config_.is_encrypted()); |
| 189 } else { | 178 } else { |
| 190 decrypted_stream_.reset(); | 179 decrypted_stream_.reset(); |
| 191 DCHECK(IsStreamEncrypted(input_stream_)); | 180 config_ = StreamTraits::GetDecoderConfig(input_stream_); |
| 181 |
| 182 // Prefer decrypting decoder by using an encrypted config. |
| 183 if (!config_.is_encrypted()) |
| 184 config_.SetIsEncrypted(true); |
| 192 } | 185 } |
| 193 | 186 |
| 194 InitializeDecoder(); | 187 InitializeDecoder(); |
| 195 } | 188 } |
| 196 | 189 |
| 197 template <DemuxerStream::Type StreamType> | 190 template <DemuxerStream::Type StreamType> |
| 198 void DecoderSelector<StreamType>::InitializeDecoder() { | 191 void DecoderSelector<StreamType>::InitializeDecoder() { |
| 199 DVLOG(2) << __func__; | 192 DVLOG(2) << __func__; |
| 200 DCHECK(task_runner_->BelongsToCurrentThread()); | 193 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 201 DCHECK(!decoder_); | 194 DCHECK(!decoder_); |
| 202 | 195 |
| 203 if (decoders_.empty()) { | 196 if (decoders_.empty()) { |
| 204 ReturnNullDecoder(); | 197 ReturnNullDecoder(); |
| 205 return; | 198 return; |
| 206 } | 199 } |
| 207 | 200 |
| 208 decoder_.reset(decoders_.front()); | 201 decoder_.reset(decoders_.front()); |
| 209 decoders_.weak_erase(decoders_.begin()); | 202 decoders_.weak_erase(decoders_.begin()); |
| 210 | 203 |
| 211 traits_->InitializeDecoder( | 204 traits_->InitializeDecoder( |
| 212 decoder_.get(), StreamTraits::GetDecoderConfig(input_stream_), | 205 decoder_.get(), config_, |
| 213 input_stream_->liveness() == DemuxerStream::LIVENESS_LIVE, cdm_context_, | 206 input_stream_->liveness() == DemuxerStream::LIVENESS_LIVE, cdm_context_, |
| 214 base::Bind(&DecoderSelector<StreamType>::DecoderInitDone, | 207 base::Bind(&DecoderSelector<StreamType>::DecoderInitDone, |
| 215 weak_ptr_factory_.GetWeakPtr()), | 208 weak_ptr_factory_.GetWeakPtr()), |
| 216 output_cb_); | 209 output_cb_); |
| 217 } | 210 } |
| 218 | 211 |
| 219 template <DemuxerStream::Type StreamType> | 212 template <DemuxerStream::Type StreamType> |
| 220 void DecoderSelector<StreamType>::DecoderInitDone(bool success) { | 213 void DecoderSelector<StreamType>::DecoderInitDone(bool success) { |
| 221 DVLOG(2) << __func__ << ": success=" << success; | 214 DVLOG(2) << __func__ << ": success=" << success; |
| 222 DCHECK(task_runner_->BelongsToCurrentThread()); | 215 DCHECK(task_runner_->BelongsToCurrentThread()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 246 | 239 |
| 247 // These forward declarations tell the compiler that we will use | 240 // These forward declarations tell the compiler that we will use |
| 248 // DecoderSelector with these arguments, allowing us to keep these definitions | 241 // DecoderSelector with these arguments, allowing us to keep these definitions |
| 249 // in our .cc without causing linker errors. This also means if anyone tries to | 242 // in our .cc without causing linker errors. This also means if anyone tries to |
| 250 // instantiate a DecoderSelector with anything but these two specializations | 243 // instantiate a DecoderSelector with anything but these two specializations |
| 251 // they'll most likely get linker errors. | 244 // they'll most likely get linker errors. |
| 252 template class DecoderSelector<DemuxerStream::AUDIO>; | 245 template class DecoderSelector<DemuxerStream::AUDIO>; |
| 253 template class DecoderSelector<DemuxerStream::VIDEO>; | 246 template class DecoderSelector<DemuxerStream::VIDEO>; |
| 254 | 247 |
| 255 } // namespace media | 248 } // namespace media |
| OLD | NEW |