| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/cdm/cdm_adapter.h" | 5 #include "media/cdm/cdm_adapter.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback_helpers.h" | 11 #include "base/callback_helpers.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "base/thread_task_runner_handle.h" | 14 #include "base/thread_task_runner_handle.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "media/base/audio_decoder_config.h" | 16 #include "media/base/audio_decoder_config.h" |
| 17 #include "media/base/cdm_initialized_promise.h" | 17 #include "media/base/cdm_initialized_promise.h" |
| 18 #include "media/base/cdm_key_information.h" | 18 #include "media/base/cdm_key_information.h" |
| 19 #include "media/base/channel_layout.h" | 19 #include "media/base/channel_layout.h" |
| 20 #include "media/base/decoder_buffer.h" | 20 #include "media/base/decoder_buffer.h" |
| 21 #include "media/base/decrypt_config.h" | 21 #include "media/base/decrypt_config.h" |
| 22 #include "media/base/limits.h" | 22 #include "media/base/limits.h" |
| 23 #include "media/base/sample_format.h" | 23 #include "media/base/sample_format.h" |
| 24 #include "media/base/video_codecs.h" | 24 #include "media/base/video_codecs.h" |
| 25 #include "media/base/video_decoder_config.h" | 25 #include "media/base/video_decoder_config.h" |
| 26 #include "media/base/video_frame.h" | 26 #include "media/base/video_frame.h" |
| 27 #include "media/base/video_types.h" | 27 #include "media/base/video_types.h" |
| 28 #include "media/cdm/cdm_buffer_impl.h" | 28 #include "media/cdm/cdm_allocator.h" |
| 29 #include "media/cdm/cdm_helpers.h" | 29 #include "media/cdm/cdm_helpers.h" |
| 30 #include "media/cdm/cdm_wrapper.h" | 30 #include "media/cdm/cdm_wrapper.h" |
| 31 #include "ui/gfx/geometry/rect.h" | 31 #include "ui/gfx/geometry/rect.h" |
| 32 | 32 |
| 33 namespace media { | 33 namespace media { |
| 34 | 34 |
| 35 namespace { | 35 namespace { |
| 36 | 36 |
| 37 cdm::SessionType ToCdmSessionType(MediaKeys::SessionType session_type) { | 37 cdm::SessionType ToCdmSessionType(MediaKeys::SessionType session_type) { |
| 38 switch (session_type) { | 38 switch (session_type) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 } | 318 } |
| 319 } | 319 } |
| 320 | 320 |
| 321 } // namespace | 321 } // namespace |
| 322 | 322 |
| 323 // static | 323 // static |
| 324 void CdmAdapter::Create( | 324 void CdmAdapter::Create( |
| 325 const std::string& key_system, | 325 const std::string& key_system, |
| 326 const base::FilePath& cdm_path, | 326 const base::FilePath& cdm_path, |
| 327 const CdmConfig& cdm_config, | 327 const CdmConfig& cdm_config, |
| 328 scoped_ptr<CdmAllocator> allocator, |
| 328 const SessionMessageCB& session_message_cb, | 329 const SessionMessageCB& session_message_cb, |
| 329 const SessionClosedCB& session_closed_cb, | 330 const SessionClosedCB& session_closed_cb, |
| 330 const LegacySessionErrorCB& legacy_session_error_cb, | 331 const LegacySessionErrorCB& legacy_session_error_cb, |
| 331 const SessionKeysChangeCB& session_keys_change_cb, | 332 const SessionKeysChangeCB& session_keys_change_cb, |
| 332 const SessionExpirationUpdateCB& session_expiration_update_cb, | 333 const SessionExpirationUpdateCB& session_expiration_update_cb, |
| 333 const CdmCreatedCB& cdm_created_cb) { | 334 const CdmCreatedCB& cdm_created_cb) { |
| 334 DCHECK(!key_system.empty()); | 335 DCHECK(!key_system.empty()); |
| 335 DCHECK(!session_message_cb.is_null()); | 336 DCHECK(!session_message_cb.is_null()); |
| 336 DCHECK(!session_closed_cb.is_null()); | 337 DCHECK(!session_closed_cb.is_null()); |
| 337 DCHECK(!legacy_session_error_cb.is_null()); | 338 DCHECK(!legacy_session_error_cb.is_null()); |
| 338 DCHECK(!session_keys_change_cb.is_null()); | 339 DCHECK(!session_keys_change_cb.is_null()); |
| 339 DCHECK(!session_expiration_update_cb.is_null()); | 340 DCHECK(!session_expiration_update_cb.is_null()); |
| 340 | 341 |
| 341 scoped_refptr<CdmAdapter> cdm = | 342 scoped_refptr<CdmAdapter> cdm = new CdmAdapter( |
| 342 new CdmAdapter(key_system, cdm_config, session_message_cb, | 343 key_system, cdm_config, std::move(allocator), session_message_cb, |
| 343 session_closed_cb, legacy_session_error_cb, | 344 session_closed_cb, legacy_session_error_cb, session_keys_change_cb, |
| 344 session_keys_change_cb, session_expiration_update_cb); | 345 session_expiration_update_cb); |
| 345 | 346 |
| 346 // |cdm| ownership passed to the promise. | 347 // |cdm| ownership passed to the promise. |
| 347 scoped_ptr<CdmInitializedPromise> cdm_created_promise( | 348 scoped_ptr<CdmInitializedPromise> cdm_created_promise( |
| 348 new CdmInitializedPromise(cdm_created_cb, cdm)); | 349 new CdmInitializedPromise(cdm_created_cb, cdm)); |
| 349 | 350 |
| 350 cdm->Initialize(cdm_path, std::move(cdm_created_promise)); | 351 cdm->Initialize(cdm_path, std::move(cdm_created_promise)); |
| 351 } | 352 } |
| 352 | 353 |
| 353 CdmAdapter::CdmAdapter( | 354 CdmAdapter::CdmAdapter( |
| 354 const std::string& key_system, | 355 const std::string& key_system, |
| 355 const CdmConfig& cdm_config, | 356 const CdmConfig& cdm_config, |
| 357 scoped_ptr<CdmAllocator> allocator, |
| 356 const SessionMessageCB& session_message_cb, | 358 const SessionMessageCB& session_message_cb, |
| 357 const SessionClosedCB& session_closed_cb, | 359 const SessionClosedCB& session_closed_cb, |
| 358 const LegacySessionErrorCB& legacy_session_error_cb, | 360 const LegacySessionErrorCB& legacy_session_error_cb, |
| 359 const SessionKeysChangeCB& session_keys_change_cb, | 361 const SessionKeysChangeCB& session_keys_change_cb, |
| 360 const SessionExpirationUpdateCB& session_expiration_update_cb) | 362 const SessionExpirationUpdateCB& session_expiration_update_cb) |
| 361 : key_system_(key_system), | 363 : key_system_(key_system), |
| 362 cdm_config_(cdm_config), | 364 cdm_config_(cdm_config), |
| 363 session_message_cb_(session_message_cb), | 365 session_message_cb_(session_message_cb), |
| 364 session_closed_cb_(session_closed_cb), | 366 session_closed_cb_(session_closed_cb), |
| 365 legacy_session_error_cb_(legacy_session_error_cb), | 367 legacy_session_error_cb_(legacy_session_error_cb), |
| 366 session_keys_change_cb_(session_keys_change_cb), | 368 session_keys_change_cb_(session_keys_change_cb), |
| 367 session_expiration_update_cb_(session_expiration_update_cb), | 369 session_expiration_update_cb_(session_expiration_update_cb), |
| 368 audio_samples_per_second_(0), | 370 audio_samples_per_second_(0), |
| 369 audio_channel_layout_(CHANNEL_LAYOUT_NONE), | 371 audio_channel_layout_(CHANNEL_LAYOUT_NONE), |
| 372 allocator_(std::move(allocator)), |
| 370 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 373 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 371 weak_factory_(this) { | 374 weak_factory_(this) { |
| 372 DCHECK(!key_system_.empty()); | 375 DCHECK(!key_system_.empty()); |
| 373 DCHECK(!session_message_cb_.is_null()); | 376 DCHECK(!session_message_cb_.is_null()); |
| 374 DCHECK(!session_closed_cb_.is_null()); | 377 DCHECK(!session_closed_cb_.is_null()); |
| 375 DCHECK(!legacy_session_error_cb_.is_null()); | 378 DCHECK(!legacy_session_error_cb_.is_null()); |
| 376 DCHECK(!session_keys_change_cb_.is_null()); | 379 DCHECK(!session_keys_change_cb_.is_null()); |
| 377 DCHECK(!session_expiration_update_cb_.is_null()); | 380 DCHECK(!session_expiration_update_cb_.is_null()); |
| 381 DCHECK(allocator_); |
| 378 } | 382 } |
| 379 | 383 |
| 380 CdmAdapter::~CdmAdapter() {} | 384 CdmAdapter::~CdmAdapter() {} |
| 381 | 385 |
| 382 CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system, | 386 CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system, |
| 383 const base::FilePath& cdm_path) { | 387 const base::FilePath& cdm_path) { |
| 384 DCHECK(task_runner_->BelongsToCurrentThread()); | 388 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 385 | 389 |
| 386 // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and | 390 // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and |
| 387 // DeinitializeCdmModule(). However, that should only be done once for the | 391 // DeinitializeCdmModule(). However, that should only be done once for the |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 | 660 |
| 657 void CdmAdapter::DecryptAndDecodeVideo( | 661 void CdmAdapter::DecryptAndDecodeVideo( |
| 658 const scoped_refptr<DecoderBuffer>& encrypted, | 662 const scoped_refptr<DecoderBuffer>& encrypted, |
| 659 const VideoDecodeCB& video_decode_cb) { | 663 const VideoDecodeCB& video_decode_cb) { |
| 660 DCHECK(task_runner_->BelongsToCurrentThread()); | 664 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 661 DVLOG(3) << __FUNCTION__ | 665 DVLOG(3) << __FUNCTION__ |
| 662 << " encrypted: " << encrypted->AsHumanReadableString(); | 666 << " encrypted: " << encrypted->AsHumanReadableString(); |
| 663 | 667 |
| 664 cdm::InputBuffer input_buffer; | 668 cdm::InputBuffer input_buffer; |
| 665 std::vector<cdm::SubsampleEntry> subsamples; | 669 std::vector<cdm::SubsampleEntry> subsamples; |
| 666 scoped_ptr<VideoFrameImpl> video_frame(new VideoFrameImpl()); | 670 scoped_ptr<VideoFrameImpl> video_frame = allocator_->CreateCdmVideoFrame(); |
| 667 | 671 |
| 668 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); | 672 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); |
| 669 cdm::Status status = | 673 cdm::Status status = |
| 670 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); | 674 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); |
| 671 | 675 |
| 672 if (status != cdm::kSuccess) { | 676 if (status != cdm::kSuccess) { |
| 673 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; | 677 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; |
| 674 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr); | 678 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr); |
| 675 return; | 679 return; |
| 676 } | 680 } |
| 677 | 681 |
| 678 uint8_t* frame_data = video_frame->FrameBuffer()->Data(); | 682 scoped_refptr<VideoFrame> decoded_frame = |
| 679 gfx::Size frame_size(video_frame->Size().width, video_frame->Size().height); | 683 video_frame->TransformToVideoFrame(natural_size_); |
| 680 scoped_refptr<VideoFrame> decoded_frame = VideoFrame::WrapExternalYuvData( | |
| 681 PIXEL_FORMAT_YV12, frame_size, gfx::Rect(frame_size), natural_size_, | |
| 682 video_frame->Stride(VideoFrameImpl::kYPlane), | |
| 683 video_frame->Stride(VideoFrameImpl::kUPlane), | |
| 684 video_frame->Stride(VideoFrameImpl::kVPlane), | |
| 685 frame_data + video_frame->PlaneOffset(VideoFrameImpl::kYPlane), | |
| 686 frame_data + video_frame->PlaneOffset(VideoFrameImpl::kUPlane), | |
| 687 frame_data + video_frame->PlaneOffset(VideoFrameImpl::kVPlane), | |
| 688 base::TimeDelta::FromMicroseconds(video_frame->Timestamp())); | |
| 689 video_decode_cb.Run(Decryptor::kSuccess, decoded_frame); | 684 video_decode_cb.Run(Decryptor::kSuccess, decoded_frame); |
| 690 } | 685 } |
| 691 | 686 |
| 692 void CdmAdapter::ResetDecoder(StreamType stream_type) { | 687 void CdmAdapter::ResetDecoder(StreamType stream_type) { |
| 693 DCHECK(task_runner_->BelongsToCurrentThread()); | 688 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 694 cdm_->ResetDecoder(ToCdmStreamType(stream_type)); | 689 cdm_->ResetDecoder(ToCdmStreamType(stream_type)); |
| 695 } | 690 } |
| 696 | 691 |
| 697 void CdmAdapter::DeinitializeDecoder(StreamType stream_type) { | 692 void CdmAdapter::DeinitializeDecoder(StreamType stream_type) { |
| 698 DCHECK(task_runner_->BelongsToCurrentThread()); | 693 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 699 cdm_->DeinitializeDecoder(ToCdmStreamType(stream_type)); | 694 cdm_->DeinitializeDecoder(ToCdmStreamType(stream_type)); |
| 700 | 695 |
| 701 // Reset the saved values from initializing the decoder. | 696 // Reset the saved values from initializing the decoder. |
| 702 switch (stream_type) { | 697 switch (stream_type) { |
| 703 case Decryptor::kAudio: | 698 case Decryptor::kAudio: |
| 704 audio_samples_per_second_ = 0; | 699 audio_samples_per_second_ = 0; |
| 705 audio_channel_layout_ = CHANNEL_LAYOUT_NONE; | 700 audio_channel_layout_ = CHANNEL_LAYOUT_NONE; |
| 706 break; | 701 break; |
| 707 case Decryptor::kVideo: | 702 case Decryptor::kVideo: |
| 708 natural_size_ = gfx::Size(); | 703 natural_size_ = gfx::Size(); |
| 709 break; | 704 break; |
| 710 } | 705 } |
| 711 } | 706 } |
| 712 | 707 |
| 713 cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) { | 708 cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) { |
| 714 DCHECK(task_runner_->BelongsToCurrentThread()); | 709 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 715 return CdmBuffer::Create(capacity); | 710 return allocator_->CreateCdmBuffer(capacity); |
| 716 } | 711 } |
| 717 | 712 |
| 718 void CdmAdapter::SetTimer(int64_t delay_ms, void* context) { | 713 void CdmAdapter::SetTimer(int64_t delay_ms, void* context) { |
| 719 DCHECK(task_runner_->BelongsToCurrentThread()); | 714 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 720 task_runner_->PostDelayedTask(FROM_HERE, | 715 task_runner_->PostDelayedTask(FROM_HERE, |
| 721 base::Bind(&CdmAdapter::TimerExpired, | 716 base::Bind(&CdmAdapter::TimerExpired, |
| 722 weak_factory_.GetWeakPtr(), context), | 717 weak_factory_.GetWeakPtr(), context), |
| 723 base::TimeDelta::FromMilliseconds(delay_ms)); | 718 base::TimeDelta::FromMilliseconds(delay_ms)); |
| 724 } | 719 } |
| 725 | 720 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 result_frames->push_back(frame); | 946 result_frames->push_back(frame); |
| 952 | 947 |
| 953 data += frame_size; | 948 data += frame_size; |
| 954 bytes_left -= frame_size; | 949 bytes_left -= frame_size; |
| 955 } while (bytes_left > 0); | 950 } while (bytes_left > 0); |
| 956 | 951 |
| 957 return true; | 952 return true; |
| 958 } | 953 } |
| 959 | 954 |
| 960 } // namespace media | 955 } // namespace media |
| OLD | NEW |