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