Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: media/filters/decrypting_video_decoder.cc

Issue 11091005: Update PluginInstance for decrypt-and-decode video. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: a lot of change, need to be reviewed again Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/message_loop_proxy.h" 10 #include "base/message_loop_proxy.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 &DecryptingVideoDecoder::DoRead, this, read_cb)); 49 &DecryptingVideoDecoder::DoRead, this, read_cb));
50 } 50 }
51 51
52 void DecryptingVideoDecoder::Reset(const base::Closure& closure) { 52 void DecryptingVideoDecoder::Reset(const base::Closure& closure) {
53 if (!message_loop_->BelongsToCurrentThread()) { 53 if (!message_loop_->BelongsToCurrentThread()) {
54 message_loop_->PostTask(FROM_HERE, base::Bind( 54 message_loop_->PostTask(FROM_HERE, base::Bind(
55 &DecryptingVideoDecoder::Reset, this, closure)); 55 &DecryptingVideoDecoder::Reset, this, closure));
56 return; 56 return;
57 } 57 }
58 58
59 DVLOG(2) << "Reset() - state: " << state_;
60
59 DCHECK(state_ == kIdle || 61 DCHECK(state_ == kIdle ||
60 state_ == kPendingDemuxerRead || 62 state_ == kPendingDemuxerRead ||
61 state_ == kPendingDecode || 63 state_ == kPendingDecode ||
62 state_ == kWaitingForKey || 64 state_ == kWaitingForKey ||
63 state_ == kDecodeFinished) << state_; 65 state_ == kDecodeFinished) << state_;
64 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization. 66 DCHECK(init_cb_.is_null()); // No Reset() during pending initialization.
65 DCHECK(stop_cb_.is_null()); // No Reset() during pending Stop(). 67 DCHECK(stop_cb_.is_null()); // No Reset() during pending Stop().
66 DCHECK(reset_cb_.is_null()); 68 DCHECK(reset_cb_.is_null());
67 69
68 reset_cb_ = closure; 70 reset_cb_ = closure;
(...skipping 19 matching lines...) Expand all
88 DoReset(); 90 DoReset();
89 } 91 }
90 92
91 void DecryptingVideoDecoder::Stop(const base::Closure& closure) { 93 void DecryptingVideoDecoder::Stop(const base::Closure& closure) {
92 if (!message_loop_->BelongsToCurrentThread()) { 94 if (!message_loop_->BelongsToCurrentThread()) {
93 message_loop_->PostTask(FROM_HERE, base::Bind( 95 message_loop_->PostTask(FROM_HERE, base::Bind(
94 &DecryptingVideoDecoder::Stop, this, closure)); 96 &DecryptingVideoDecoder::Stop, this, closure));
95 return; 97 return;
96 } 98 }
97 99
100 DVLOG(2) << "Stop() - state: " << state_;
101
98 DCHECK(stop_cb_.is_null()); 102 DCHECK(stop_cb_.is_null());
99 stop_cb_ = closure; 103 stop_cb_ = closure;
100 104
101 // We need to call Decryptor::StopVideoDecoder() if we ever called 105 // We need to call Decryptor::StopVideoDecoder() if we ever called
102 // Decryptor::InitializeVideoDecoder() to cancel the pending initialization if 106 // Decryptor::InitializeVideoDecoder() to cancel the pending initialization if
103 // the initialization is still pending, or to stop the video decoder if 107 // the initialization is still pending, or to stop the video decoder if
104 // the initialization has completed. 108 // the initialization has completed.
105 // When the state is kUninitialized and kDecryptorRequested, 109 // When the state is kUninitialized and kDecryptorRequested,
106 // InitializeVideoDecoder() has not been called, so we are okay. 110 // InitializeVideoDecoder() has not been called, so we are okay.
107 // When the state is kStopped, the video decoder should have already been 111 // When the state is kStopped, the video decoder should have already been
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 } 155 }
152 156
153 void DecryptingVideoDecoder::DoInitialize( 157 void DecryptingVideoDecoder::DoInitialize(
154 const scoped_refptr<DemuxerStream>& stream, 158 const scoped_refptr<DemuxerStream>& stream,
155 const PipelineStatusCB& status_cb, 159 const PipelineStatusCB& status_cb,
156 const StatisticsCB& statistics_cb) { 160 const StatisticsCB& statistics_cb) {
157 DCHECK(message_loop_->BelongsToCurrentThread()); 161 DCHECK(message_loop_->BelongsToCurrentThread());
158 DCHECK_EQ(state_, kUninitialized) << state_; 162 DCHECK_EQ(state_, kUninitialized) << state_;
159 DCHECK(stream); 163 DCHECK(stream);
160 164
165 DVLOG(2) << "DoInitialize()";
ddorwin 2012/10/13 01:40:28 Suggest eliminating the extra line below. One way
xhwang 2012/10/15 19:53:01 Done.
166
161 const VideoDecoderConfig& config = stream->video_decoder_config(); 167 const VideoDecoderConfig& config = stream->video_decoder_config();
162 if (!config.IsValidConfig()) { 168 if (!config.IsValidConfig()) {
163 DLOG(ERROR) << "Invalid video stream config: " 169 DLOG(ERROR) << "Invalid video stream config: "
164 << config.AsHumanReadableString(); 170 << config.AsHumanReadableString();
165 status_cb.Run(PIPELINE_ERROR_DECODE); 171 status_cb.Run(PIPELINE_ERROR_DECODE);
166 return; 172 return;
167 } 173 }
168 174
169 // DecryptingVideoDecoder only accepts potentially encrypted stream. 175 // DecryptingVideoDecoder only accepts potentially encrypted stream.
170 if (!config.is_encrypted()) { 176 if (!config.is_encrypted()) {
(...skipping 10 matching lines...) Expand all
181 state_ = kDecryptorRequested; 187 state_ = kDecryptorRequested;
182 request_decryptor_notification_cb_.Run( 188 request_decryptor_notification_cb_.Run(
183 BIND_TO_LOOP(&DecryptingVideoDecoder::SetDecryptor)); 189 BIND_TO_LOOP(&DecryptingVideoDecoder::SetDecryptor));
184 } 190 }
185 191
186 void DecryptingVideoDecoder::SetDecryptor(Decryptor* decryptor) { 192 void DecryptingVideoDecoder::SetDecryptor(Decryptor* decryptor) {
187 DCHECK(message_loop_->BelongsToCurrentThread()); 193 DCHECK(message_loop_->BelongsToCurrentThread());
188 DCHECK_EQ(state_, kDecryptorRequested) << state_; 194 DCHECK_EQ(state_, kDecryptorRequested) << state_;
189 DCHECK(!init_cb_.is_null()); 195 DCHECK(!init_cb_.is_null());
190 196
197 DVLOG(2) << "SetDecryptor()";
198
191 if (!stop_cb_.is_null()) { 199 if (!stop_cb_.is_null()) {
192 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 200 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
193 DoStop(); 201 DoStop();
194 return; 202 return;
195 } 203 }
196 204
197 decryptor_ = decryptor; 205 decryptor_ = decryptor;
198 206
199 scoped_ptr<VideoDecoderConfig> scoped_config(new VideoDecoderConfig()); 207 scoped_ptr<VideoDecoderConfig> scoped_config(new VideoDecoderConfig());
200 scoped_config->CopyFrom(demuxer_stream_->video_decoder_config()); 208 scoped_config->CopyFrom(demuxer_stream_->video_decoder_config());
201 209
202 state_ = kPendingDecoderInit; 210 state_ = kPendingDecoderInit;
203 decryptor_->InitializeVideoDecoder( 211 decryptor_->InitializeVideoDecoder(
204 scoped_config.Pass(), 212 scoped_config.Pass(),
205 BIND_TO_LOOP(&DecryptingVideoDecoder::FinishInitialization), 213 BIND_TO_LOOP(&DecryptingVideoDecoder::FinishInitialization),
206 BIND_TO_LOOP(&DecryptingVideoDecoder::OnKeyAdded)); 214 BIND_TO_LOOP(&DecryptingVideoDecoder::OnKeyAdded));
207 } 215 }
208 216
209 void DecryptingVideoDecoder::FinishInitialization(bool success) { 217 void DecryptingVideoDecoder::FinishInitialization(bool success) {
210 DCHECK(message_loop_->BelongsToCurrentThread()); 218 DCHECK(message_loop_->BelongsToCurrentThread());
211 DCHECK_EQ(state_, kPendingDecoderInit) << state_; 219 DCHECK_EQ(state_, kPendingDecoderInit) << state_;
212 DCHECK(!init_cb_.is_null()); 220 DCHECK(!init_cb_.is_null());
213 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished. 221 DCHECK(reset_cb_.is_null()); // No Reset() before initialization finished.
214 DCHECK(read_cb_.is_null()); // No Read() before initialization finished. 222 DCHECK(read_cb_.is_null()); // No Read() before initialization finished.
215 223
224 DVLOG(2) << "FinishInitialization()";
225
216 if (!stop_cb_.is_null()) { 226 if (!stop_cb_.is_null()) {
217 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 227 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
218 DoStop(); 228 DoStop();
219 return; 229 return;
220 } 230 }
221 231
222 if (!success) { 232 if (!success) {
223 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 233 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
224 state_ = kStopped; 234 state_ = kStopped;
225 return; 235 return;
226 } 236 }
227 237
228 // Success! 238 // Success!
229 state_ = kIdle; 239 state_ = kIdle;
230 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); 240 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
231 } 241 }
232 242
233 void DecryptingVideoDecoder::DoRead(const ReadCB& read_cb) { 243 void DecryptingVideoDecoder::DoRead(const ReadCB& read_cb) {
234 DCHECK(message_loop_->BelongsToCurrentThread()); 244 DCHECK(message_loop_->BelongsToCurrentThread());
235 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_; 245 DCHECK(state_ == kIdle || state_ == kDecodeFinished) << state_;
236 DCHECK(!read_cb.is_null()); 246 DCHECK(!read_cb.is_null());
237 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported."; 247 CHECK(read_cb_.is_null()) << "Overlapping decodes are not supported.";
238 248
249 DVLOG(3) << "DoRead()";
250
239 // Return empty frames if decoding has finished. 251 // Return empty frames if decoding has finished.
240 if (state_ == kDecodeFinished) { 252 if (state_ == kDecodeFinished) {
241 read_cb.Run(kOk, VideoFrame::CreateEmptyFrame()); 253 read_cb.Run(kOk, VideoFrame::CreateEmptyFrame());
242 return; 254 return;
243 } 255 }
244 256
245 read_cb_ = read_cb; 257 read_cb_ = read_cb;
246 state_ = kPendingDemuxerRead; 258 state_ = kPendingDemuxerRead;
247 ReadFromDemuxerStream(); 259 ReadFromDemuxerStream();
248 } 260 }
(...skipping 20 matching lines...) Expand all
269 } 281 }
270 282
271 void DecryptingVideoDecoder::DoDecryptAndDecodeBuffer( 283 void DecryptingVideoDecoder::DoDecryptAndDecodeBuffer(
272 DemuxerStream::Status status, 284 DemuxerStream::Status status,
273 const scoped_refptr<DecoderBuffer>& buffer) { 285 const scoped_refptr<DecoderBuffer>& buffer) {
274 DCHECK(message_loop_->BelongsToCurrentThread()); 286 DCHECK(message_loop_->BelongsToCurrentThread());
275 DCHECK_EQ(state_, kPendingDemuxerRead) << state_; 287 DCHECK_EQ(state_, kPendingDemuxerRead) << state_;
276 DCHECK(!read_cb_.is_null()); 288 DCHECK(!read_cb_.is_null());
277 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status; 289 DCHECK_EQ(buffer != NULL, status == DemuxerStream::kOk) << status;
278 290
291 DVLOG(3) << "DoDecryptAndDecodeBuffer()";
292
279 if (!reset_cb_.is_null() || !stop_cb_.is_null()) { 293 if (!reset_cb_.is_null() || !stop_cb_.is_null()) {
280 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 294 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
281 if (!reset_cb_.is_null()) 295 if (!reset_cb_.is_null())
282 DoReset(); 296 DoReset();
283 if (!stop_cb_.is_null()) 297 if (!stop_cb_.is_null())
284 DoStop(); 298 DoStop();
285 return; 299 return;
286 } 300 }
287 301
288 if (status == DemuxerStream::kAborted) { 302 if (status == DemuxerStream::kAborted) {
303 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kAborted";
304 state_ = kIdle;
289 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 305 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
290 state_ = kIdle;
291 return; 306 return;
292 } 307 }
293 308
294 if (status == DemuxerStream::kConfigChanged) { 309 if (status == DemuxerStream::kConfigChanged) {
295 // TODO(xhwang): Add config change support. 310 // TODO(xhwang): Add config change support.
296 // The |state_| is chosen to be kDecodeFinished here to be consistent with 311 // The |state_| is chosen to be kDecodeFinished here to be consistent with
297 // the implementation of FFmpegVideoDecoder. 312 // the implementation of FFmpegVideoDecoder.
313 DVLOG(2) << "DoDecryptAndDecodeBuffer() - kConfigChanged";
298 state_ = kDecodeFinished; 314 state_ = kDecodeFinished;
299 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL); 315 base::ResetAndReturn(&read_cb_).Run(kDecodeError, NULL);
300 return; 316 return;
301 } 317 }
302 318
303 DCHECK_EQ(status, DemuxerStream::kOk); 319 DCHECK_EQ(status, DemuxerStream::kOk);
304 pending_buffer_to_decode_ = buffer; 320 pending_buffer_to_decode_ = buffer;
305 state_ = kPendingDecode; 321 state_ = kPendingDecode;
306 DecodePendingBuffer(); 322 DecodePendingBuffer();
307 } 323 }
(...skipping 22 matching lines...) Expand all
330 346
331 void DecryptingVideoDecoder::DoDeliverFrame( 347 void DecryptingVideoDecoder::DoDeliverFrame(
332 int buffer_size, 348 int buffer_size,
333 Decryptor::Status status, 349 Decryptor::Status status,
334 const scoped_refptr<VideoFrame>& frame) { 350 const scoped_refptr<VideoFrame>& frame) {
335 DCHECK(message_loop_->BelongsToCurrentThread()); 351 DCHECK(message_loop_->BelongsToCurrentThread());
336 DCHECK_EQ(state_, kPendingDecode) << state_; 352 DCHECK_EQ(state_, kPendingDecode) << state_;
337 DCHECK(!read_cb_.is_null()); 353 DCHECK(!read_cb_.is_null());
338 DCHECK(pending_buffer_to_decode_); 354 DCHECK(pending_buffer_to_decode_);
339 355
356 DVLOG(3) << "DoDeliverFrame()";
357
340 bool need_to_try_again_if_nokey_is_returned = key_added_while_pending_decode_; 358 bool need_to_try_again_if_nokey_is_returned = key_added_while_pending_decode_;
341 key_added_while_pending_decode_ = false; 359 key_added_while_pending_decode_ = false;
342 360
343 if (!reset_cb_.is_null() || !stop_cb_.is_null()) { 361 if (!reset_cb_.is_null() || !stop_cb_.is_null()) {
344 pending_buffer_to_decode_ = NULL; 362 pending_buffer_to_decode_ = NULL;
345 base::ResetAndReturn(&read_cb_).Run(kOk, NULL); 363 base::ResetAndReturn(&read_cb_).Run(kOk, NULL);
346 if (!reset_cb_.is_null()) 364 if (!reset_cb_.is_null())
347 DoReset(); 365 DoReset();
348 if (!stop_cb_.is_null()) 366 if (!stop_cb_.is_null())
349 DoStop(); 367 DoStop();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 } 402 }
385 403
386 DCHECK_EQ(status, Decryptor::kSuccess); 404 DCHECK_EQ(status, Decryptor::kSuccess);
387 state_ = frame->IsEndOfStream() ? kDecodeFinished : kIdle; 405 state_ = frame->IsEndOfStream() ? kDecodeFinished : kIdle;
388 base::ResetAndReturn(&read_cb_).Run(kOk, frame); 406 base::ResetAndReturn(&read_cb_).Run(kOk, frame);
389 } 407 }
390 408
391 void DecryptingVideoDecoder::OnKeyAdded() { 409 void DecryptingVideoDecoder::OnKeyAdded() {
392 DCHECK(message_loop_->BelongsToCurrentThread()); 410 DCHECK(message_loop_->BelongsToCurrentThread());
393 411
412 DVLOG(2) << "OnKeyAdded()";
413
394 if (state_ == kPendingDecode) { 414 if (state_ == kPendingDecode) {
395 key_added_while_pending_decode_ = true; 415 key_added_while_pending_decode_ = true;
396 return; 416 return;
397 } 417 }
398 418
399 if (state_ == kWaitingForKey) { 419 if (state_ == kWaitingForKey) {
400 state_ = kPendingDecode; 420 state_ = kPendingDecode;
401 DecodePendingBuffer(); 421 DecodePendingBuffer();
402 } 422 }
403 } 423 }
404 424
405 void DecryptingVideoDecoder::DoReset() { 425 void DecryptingVideoDecoder::DoReset() {
406 DCHECK(init_cb_.is_null()); 426 DCHECK(init_cb_.is_null());
407 DCHECK(read_cb_.is_null()); 427 DCHECK(read_cb_.is_null());
408 state_ = kIdle; 428 state_ = kIdle;
409 base::ResetAndReturn(&reset_cb_).Run(); 429 base::ResetAndReturn(&reset_cb_).Run();
410 } 430 }
411 431
412 void DecryptingVideoDecoder::DoStop() { 432 void DecryptingVideoDecoder::DoStop() {
413 DCHECK(init_cb_.is_null()); 433 DCHECK(init_cb_.is_null());
414 DCHECK(read_cb_.is_null()); 434 DCHECK(read_cb_.is_null());
415 state_ = kStopped; 435 state_ = kStopped;
416 base::ResetAndReturn(&stop_cb_).Run(); 436 base::ResetAndReturn(&stop_cb_).Run();
417 } 437 }
418 438
419 } // namespace media 439 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | ppapi/cpp/private/content_decryptor_private.h » ('j') | ppapi/cpp/private/content_decryptor_private.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698