Revert of Set defaultPageScaleLimits before setIgnoreViewportTagScaleLimits (patchset...
[chromium-blink-merge.git] / media / filters / decrypting_video_decoder.cc
blobf4aa3756ed8b1c1a0ef1e5092091788c2370d772
1 // Copyright (c) 2012 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 "media/filters/decrypting_video_decoder.h"
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/trace_event/trace_event.h"
13 #include "media/base/bind_to_current_loop.h"
14 #include "media/base/decoder_buffer.h"
15 #include "media/base/decryptor.h"
16 #include "media/base/pipeline.h"
17 #include "media/base/video_decoder_config.h"
18 #include "media/base/video_frame.h"
20 namespace media {
22 const char DecryptingVideoDecoder::kDecoderName[] = "DecryptingVideoDecoder";
24 DecryptingVideoDecoder::DecryptingVideoDecoder(
25 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
26 const SetDecryptorReadyCB& set_decryptor_ready_cb)
27 : task_runner_(task_runner),
28 state_(kUninitialized),
29 set_decryptor_ready_cb_(set_decryptor_ready_cb),
30 decryptor_(NULL),
31 key_added_while_decode_pending_(false),
32 trace_id_(0),
33 weak_factory_(this) {}
35 std::string DecryptingVideoDecoder::GetDisplayName() const {
36 return kDecoderName;
39 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config,
40 bool /* low_delay */,
41 const PipelineStatusCB& status_cb,
42 const OutputCB& output_cb) {
43 DVLOG(2) << "Initialize()";
44 DCHECK(task_runner_->BelongsToCurrentThread());
45 DCHECK(state_ == kUninitialized ||
46 state_ == kIdle ||
47 state_ == kDecodeFinished) << state_;
48 DCHECK(decode_cb_.is_null());
49 DCHECK(reset_cb_.is_null());
50 DCHECK(config.IsValidConfig());
51 DCHECK(config.is_encrypted());
53 init_cb_ = BindToCurrentLoop(status_cb);
54 output_cb_ = BindToCurrentLoop(output_cb);
55 weak_this_ = weak_factory_.GetWeakPtr();
56 config_ = config;
58 if (state_ == kUninitialized) {
59 state_ = kDecryptorRequested;
60 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind(
61 &DecryptingVideoDecoder::SetDecryptor, weak_this_)));
62 return;
65 // Reinitialization.
66 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
67 state_ = kPendingDecoderInit;
68 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind(
69 &DecryptingVideoDecoder::FinishInitialization, weak_this_)));
72 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer,
73 const DecodeCB& decode_cb) {
74 DVLOG(3) << "Decode()";
75 DCHECK(task_runner_->BelongsToCurrentThread());
76 DCHECK(state_ == kIdle ||
77 state_ == kDecodeFinished ||
78 state_ == kError) << state_;
79 DCHECK(!decode_cb.is_null());
80 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported.";
82 decode_cb_ = BindToCurrentLoop(decode_cb);
84 if (state_ == kError) {
85 base::ResetAndReturn(&decode_cb_).Run(kDecodeError);
86 return;
89 // Return empty frames if decoding has finished.
90 if (state_ == kDecodeFinished) {
91 base::ResetAndReturn(&decode_cb_).Run(kOk);
92 return;
95 pending_buffer_to_decode_ = buffer;
96 state_ = kPendingDecode;
97 DecodePendingBuffer();
100 void DecryptingVideoDecoder::Reset(const base::Closure& closure) {
101 DVLOG(2) << "Reset() - state: " << state_;
102 DCHECK(task_runner_->BelongsToCurrentThread());
103 DCHECK(state_ == kIdle ||
104 state_ == kPendingDecode ||
105 state_ == kWaitingForKey ||
106 state_ == kDecodeFinished ||
107 state_ == kError) << state_;
108 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization.
109 DCHECK(reset_cb_.is_null());
111 reset_cb_ = BindToCurrentLoop(closure);
113 decryptor_->ResetDecoder(Decryptor::kVideo);
115 // Reset() cannot complete if the decode callback is still pending.
116 // Defer the resetting process in this case. The |reset_cb_| will be fired
117 // after the decode callback is fired - see DecryptAndDecodeBuffer() and
118 // DeliverFrame().
119 if (state_ == kPendingDecode) {
120 DCHECK(!decode_cb_.is_null());
121 return;
124 if (state_ == kWaitingForKey) {
125 DCHECK(!decode_cb_.is_null());
126 pending_buffer_to_decode_ = NULL;
127 base::ResetAndReturn(&decode_cb_).Run(kAborted);
130 DCHECK(decode_cb_.is_null());
131 DoReset();
134 DecryptingVideoDecoder::~DecryptingVideoDecoder() {
135 DCHECK(task_runner_->BelongsToCurrentThread());
137 if (state_ == kUninitialized)
138 return;
140 if (decryptor_) {
141 decryptor_->DeinitializeDecoder(Decryptor::kVideo);
142 decryptor_ = NULL;
144 if (!set_decryptor_ready_cb_.is_null())
145 base::ResetAndReturn(&set_decryptor_ready_cb_).Run(DecryptorReadyCB());
146 pending_buffer_to_decode_ = NULL;
147 if (!init_cb_.is_null())
148 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
149 if (!decode_cb_.is_null())
150 base::ResetAndReturn(&decode_cb_).Run(kAborted);
151 if (!reset_cb_.is_null())
152 base::ResetAndReturn(&reset_cb_).Run();
155 void DecryptingVideoDecoder::SetDecryptor(
156 Decryptor* decryptor,
157 const DecryptorAttachedCB& decryptor_attached_cb) {
158 DVLOG(2) << "SetDecryptor()";
159 DCHECK(task_runner_->BelongsToCurrentThread());
160 DCHECK_EQ(state_, kDecryptorRequested) << state_;
161 DCHECK(!init_cb_.is_null());
162 DCHECK(!set_decryptor_ready_cb_.is_null());
163 set_decryptor_ready_cb_.Reset();
165 if (!decryptor) {
166 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
167 state_ = kError;
168 decryptor_attached_cb.Run(false);
169 return;
172 decryptor_ = decryptor;
174 state_ = kPendingDecoderInit;
175 decryptor_->InitializeVideoDecoder(
176 config_,
177 BindToCurrentLoop(base::Bind(
178 &DecryptingVideoDecoder::FinishInitialization, weak_this_)));
179 decryptor_attached_cb.Run(true);
182 void DecryptingVideoDecoder::FinishInitialization(bool success) {
183 DVLOG(2) << "FinishInitialization()";
184 DCHECK(task_runner_->BelongsToCurrentThread());
185 DCHECK_EQ(state_, kPendingDecoderInit) << state_;
186 DCHECK(!init_cb_.is_null());
187 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished.
188 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished.
190 if (!success) {
191 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
192 decryptor_ = NULL;
193 state_ = kError;
194 return;
197 decryptor_->RegisterNewKeyCB(
198 Decryptor::kVideo,
199 BindToCurrentLoop(
200 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_)));
202 // Success!
203 state_ = kIdle;
204 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
208 void DecryptingVideoDecoder::DecodePendingBuffer() {
209 DCHECK(task_runner_->BelongsToCurrentThread());
210 DCHECK_EQ(state_, kPendingDecode) << state_;
211 TRACE_EVENT_ASYNC_BEGIN0(
212 "media", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_);
214 int buffer_size = 0;
215 if (!pending_buffer_to_decode_->end_of_stream()) {
216 buffer_size = pending_buffer_to_decode_->data_size();
219 decryptor_->DecryptAndDecodeVideo(
220 pending_buffer_to_decode_, BindToCurrentLoop(base::Bind(
221 &DecryptingVideoDecoder::DeliverFrame, weak_this_, buffer_size)));
224 void DecryptingVideoDecoder::DeliverFrame(
225 int buffer_size,
226 Decryptor::Status status,
227 const scoped_refptr<VideoFrame>& frame) {
228 DVLOG(3) << "DeliverFrame() - status: " << status;
229 DCHECK(task_runner_->BelongsToCurrentThread());
230 DCHECK_EQ(state_, kPendingDecode) << state_;
231 DCHECK(!decode_cb_.is_null());
232 DCHECK(pending_buffer_to_decode_.get());
234 TRACE_EVENT_ASYNC_END2(
235 "media", "DecryptingVideoDecoder::DecodePendingBuffer", trace_id_,
236 "buffer_size", buffer_size, "status", status);
238 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_;
239 key_added_while_decode_pending_ = false;
241 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode =
242 pending_buffer_to_decode_;
243 pending_buffer_to_decode_ = NULL;
245 if (!reset_cb_.is_null()) {
246 base::ResetAndReturn(&decode_cb_).Run(kAborted);
247 DoReset();
248 return;
251 DCHECK_EQ(status == Decryptor::kSuccess, frame.get() != NULL);
253 if (status == Decryptor::kError) {
254 DVLOG(2) << "DeliverFrame() - kError";
255 state_ = kError;
256 base::ResetAndReturn(&decode_cb_).Run(kDecodeError);
257 return;
260 if (status == Decryptor::kNoKey) {
261 DVLOG(2) << "DeliverFrame() - kNoKey";
262 // Set |pending_buffer_to_decode_| back as we need to try decoding the
263 // pending buffer again when new key is added to the decryptor.
264 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode;
266 if (need_to_try_again_if_nokey_is_returned) {
267 // The |state_| is still kPendingDecode.
268 DecodePendingBuffer();
269 return;
272 state_ = kWaitingForKey;
273 return;
276 if (status == Decryptor::kNeedMoreData) {
277 DVLOG(2) << "DeliverFrame() - kNeedMoreData";
278 state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished
279 : kIdle;
280 base::ResetAndReturn(&decode_cb_).Run(kOk);
281 return;
284 DCHECK_EQ(status, Decryptor::kSuccess);
285 // No frame returned with kSuccess should be end-of-stream frame.
286 DCHECK(!frame->end_of_stream());
287 output_cb_.Run(frame);
289 if (scoped_pending_buffer_to_decode->end_of_stream()) {
290 // Set |pending_buffer_to_decode_| back as we need to keep flushing the
291 // decryptor.
292 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode;
293 DecodePendingBuffer();
294 return;
297 state_ = kIdle;
298 base::ResetAndReturn(&decode_cb_).Run(kOk);
301 void DecryptingVideoDecoder::OnKeyAdded() {
302 DVLOG(2) << "OnKeyAdded()";
303 DCHECK(task_runner_->BelongsToCurrentThread());
305 if (state_ == kPendingDecode) {
306 key_added_while_decode_pending_ = true;
307 return;
310 if (state_ == kWaitingForKey) {
311 state_ = kPendingDecode;
312 DecodePendingBuffer();
316 void DecryptingVideoDecoder::DoReset() {
317 DCHECK(init_cb_.is_null());
318 DCHECK(decode_cb_.is_null());
319 state_ = kIdle;
320 base::ResetAndReturn(&reset_cb_).Run();
323 } // namespace media