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 |