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. 4 5 #include "media/filters/decrypting_video_decoder.h" 6 7 #include "base/bind.h" 8 #include "base/callback_helpers.h" 9 #include "base/debug/trace_event.h" 10 #include "base/location.h" 11 #include "base/logging.h" 12 #include "base/single_thread_task_runner.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" 19 20 namespace media { 21 22 DecryptingVideoDecoder::DecryptingVideoDecoder( 23 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 24 const SetDecryptorReadyCB& set_decryptor_ready_cb) 25 : task_runner_(task_runner), 26 state_(kUninitialized), 27 set_decryptor_ready_cb_(set_decryptor_ready_cb), 28 decryptor_(NULL), 29 key_added_while_decode_pending_(false), 30 trace_id_(0), 31 weak_factory_(this) {} 32 33 void DecryptingVideoDecoder::Initialize(const VideoDecoderConfig& config, 34 bool /* low_delay */, 35 const PipelineStatusCB& status_cb, 36 const OutputCB& output_cb) { 37 DVLOG(2) << "Initialize()"; 38 DCHECK(task_runner_->BelongsToCurrentThread()); 39 DCHECK(state_ == kUninitialized || 40 state_ == kIdle || 41 state_ == kDecodeFinished) << state_; 42 DCHECK(decode_cb_.is_null()); 43 DCHECK(reset_cb_.is_null()); 44 DCHECK(config.IsValidConfig()); 45 DCHECK(config.is_encrypted()); 46 47 init_cb_ = BindToCurrentLoop(status_cb); 48 output_cb_ = BindToCurrentLoop(output_cb); 49 weak_this_ = weak_factory_.GetWeakPtr(); 50 config_ = config; 51 52 if (state_ == kUninitialized) { 53 state_ = kDecryptorRequested; 54 set_decryptor_ready_cb_.Run(BindToCurrentLoop(base::Bind( 55 &DecryptingVideoDecoder::SetDecryptor, weak_this_))); 56 return; 57 } 58 59 // Reinitialization. 60 decryptor_->DeinitializeDecoder(Decryptor::kVideo); 61 state_ = kPendingDecoderInit; 62 decryptor_->InitializeVideoDecoder(config, BindToCurrentLoop(base::Bind( 63 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); 64 } 65 66 void DecryptingVideoDecoder::Decode(const scoped_refptr<DecoderBuffer>& buffer, 67 const DecodeCB& decode_cb) { 68 DVLOG(3) << "Decode()"; 69 DCHECK(task_runner_->BelongsToCurrentThread()); 70 DCHECK(state_ == kIdle || 71 state_ == kDecodeFinished || 72 state_ == kError) << state_; 73 DCHECK(!decode_cb.is_null()); 74 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; 75 76 decode_cb_ = BindToCurrentLoop(decode_cb); 77 78 if (state_ == kError) { 79 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); 80 return; 81 } 82 83 // Return empty frames if decoding has finished. 84 if (state_ == kDecodeFinished) { 85 base::ResetAndReturn(&decode_cb_).Run(kOk); 86 return; 87 } 88 89 pending_buffer_to_decode_ = buffer; 90 state_ = kPendingDecode; 91 DecodePendingBuffer(); 92 } 93 94 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { 95 DVLOG(2) << "Reset() - state: " << state_; 96 DCHECK(task_runner_->BelongsToCurrentThread()); 97 DCHECK(state_ == kIdle || 98 state_ == kPendingDecode || 99 state_ == kWaitingForKey || 100 state_ == kDecodeFinished || 101 state_ == kError) << state_; 102 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 103 DCHECK(reset_cb_.is_null()); 104 105 reset_cb_ = BindToCurrentLoop(closure); 106 107 decryptor_->ResetDecoder(Decryptor::kVideo); 108 109 // Reset() cannot complete if the decode callback is still pending. 110 // Defer the resetting process in this case. The |reset_cb_| will be fired 111 // after the decode callback is fired - see DecryptAndDecodeBuffer() and 112 // DeliverFrame(). 113 if (state_ == kPendingDecode) { 114 DCHECK(!decode_cb_.is_null()); 115 return; 116 } 117 118 if (state_ == kWaitingForKey) { 119 DCHECK(!decode_cb_.is_null()); 120 pending_buffer_to_decode_ = NULL; 121 base::ResetAndReturn(&decode_cb_).Run(kAborted); 122 } 123 124 DCHECK(decode_cb_.is_null()); 125 DoReset(); 126 } 127 128 void DecryptingVideoDecoder::Stop() { 129 DCHECK(task_runner_->BelongsToCurrentThread()); 130 DVLOG(2) << "Stop() - state: " << state_; 131 132 // Invalidate all weak pointers so that pending callbacks won't be fired into 133 // this object. 134 weak_factory_.InvalidateWeakPtrs(); 135 136 // At this point the render thread is likely paused (in WebMediaPlayerImpl's 137 // Destroy()), so running |closure| can't wait for anything that requires the 138 // render thread to be processing messages to complete (such as PPAPI 139 // callbacks). 140 if (decryptor_) { 141 decryptor_->DeinitializeDecoder(Decryptor::kVideo); 142 decryptor_ = NULL; 143 } 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(); 153 154 state_ = kStopped; 155 } 156 157 DecryptingVideoDecoder::~DecryptingVideoDecoder() { 158 DCHECK(state_ == kUninitialized || state_ == kStopped) << state_; 159 } 160 161 void DecryptingVideoDecoder::SetDecryptor(Decryptor* decryptor) { 162 DVLOG(2) << "SetDecryptor()"; 163 DCHECK(task_runner_->BelongsToCurrentThread()); 164 DCHECK_EQ(state_, kDecryptorRequested) << state_; 165 DCHECK(!init_cb_.is_null()); 166 DCHECK(!set_decryptor_ready_cb_.is_null()); 167 set_decryptor_ready_cb_.Reset(); 168 169 if (!decryptor) { 170 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 171 state_ = kStopped; 172 return; 173 } 174 175 decryptor_ = decryptor; 176 177 state_ = kPendingDecoderInit; 178 decryptor_->InitializeVideoDecoder( 179 config_, 180 BindToCurrentLoop(base::Bind( 181 &DecryptingVideoDecoder::FinishInitialization, weak_this_))); 182 } 183 184 void DecryptingVideoDecoder::FinishInitialization(bool success) { 185 DVLOG(2) << "FinishInitialization()"; 186 DCHECK(task_runner_->BelongsToCurrentThread()); 187 DCHECK_EQ(state_, kPendingDecoderInit) << state_; 188 DCHECK(!init_cb_.is_null()); 189 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. 190 DCHECK(decode_cb_.is_null()); // No Decode() before initialization finished. 191 192 if (!success) { 193 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 194 state_ = kStopped; 195 return; 196 } 197 198 decryptor_->RegisterNewKeyCB( 199 Decryptor::kVideo, 200 BindToCurrentLoop( 201 base::Bind(&DecryptingVideoDecoder::OnKeyAdded, weak_this_))); 202 203 // Success! 204 state_ = kIdle; 205 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 206 } 207 208 209 void DecryptingVideoDecoder::DecodePendingBuffer() { 210 DCHECK(task_runner_->BelongsToCurrentThread()); 211 DCHECK_EQ(state_, kPendingDecode) << state_; 212 TRACE_EVENT_ASYNC_BEGIN0( 213 "media", "DecryptingVideoDecoder::DecodePendingBuffer", ++trace_id_); 214 215 int buffer_size = 0; 216 if (!pending_buffer_to_decode_->end_of_stream()) { 217 buffer_size = pending_buffer_to_decode_->data_size(); 218 } 219 220 decryptor_->DecryptAndDecodeVideo( 221 pending_buffer_to_decode_, BindToCurrentLoop(base::Bind( 222 &DecryptingVideoDecoder::DeliverFrame, weak_this_, buffer_size))); 223 } 224 225 void DecryptingVideoDecoder::DeliverFrame( 226 int buffer_size, 227 Decryptor::Status status, 228 const scoped_refptr<VideoFrame>& frame) { 229 DVLOG(3) << "DeliverFrame() - status: " << status; 230 DCHECK(task_runner_->BelongsToCurrentThread()); 231 DCHECK_EQ(state_, kPendingDecode) << state_; 232 DCHECK(!decode_cb_.is_null()); 233 DCHECK(pending_buffer_to_decode_.get()); 234 235 TRACE_EVENT_ASYNC_END2( 236 "media", "DecryptingVideoDecoder::DecodePendingBuffer", trace_id_, 237 "buffer_size", buffer_size, "status", status); 238 239 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; 240 key_added_while_decode_pending_ = false; 241 242 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = 243 pending_buffer_to_decode_; 244 pending_buffer_to_decode_ = NULL; 245 246 if (!reset_cb_.is_null()) { 247 base::ResetAndReturn(&decode_cb_).Run(kAborted); 248 DoReset(); 249 return; 250 } 251 252 DCHECK_EQ(status == Decryptor::kSuccess, frame.get() != NULL); 253 254 if (status == Decryptor::kError) { 255 DVLOG(2) << "DeliverFrame() - kError"; 256 state_ = kError; 257 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); 258 return; 259 } 260 261 if (status == Decryptor::kNoKey) { 262 DVLOG(2) << "DeliverFrame() - kNoKey"; 263 // Set |pending_buffer_to_decode_| back as we need to try decoding the 264 // pending buffer again when new key is added to the decryptor. 265 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; 266 267 if (need_to_try_again_if_nokey_is_returned) { 268 // The |state_| is still kPendingDecode. 269 DecodePendingBuffer(); 270 return; 271 } 272 273 state_ = kWaitingForKey; 274 return; 275 } 276 277 if (status == Decryptor::kNeedMoreData) { 278 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; 279 state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished 280 : kIdle; 281 base::ResetAndReturn(&decode_cb_).Run(kOk); 282 return; 283 } 284 285 DCHECK_EQ(status, Decryptor::kSuccess); 286 // No frame returned with kSuccess should be end-of-stream frame. 287 DCHECK(!frame->end_of_stream()); 288 output_cb_.Run(frame); 289 290 if (scoped_pending_buffer_to_decode->end_of_stream()) { 291 // Set |pending_buffer_to_decode_| back as we need to keep flushing the 292 // decryptor. 293 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; 294 DecodePendingBuffer(); 295 return; 296 } 297 298 state_ = kIdle; 299 base::ResetAndReturn(&decode_cb_).Run(kOk); 300 } 301 302 void DecryptingVideoDecoder::OnKeyAdded() { 303 DVLOG(2) << "OnKeyAdded()"; 304 DCHECK(task_runner_->BelongsToCurrentThread()); 305 306 if (state_ == kPendingDecode) { 307 key_added_while_decode_pending_ = true; 308 return; 309 } 310 311 if (state_ == kWaitingForKey) { 312 state_ = kPendingDecode; 313 DecodePendingBuffer(); 314 } 315 } 316 317 void DecryptingVideoDecoder::DoReset() { 318 DCHECK(init_cb_.is_null()); 319 DCHECK(decode_cb_.is_null()); 320 state_ = kIdle; 321 base::ResetAndReturn(&reset_cb_).Run(); 322 } 323 324 } // namespace media 325