| 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_) { |
| 359 if (!video_decoder_) | 359 video_decoder_ = CreateVideoDecoder(allocator_, video_decoder_config); |
| 360 video_decoder_.reset(new webkit_media::FFmpegCdmVideoDecoder(allocator_)); | 360 if (!video_decoder_) |
| 361 | 361 return cdm::kSessionError; |
| 362 if (!video_decoder_->Initialize(video_decoder_config)) | 362 } |
| 363 return cdm::kSessionError; | |
| 364 | 363 |
| 365 return cdm::kSuccess; | 364 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 } | 365 } |
| 374 | 366 |
| 375 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { | 367 void ClearKeyCdm::ResetDecoder(cdm::StreamType decoder_type) { |
| 376 DVLOG(1) << "ResetDecoder()"; | 368 DVLOG(1) << "ResetDecoder()"; |
| 377 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | 369 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) |
| 378 switch (decoder_type) { | 370 switch (decoder_type) { |
| 379 case cdm::kStreamTypeVideo: | 371 case cdm::kStreamTypeVideo: |
| 380 video_decoder_->Reset(); | 372 video_decoder_->Reset(); |
| 381 break; | 373 break; |
| 382 case cdm::kStreamTypeAudio: | 374 case cdm::kStreamTypeAudio: |
| 383 audio_decoder_->Reset(); | 375 audio_decoder_->Reset(); |
| 384 break; | 376 break; |
| 385 default: | 377 default: |
| 386 NOTREACHED() << "ResetDecoder(): invalid cdm::StreamType"; | 378 NOTREACHED() << "ResetDecoder(): invalid cdm::StreamType"; |
| 387 } | 379 } |
| 388 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 380 #elif defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
| 389 if (decoder_type == cdm::kStreamTypeAudio) { | 381 if (decoder_type == cdm::kStreamTypeAudio) { |
| 390 output_timestamp_base_in_microseconds_ = kNoTimestamp; | 382 output_timestamp_base_in_microseconds_ = kNoTimestamp; |
| 391 total_samples_generated_ = 0; | 383 total_samples_generated_ = 0; |
| 392 } | 384 } |
| 393 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER | 385 #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER |
| 394 } | 386 } |
| 395 | 387 |
| 396 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { | 388 void ClearKeyCdm::DeinitializeDecoder(cdm::StreamType decoder_type) { |
| 397 DVLOG(1) << "DeinitializeDecoder()"; | 389 DVLOG(1) << "DeinitializeDecoder()"; |
| 398 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | |
| 399 switch (decoder_type) { | 390 switch (decoder_type) { |
| 400 case cdm::kStreamTypeVideo: | 391 case cdm::kStreamTypeVideo: |
| 401 video_decoder_->Deinitialize(); | 392 video_decoder_->Deinitialize(); |
| 402 break; | 393 break; |
| 403 case cdm::kStreamTypeAudio: | 394 case cdm::kStreamTypeAudio: |
| 395 #if !defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
| 404 audio_decoder_->Deinitialize(); | 396 audio_decoder_->Deinitialize(); |
| 397 #else |
| 398 output_timestamp_base_in_microseconds_ = kNoTimestamp; |
| 399 total_samples_generated_ = 0; |
| 400 #endif |
| 405 break; | 401 break; |
| 406 default: | 402 default: |
| 407 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType"; | 403 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType"; |
| 408 } | 404 } |
| 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 } | 405 } |
| 416 | 406 |
| 417 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( | 407 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( |
| 418 const cdm::InputBuffer& encrypted_buffer, | 408 const cdm::InputBuffer& encrypted_buffer, |
| 419 cdm::VideoFrame* decoded_frame) { | 409 cdm::VideoFrame* decoded_frame) { |
| 420 DVLOG(1) << "DecryptAndDecodeFrame()"; | 410 DVLOG(1) << "DecryptAndDecodeFrame()"; |
| 421 TRACE_EVENT0("eme", "ClearKeyCdm::DecryptAndDecodeFrame"); | 411 TRACE_EVENT0("eme", "ClearKeyCdm::DecryptAndDecodeFrame"); |
| 422 | 412 |
| 423 scoped_refptr<media::DecoderBuffer> buffer; | 413 scoped_refptr<media::DecoderBuffer> buffer; |
| 424 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); | 414 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); |
| 425 | 415 |
| 426 if (status != cdm::kSuccess) | 416 if (status != cdm::kSuccess) |
| 427 return status; | 417 return status; |
| 428 | 418 |
| 429 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) | |
| 430 DCHECK(status == cdm::kSuccess); | 419 DCHECK(status == cdm::kSuccess); |
| 431 DCHECK(buffer); | 420 DCHECK(buffer); |
| 432 return video_decoder_->DecodeFrame(buffer.get()->GetData(), | 421 return video_decoder_->DecodeFrame(buffer.get()->GetData(), |
| 433 buffer->GetDataSize(), | 422 buffer->GetDataSize(), |
| 434 encrypted_buffer.timestamp, | 423 encrypted_buffer.timestamp, |
| 435 decoded_frame); | 424 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 } | 425 } |
| 449 | 426 |
| 450 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( | 427 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( |
| 451 const cdm::InputBuffer& encrypted_buffer, | 428 const cdm::InputBuffer& encrypted_buffer, |
| 452 cdm::AudioFrames* audio_frames) { | 429 cdm::AudioFrames* audio_frames) { |
| 453 DVLOG(1) << "DecryptAndDecodeSamples()"; | 430 DVLOG(1) << "DecryptAndDecodeSamples()"; |
| 454 | 431 |
| 455 scoped_refptr<media::DecoderBuffer> buffer; | 432 scoped_refptr<media::DecoderBuffer> buffer; |
| 456 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); | 433 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); |
| 457 | 434 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 | 533 |
| 557 int samples_generated = GenerateFakeAudioFramesFromDuration( | 534 int samples_generated = GenerateFakeAudioFramesFromDuration( |
| 558 timestamp_in_microseconds - CurrentTimeStampInMicroseconds(), | 535 timestamp_in_microseconds - CurrentTimeStampInMicroseconds(), |
| 559 audio_frames); | 536 audio_frames); |
| 560 total_samples_generated_ += samples_generated; | 537 total_samples_generated_ += samples_generated; |
| 561 | 538 |
| 562 return samples_generated == 0 ? cdm::kNeedMoreData : cdm::kSuccess; | 539 return samples_generated == 0 ? cdm::kNeedMoreData : cdm::kSuccess; |
| 563 } | 540 } |
| 564 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER | 541 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER |
| 565 | 542 |
| 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 | 543 } // namespace webkit_media |
| OLD | NEW |