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(DecodeStatus::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(DecodeStatus::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(DecodeStatus::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(DecodeStatus::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(DecodeStatus::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(DecodeStatus::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(DecodeStatus::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(DecodeStatus::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 |