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 |