InputImeEventRouter::RegisterImeExtension should register extensions
[chromium-blink-merge.git] / media / filters / decoder_selector.cc
blob7214b338be6b5bbdfb369029dcba014e589383cc
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
3 // found in the LICENSE file.
5 #include "decoder_selector.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "media/base/audio_decoder.h"
12 #include "media/base/bind_to_current_loop.h"
13 #include "media/base/demuxer_stream.h"
14 #include "media/base/pipeline.h"
15 #include "media/base/video_decoder.h"
16 #include "media/filters/decoder_stream_traits.h"
17 #include "media/filters/decrypting_audio_decoder.h"
18 #include "media/filters/decrypting_demuxer_stream.h"
19 #include "media/filters/decrypting_video_decoder.h"
21 namespace media {
23 static bool HasValidStreamConfig(DemuxerStream* stream) {
24 switch (stream->type()) {
25 case DemuxerStream::AUDIO:
26 return stream->audio_decoder_config().IsValidConfig();
27 case DemuxerStream::VIDEO:
28 return stream->video_decoder_config().IsValidConfig();
29 case DemuxerStream::UNKNOWN:
30 case DemuxerStream::TEXT:
31 case DemuxerStream::NUM_TYPES:
32 NOTREACHED();
34 return false;
37 static bool IsStreamEncrypted(DemuxerStream* stream) {
38 switch (stream->type()) {
39 case DemuxerStream::AUDIO:
40 return stream->audio_decoder_config().is_encrypted();
41 case DemuxerStream::VIDEO:
42 return stream->video_decoder_config().is_encrypted();
43 case DemuxerStream::UNKNOWN:
44 case DemuxerStream::TEXT:
45 case DemuxerStream::NUM_TYPES:
46 NOTREACHED();
48 return false;
51 template <DemuxerStream::Type StreamType>
52 DecoderSelector<StreamType>::DecoderSelector(
53 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
54 ScopedVector<Decoder> decoders,
55 const SetDecryptorReadyCB& set_decryptor_ready_cb)
56 : task_runner_(task_runner),
57 decoders_(decoders.Pass()),
58 set_decryptor_ready_cb_(set_decryptor_ready_cb),
59 input_stream_(NULL),
60 weak_ptr_factory_(this) {}
62 template <DemuxerStream::Type StreamType>
63 DecoderSelector<StreamType>::~DecoderSelector() {
64 DVLOG(2) << __FUNCTION__;
65 DCHECK(task_runner_->BelongsToCurrentThread());
67 if (!select_decoder_cb_.is_null())
68 ReturnNullDecoder();
70 decoder_.reset();
71 decrypted_stream_.reset();
74 template <DemuxerStream::Type StreamType>
75 void DecoderSelector<StreamType>::SelectDecoder(
76 DemuxerStream* stream,
77 bool low_delay,
78 const SelectDecoderCB& select_decoder_cb,
79 const typename Decoder::OutputCB& output_cb) {
80 DVLOG(2) << __FUNCTION__;
81 DCHECK(task_runner_->BelongsToCurrentThread());
82 DCHECK(stream);
84 // Make sure |select_decoder_cb| runs on a different execution stack.
85 select_decoder_cb_ = BindToCurrentLoop(select_decoder_cb);
87 if (!HasValidStreamConfig(stream)) {
88 DLOG(ERROR) << "Invalid stream config.";
89 ReturnNullDecoder();
90 return;
93 input_stream_ = stream;
94 low_delay_ = low_delay;
95 output_cb_ = output_cb;
97 if (!IsStreamEncrypted(input_stream_)) {
98 InitializeDecoder();
99 return;
102 // This could happen if Encrypted Media Extension (EME) is not enabled.
103 if (set_decryptor_ready_cb_.is_null()) {
104 ReturnNullDecoder();
105 return;
108 decoder_.reset(new typename StreamTraits::DecryptingDecoderType(
109 task_runner_, set_decryptor_ready_cb_));
111 DecoderStreamTraits<StreamType>::Initialize(
112 decoder_.get(),
113 StreamTraits::GetDecoderConfig(*input_stream_),
114 low_delay_,
115 base::Bind(&DecoderSelector<StreamType>::DecryptingDecoderInitDone,
116 weak_ptr_factory_.GetWeakPtr()),
117 output_cb_);
120 template <DemuxerStream::Type StreamType>
121 void DecoderSelector<StreamType>::DecryptingDecoderInitDone(
122 PipelineStatus status) {
123 DVLOG(2) << __FUNCTION__;
124 DCHECK(task_runner_->BelongsToCurrentThread());
126 if (status == PIPELINE_OK) {
127 base::ResetAndReturn(&select_decoder_cb_)
128 .Run(decoder_.Pass(), scoped_ptr<DecryptingDemuxerStream>());
129 return;
132 decoder_.reset();
134 decrypted_stream_.reset(
135 new DecryptingDemuxerStream(task_runner_, set_decryptor_ready_cb_));
137 decrypted_stream_->Initialize(
138 input_stream_,
139 base::Bind(&DecoderSelector<StreamType>::DecryptingDemuxerStreamInitDone,
140 weak_ptr_factory_.GetWeakPtr()));
143 template <DemuxerStream::Type StreamType>
144 void DecoderSelector<StreamType>::DecryptingDemuxerStreamInitDone(
145 PipelineStatus status) {
146 DVLOG(2) << __FUNCTION__;
147 DCHECK(task_runner_->BelongsToCurrentThread());
149 if (status != PIPELINE_OK) {
150 ReturnNullDecoder();
151 return;
154 DCHECK(!IsStreamEncrypted(decrypted_stream_.get()));
155 input_stream_ = decrypted_stream_.get();
156 InitializeDecoder();
159 template <DemuxerStream::Type StreamType>
160 void DecoderSelector<StreamType>::InitializeDecoder() {
161 DVLOG(2) << __FUNCTION__;
162 DCHECK(task_runner_->BelongsToCurrentThread());
163 DCHECK(!decoder_);
165 if (decoders_.empty()) {
166 ReturnNullDecoder();
167 return;
170 decoder_.reset(decoders_.front());
171 decoders_.weak_erase(decoders_.begin());
173 DecoderStreamTraits<StreamType>::Initialize(
174 decoder_.get(),
175 StreamTraits::GetDecoderConfig(*input_stream_),
176 low_delay_,
177 base::Bind(&DecoderSelector<StreamType>::DecoderInitDone,
178 weak_ptr_factory_.GetWeakPtr()),
179 output_cb_);
182 template <DemuxerStream::Type StreamType>
183 void DecoderSelector<StreamType>::DecoderInitDone(PipelineStatus status) {
184 DVLOG(2) << __FUNCTION__;
185 DCHECK(task_runner_->BelongsToCurrentThread());
187 if (status != PIPELINE_OK) {
188 decoder_.reset();
189 InitializeDecoder();
190 return;
193 base::ResetAndReturn(&select_decoder_cb_)
194 .Run(decoder_.Pass(), decrypted_stream_.Pass());
197 template <DemuxerStream::Type StreamType>
198 void DecoderSelector<StreamType>::ReturnNullDecoder() {
199 DVLOG(2) << __FUNCTION__;
200 DCHECK(task_runner_->BelongsToCurrentThread());
201 base::ResetAndReturn(&select_decoder_cb_)
202 .Run(scoped_ptr<Decoder>(),
203 scoped_ptr<DecryptingDemuxerStream>());
206 // These forward declarations tell the compiler that we will use
207 // DecoderSelector with these arguments, allowing us to keep these definitions
208 // in our .cc without causing linker errors. This also means if anyone tries to
209 // instantiate a DecoderSelector with anything but these two specializations
210 // they'll most likely get linker errors.
211 template class DecoderSelector<DemuxerStream::AUDIO>;
212 template class DecoderSelector<DemuxerStream::VIDEO>;
214 } // namespace media