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 "webkit/media/crypto/ppapi/clear_key_cdm.h" | 5 #include "webkit/media/crypto/ppapi/clear_key_cdm.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <sstream> | 8 #include <sstream> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
348 samples_per_second_ = audio_decoder_config.samples_per_second; | 348 samples_per_second_ = audio_decoder_config.samples_per_second; |
349 return cdm::kSuccess; | 349 return cdm::kSuccess; |
350 #else | 350 #else |
351 NOTIMPLEMENTED(); | 351 NOTIMPLEMENTED(); |
352 return cdm::kSessionError; | 352 return cdm::kSessionError; |
353 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | 353 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER |
354 } | 354 } |
355 | 355 |
356 cdm::Status ClearKeyCdm::InitializeVideoDecoder( | 356 cdm::Status ClearKeyCdm::InitializeVideoDecoder( |
357 const cdm::VideoDecoderConfig& video_decoder_config) { | 357 const cdm::VideoDecoderConfig& video_decoder_config) { |
358 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 358 if (video_decoder_ && video_decoder_->is_initialized()) |
ddorwin
2012/12/04 22:38:15
I'm not familiar with this logic. xhwang, is this
xhwang
2012/12/04 23:07:46
Hmm, shouldn't we DCHECK(!video_decoder_->is_initi
Tom Finegan
2012/12/04 23:17:39
Done.
| |
359 return cdm::kSessionError; | |
360 | |
361 video_decoder_ = CreateVideoDecoder(allocator_, video_decoder_config); | |
ddorwin
2012/12/04 22:38:15
// Any uninitialized decoder will be replaced.
Tom Finegan
2012/12/04 23:17:39
Done.
| |
359 if (!video_decoder_) | 362 if (!video_decoder_) |
360 video_decoder_.reset(new webkit_media::FFmpegCdmVideoDecoder(allocator_)); | |
361 | |
362 if (!video_decoder_->Initialize(video_decoder_config)) | |
363 return cdm::kSessionError; | 363 return cdm::kSessionError; |
364 | 364 |
365 return cdm::kSuccess; | 365 return cdm::kSuccess; |
366 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | |
367 video_size_ = video_decoder_config.coded_size; | |
368 return cdm::kSuccess; | |
369 #else | |
370 NOTIMPLEMENTED(); | |
371 return cdm::kSessionError; | |
372 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | |
373 } | 366 } |
374 | 367 |
375 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { | 368 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { |
376 DVLOG(1) << "ResetDecoder()"; | 369 DVLOG(1) << "ResetDecoder()"; |
377 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 370 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) |
378 switch (decoder_type) { | 371 switch (decoder_type) { |
379 case cdm::kStreamTypeVideo: | 372 case cdm::kStreamTypeVideo: |
380 video_decoder_->Reset(); | 373 video_decoder_->Reset(); |
381 break; | 374 break; |
382 case cdm::kStreamTypeAudio: | 375 case cdm::kStreamTypeAudio: |
383 audio_decoder_->Reset(); | 376 audio_decoder_->Reset(); |
384 break; | 377 break; |
385 default: | 378 default: |
386 NOTREACHED() << "ResetDecoder(): invalid cdm::StreamType"; | 379 NOTREACHED() << "ResetDecoder(): invalid cdm::StreamType"; |
387 } | 380 } |
388 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 381 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
389 if (decoder_type == cdm::kStreamTypeAudio) { | 382 if (decoder_type == cdm::kStreamTypeAudio) { |
390 output_timestamp_base_in_microseconds_ = kNoTimestamp; | 383 output_timestamp_base_in_microseconds_ = kNoTimestamp; |
391 total_samples_generated_ = 0; | 384 total_samples_generated_ = 0; |
392 } | 385 } |
393 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | 386 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER |
394 } | 387 } |
395 | 388 |
396 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { | 389 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { |
397 DVLOG(1) << "DeinitializeDecoder()"; | 390 DVLOG(1) << "DeinitializeDecoder()"; |
398 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | |
399 switch (decoder_type) { | 391 switch (decoder_type) { |
400 case cdm::kStreamTypeVideo: | 392 case cdm::kStreamTypeVideo: |
401 video_decoder_->Deinitialize(); | 393 video_decoder_->Deinitialize(); |
402 break; | 394 break; |
403 case cdm::kStreamTypeAudio: | 395 case cdm::kStreamTypeAudio: |
396 #if !defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | |
404 audio_decoder_->Deinitialize(); | 397 audio_decoder_->Deinitialize(); |
398 #else | |
399 output_timestamp_base_in_microseconds_ = kNoTimestamp; | |
400 total_samples_generated_ = 0; | |
401 #endif | |
405 break; | 402 break; |
406 default: | 403 default: |
407 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType"; | 404 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType"; |
408 } | 405 } |
409 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | |
410 if (decoder_type == cdm::kStreamTypeAudio) { | |
411 output_timestamp_base_in_microseconds_ = kNoTimestamp; | |
412 total_samples_generated_ = 0; | |
413 } | |
414 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | |
415 } | 406 } |
416 | 407 |
417 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( | 408 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( |
418 const cdm::InputBuffer& encrypted_buffer, | 409 const cdm::InputBuffer& encrypted_buffer, |
419 cdm::VideoFrame* decoded_frame) { | 410 cdm::VideoFrame* decoded_frame) { |
420 DVLOG(1) << "DecryptAndDecodeFrame()"; | 411 DVLOG(1) << "DecryptAndDecodeFrame()"; |
421 TRACE_EVENT0("eme", "ClearKeyCdm::DecryptAndDecodeFrame"); | 412 TRACE_EVENT0("eme", "ClearKeyCdm::DecryptAndDecodeFrame"); |
422 | 413 |
423 scoped_refptr<media::DecoderBuffer> buffer; | 414 scoped_refptr<media::DecoderBuffer> buffer; |
424 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); | 415 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); |
425 | 416 |
426 if (status != cdm::kSuccess) | 417 if (status != cdm::kSuccess) |
427 return status; | 418 return status; |
428 | 419 |
429 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | |
430 DCHECK(status == cdm::kSuccess); | 420 DCHECK(status == cdm::kSuccess); |
431 DCHECK(buffer); | 421 DCHECK(buffer); |
432 return video_decoder_->DecodeFrame(buffer.get()->GetData(), | 422 return video_decoder_->DecodeFrame(buffer.get()->GetData(), |
433 buffer->GetDataSize(), | 423 buffer->GetDataSize(), |
434 encrypted_buffer.timestamp, | 424 encrypted_buffer.timestamp, |
435 decoded_frame); | 425 decoded_frame); |
436 #elif defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | |
437 // The fake decoder does not buffer any frames internally. So if the input is | |
438 // empty (EOS), just return kNeedMoreData. | |
439 if (buffer->IsEndOfStream()) | |
440 return cdm::kNeedMoreData; | |
441 | |
442 GenerateFakeVideoFrame(buffer->GetTimestamp(), decoded_frame); | |
443 return cdm::kSuccess; | |
444 #else | |
445 NOTIMPLEMENTED(); | |
446 return cdm::kDecodeError; | |
447 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | |
448 } | 426 } |
449 | 427 |
450 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( | 428 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( |
451 const cdm::InputBuffer& encrypted_buffer, | 429 const cdm::InputBuffer& encrypted_buffer, |
452 cdm::AudioFrames* audio_frames) { | 430 cdm::AudioFrames* audio_frames) { |
453 DVLOG(1) << "DecryptAndDecodeSamples()"; | 431 DVLOG(1) << "DecryptAndDecodeSamples()"; |
454 | 432 |
455 scoped_refptr<media::DecoderBuffer> buffer; | 433 scoped_refptr<media::DecoderBuffer> buffer; |
456 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); | 434 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); |
457 | 435 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
556 | 534 |
557 int samples_generated = GenerateFakeAudioFramesFromDuration( | 535 int samples_generated = GenerateFakeAudioFramesFromDuration( |
558 timestamp_in_microseconds - CurrentTimeStampInMicroseconds(), | 536 timestamp_in_microseconds - CurrentTimeStampInMicroseconds(), |
559 audio_frames); | 537 audio_frames); |
560 total_samples_generated_ += samples_generated; | 538 total_samples_generated_ += samples_generated; |
561 | 539 |
562 return samples_generated == 0 ? cdm::kNeedMoreData : cdm::kSuccess; | 540 return samples_generated == 0 ? cdm::kNeedMoreData : cdm::kSuccess; |
563 } | 541 } |
564 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER | 542 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER |
565 | 543 |
566 #if defined(CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER) | |
567 void ClearKeyCdm::GenerateFakeVideoFrame(base::TimeDelta timestamp, | |
568 cdm::VideoFrame* video_frame) { | |
569 // Choose non-zero alignment and padding on purpose for testing. | |
570 const int kAlignment = 8; | |
571 const int kPadding = 16; | |
572 const int kPlanePadding = 128; | |
573 | |
574 int width = video_size_.width; | |
575 int height = video_size_.height; | |
576 DCHECK_EQ(width % 2, 0); | |
577 DCHECK_EQ(height % 2, 0); | |
578 | |
579 int y_stride = (width + kAlignment - 1) / kAlignment * kAlignment + kPadding; | |
580 int uv_stride = | |
581 (width / 2 + kAlignment - 1) / kAlignment * kAlignment + kPadding; | |
582 int y_rows = height; | |
583 int uv_rows = height / 2; | |
584 int y_offset = 0; | |
585 int v_offset = y_stride * y_rows + kPlanePadding; | |
586 int u_offset = v_offset + uv_stride * uv_rows + kPlanePadding; | |
587 int frame_size = u_offset + uv_stride * uv_rows + kPlanePadding; | |
588 | |
589 video_frame->set_format(cdm::kYv12); | |
590 video_frame->set_size(video_size_); | |
591 video_frame->set_frame_buffer(allocator_->Allocate(frame_size)); | |
592 video_frame->set_plane_offset(cdm::VideoFrame::kYPlane, y_offset); | |
593 video_frame->set_plane_offset(cdm::VideoFrame::kVPlane, v_offset); | |
594 video_frame->set_plane_offset(cdm::VideoFrame::kUPlane, u_offset); | |
595 video_frame->set_stride(cdm::VideoFrame::kYPlane, y_stride); | |
596 video_frame->set_stride(cdm::VideoFrame::kVPlane, uv_stride); | |
597 video_frame->set_stride(cdm::VideoFrame::kUPlane, uv_stride); | |
598 video_frame->set_timestamp(timestamp.InMicroseconds()); | |
599 | |
600 static unsigned char color = 0; | |
601 color += 10; | |
602 | |
603 memset(reinterpret_cast<void*>(video_frame->frame_buffer()->data()), | |
604 color, frame_size); | |
605 } | |
606 #endif // CLEAR_KEY_CDM_USE_FAKE_VIDEO_DECODER | |
607 | |
608 } // namespace webkit_media | 544 } // namespace webkit_media |
OLD | NEW |