| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/decrypting_video_decoder.h" | 5 #include "media/filters/decrypting_video_decoder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 DCHECK(task_runner_->BelongsToCurrentThread()); | 84 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 85 DCHECK(state_ == kIdle || | 85 DCHECK(state_ == kIdle || |
| 86 state_ == kDecodeFinished || | 86 state_ == kDecodeFinished || |
| 87 state_ == kError) << state_; | 87 state_ == kError) << state_; |
| 88 DCHECK(!decode_cb.is_null()); | 88 DCHECK(!decode_cb.is_null()); |
| 89 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; | 89 CHECK(decode_cb_.is_null()) << "Overlapping decodes are not supported."; |
| 90 | 90 |
| 91 decode_cb_ = BindToCurrentLoop(decode_cb); | 91 decode_cb_ = BindToCurrentLoop(decode_cb); |
| 92 | 92 |
| 93 if (state_ == kError) { | 93 if (state_ == kError) { |
| 94 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); | 94 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::DECODE_ERROR); |
| 95 return; | 95 return; |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Return empty frames if decoding has finished. | 98 // Return empty frames if decoding has finished. |
| 99 if (state_ == kDecodeFinished) { | 99 if (state_ == kDecodeFinished) { |
| 100 base::ResetAndReturn(&decode_cb_).Run(kOk); | 100 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::OK); |
| 101 return; | 101 return; |
| 102 } | 102 } |
| 103 | 103 |
| 104 pending_buffer_to_decode_ = buffer; | 104 pending_buffer_to_decode_ = buffer; |
| 105 state_ = kPendingDecode; | 105 state_ = kPendingDecode; |
| 106 DecodePendingBuffer(); | 106 DecodePendingBuffer(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { | 109 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { |
| 110 DVLOG(2) << "Reset() - state: " << state_; | 110 DVLOG(2) << "Reset() - state: " << state_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 126 // after the decode callback is fired - see DecryptAndDecodeBuffer() and | 126 // after the decode callback is fired - see DecryptAndDecodeBuffer() and |
| 127 // DeliverFrame(). | 127 // DeliverFrame(). |
| 128 if (state_ == kPendingDecode) { | 128 if (state_ == kPendingDecode) { |
| 129 DCHECK(!decode_cb_.is_null()); | 129 DCHECK(!decode_cb_.is_null()); |
| 130 return; | 130 return; |
| 131 } | 131 } |
| 132 | 132 |
| 133 if (state_ == kWaitingForKey) { | 133 if (state_ == kWaitingForKey) { |
| 134 DCHECK(!decode_cb_.is_null()); | 134 DCHECK(!decode_cb_.is_null()); |
| 135 pending_buffer_to_decode_ = NULL; | 135 pending_buffer_to_decode_ = NULL; |
| 136 base::ResetAndReturn(&decode_cb_).Run(kAborted); | 136 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::ABORTED); |
| 137 } | 137 } |
| 138 | 138 |
| 139 DCHECK(decode_cb_.is_null()); | 139 DCHECK(decode_cb_.is_null()); |
| 140 DoReset(); | 140 DoReset(); |
| 141 } | 141 } |
| 142 | 142 |
| 143 DecryptingVideoDecoder::~DecryptingVideoDecoder() { | 143 DecryptingVideoDecoder::~DecryptingVideoDecoder() { |
| 144 DCHECK(task_runner_->BelongsToCurrentThread()); | 144 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 145 | 145 |
| 146 if (state_ == kUninitialized) | 146 if (state_ == kUninitialized) |
| 147 return; | 147 return; |
| 148 | 148 |
| 149 if (decryptor_) { | 149 if (decryptor_) { |
| 150 decryptor_->DeinitializeDecoder(Decryptor::kVideo); | 150 decryptor_->DeinitializeDecoder(Decryptor::kVideo); |
| 151 decryptor_ = NULL; | 151 decryptor_ = NULL; |
| 152 } | 152 } |
| 153 pending_buffer_to_decode_ = NULL; | 153 pending_buffer_to_decode_ = NULL; |
| 154 if (!init_cb_.is_null()) | 154 if (!init_cb_.is_null()) |
| 155 base::ResetAndReturn(&init_cb_).Run(false); | 155 base::ResetAndReturn(&init_cb_).Run(false); |
| 156 if (!decode_cb_.is_null()) | 156 if (!decode_cb_.is_null()) |
| 157 base::ResetAndReturn(&decode_cb_).Run(kAborted); | 157 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::ABORTED); |
| 158 if (!reset_cb_.is_null()) | 158 if (!reset_cb_.is_null()) |
| 159 base::ResetAndReturn(&reset_cb_).Run(); | 159 base::ResetAndReturn(&reset_cb_).Run(); |
| 160 } | 160 } |
| 161 | 161 |
| 162 void DecryptingVideoDecoder::FinishInitialization(bool success) { | 162 void DecryptingVideoDecoder::FinishInitialization(bool success) { |
| 163 DVLOG(2) << "FinishInitialization()"; | 163 DVLOG(2) << "FinishInitialization()"; |
| 164 DCHECK(task_runner_->BelongsToCurrentThread()); | 164 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 165 DCHECK_EQ(state_, kPendingDecoderInit) << state_; | 165 DCHECK_EQ(state_, kPendingDecoderInit) << state_; |
| 166 DCHECK(!init_cb_.is_null()); | 166 DCHECK(!init_cb_.is_null()); |
| 167 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. | 167 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 "buffer_size", buffer_size, "status", status); | 218 "buffer_size", buffer_size, "status", status); |
| 219 | 219 |
| 220 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; | 220 bool need_to_try_again_if_nokey_is_returned = key_added_while_decode_pending_; |
| 221 key_added_while_decode_pending_ = false; | 221 key_added_while_decode_pending_ = false; |
| 222 | 222 |
| 223 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = | 223 scoped_refptr<DecoderBuffer> scoped_pending_buffer_to_decode = |
| 224 pending_buffer_to_decode_; | 224 pending_buffer_to_decode_; |
| 225 pending_buffer_to_decode_ = NULL; | 225 pending_buffer_to_decode_ = NULL; |
| 226 | 226 |
| 227 if (!reset_cb_.is_null()) { | 227 if (!reset_cb_.is_null()) { |
| 228 base::ResetAndReturn(&decode_cb_).Run(kAborted); | 228 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::ABORTED); |
| 229 DoReset(); | 229 DoReset(); |
| 230 return; | 230 return; |
| 231 } | 231 } |
| 232 | 232 |
| 233 DCHECK_EQ(status == Decryptor::kSuccess, frame.get() != NULL); | 233 DCHECK_EQ(status == Decryptor::kSuccess, frame.get() != NULL); |
| 234 | 234 |
| 235 if (status == Decryptor::kError) { | 235 if (status == Decryptor::kError) { |
| 236 DVLOG(2) << "DeliverFrame() - kError"; | 236 DVLOG(2) << "DeliverFrame() - kError"; |
| 237 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": decode error"; | 237 MEDIA_LOG(ERROR, media_log_) << GetDisplayName() << ": decode error"; |
| 238 state_ = kError; | 238 state_ = kError; |
| 239 base::ResetAndReturn(&decode_cb_).Run(kDecodeError); | 239 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::DECODE_ERROR); |
| 240 return; | 240 return; |
| 241 } | 241 } |
| 242 | 242 |
| 243 if (status == Decryptor::kNoKey) { | 243 if (status == Decryptor::kNoKey) { |
| 244 DVLOG(2) << "DeliverFrame() - kNoKey"; | 244 DVLOG(2) << "DeliverFrame() - kNoKey"; |
| 245 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no key"; | 245 MEDIA_LOG(DEBUG, media_log_) << GetDisplayName() << ": no key"; |
| 246 | 246 |
| 247 // Set |pending_buffer_to_decode_| back as we need to try decoding the | 247 // Set |pending_buffer_to_decode_| back as we need to try decoding the |
| 248 // pending buffer again when new key is added to the decryptor. | 248 // pending buffer again when new key is added to the decryptor. |
| 249 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; | 249 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; |
| 250 | 250 |
| 251 if (need_to_try_again_if_nokey_is_returned) { | 251 if (need_to_try_again_if_nokey_is_returned) { |
| 252 // The |state_| is still kPendingDecode. | 252 // The |state_| is still kPendingDecode. |
| 253 DecodePendingBuffer(); | 253 DecodePendingBuffer(); |
| 254 return; | 254 return; |
| 255 } | 255 } |
| 256 | 256 |
| 257 state_ = kWaitingForKey; | 257 state_ = kWaitingForKey; |
| 258 waiting_for_decryption_key_cb_.Run(); | 258 waiting_for_decryption_key_cb_.Run(); |
| 259 return; | 259 return; |
| 260 } | 260 } |
| 261 | 261 |
| 262 if (status == Decryptor::kNeedMoreData) { | 262 if (status == Decryptor::kNeedMoreData) { |
| 263 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; | 263 DVLOG(2) << "DeliverFrame() - kNeedMoreData"; |
| 264 state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished | 264 state_ = scoped_pending_buffer_to_decode->end_of_stream() ? kDecodeFinished |
| 265 : kIdle; | 265 : kIdle; |
| 266 base::ResetAndReturn(&decode_cb_).Run(kOk); | 266 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::OK); |
| 267 return; | 267 return; |
| 268 } | 268 } |
| 269 | 269 |
| 270 DCHECK_EQ(status, Decryptor::kSuccess); | 270 DCHECK_EQ(status, Decryptor::kSuccess); |
| 271 // No frame returned with kSuccess should be end-of-stream frame. | 271 // No frame returned with kSuccess should be end-of-stream frame. |
| 272 DCHECK(!frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)); | 272 DCHECK(!frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM)); |
| 273 output_cb_.Run(frame); | 273 output_cb_.Run(frame); |
| 274 | 274 |
| 275 if (scoped_pending_buffer_to_decode->end_of_stream()) { | 275 if (scoped_pending_buffer_to_decode->end_of_stream()) { |
| 276 // Set |pending_buffer_to_decode_| back as we need to keep flushing the | 276 // Set |pending_buffer_to_decode_| back as we need to keep flushing the |
| 277 // decryptor. | 277 // decryptor. |
| 278 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; | 278 pending_buffer_to_decode_ = scoped_pending_buffer_to_decode; |
| 279 DecodePendingBuffer(); | 279 DecodePendingBuffer(); |
| 280 return; | 280 return; |
| 281 } | 281 } |
| 282 | 282 |
| 283 state_ = kIdle; | 283 state_ = kIdle; |
| 284 base::ResetAndReturn(&decode_cb_).Run(kOk); | 284 base::ResetAndReturn(&decode_cb_).Run(DecoderStatus::OK); |
| 285 } | 285 } |
| 286 | 286 |
| 287 void DecryptingVideoDecoder::OnKeyAdded() { | 287 void DecryptingVideoDecoder::OnKeyAdded() { |
| 288 DVLOG(2) << "OnKeyAdded()"; | 288 DVLOG(2) << "OnKeyAdded()"; |
| 289 DCHECK(task_runner_->BelongsToCurrentThread()); | 289 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 290 | 290 |
| 291 if (state_ == kPendingDecode) { | 291 if (state_ == kPendingDecode) { |
| 292 key_added_while_decode_pending_ = true; | 292 key_added_while_decode_pending_ = true; |
| 293 return; | 293 return; |
| 294 } | 294 } |
| 295 | 295 |
| 296 if (state_ == kWaitingForKey) { | 296 if (state_ == kWaitingForKey) { |
| 297 state_ = kPendingDecode; | 297 state_ = kPendingDecode; |
| 298 DecodePendingBuffer(); | 298 DecodePendingBuffer(); |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 | 301 |
| 302 void DecryptingVideoDecoder::DoReset() { | 302 void DecryptingVideoDecoder::DoReset() { |
| 303 DCHECK(init_cb_.is_null()); | 303 DCHECK(init_cb_.is_null()); |
| 304 DCHECK(decode_cb_.is_null()); | 304 DCHECK(decode_cb_.is_null()); |
| 305 state_ = kIdle; | 305 state_ = kIdle; |
| 306 base::ResetAndReturn(&reset_cb_).Run(); | 306 base::ResetAndReturn(&reset_cb_).Run(); |
| 307 } | 307 } |
| 308 | 308 |
| 309 } // namespace media | 309 } // namespace media |
| OLD | NEW |