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_buffer.h" |
29 #include "media/cdm/cdm_buffer_allocator.h" | |
29 #include "media/cdm/cdm_helpers.h" | 30 #include "media/cdm/cdm_helpers.h" |
30 #include "media/cdm/cdm_wrapper.h" | 31 #include "media/cdm/cdm_wrapper.h" |
31 #include "ui/gfx/geometry/rect.h" | 32 #include "ui/gfx/geometry/rect.h" |
32 | 33 |
33 namespace media { | 34 namespace media { |
34 | 35 |
35 namespace { | 36 namespace { |
36 | 37 |
37 cdm::SessionType ToCdmSessionType(MediaKeys::SessionType session_type) { | 38 cdm::SessionType ToCdmSessionType(MediaKeys::SessionType session_type) { |
38 switch (session_type) { | 39 switch (session_type) { |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 // static | 324 // static |
324 void CdmAdapter::Create( | 325 void CdmAdapter::Create( |
325 const std::string& key_system, | 326 const std::string& key_system, |
326 const base::FilePath& cdm_path, | 327 const base::FilePath& cdm_path, |
327 const CdmConfig& cdm_config, | 328 const CdmConfig& cdm_config, |
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, |
335 CdmBufferAllocator* allocator) { | |
xhwang
2016/02/09 18:27:32
who owns the allocator?
xhwang
2016/02/09 18:27:32
The |allocator| seems an input, while the callback
jrummell
2016/02/11 01:39:38
Done.
jrummell
2016/02/11 01:39:38
Changed to scoped_ptr<> to be clear.
| |
334 DCHECK(!key_system.empty()); | 336 DCHECK(!key_system.empty()); |
335 DCHECK(!session_message_cb.is_null()); | 337 DCHECK(!session_message_cb.is_null()); |
336 DCHECK(!session_closed_cb.is_null()); | 338 DCHECK(!session_closed_cb.is_null()); |
337 DCHECK(!legacy_session_error_cb.is_null()); | 339 DCHECK(!legacy_session_error_cb.is_null()); |
338 DCHECK(!session_keys_change_cb.is_null()); | 340 DCHECK(!session_keys_change_cb.is_null()); |
339 DCHECK(!session_expiration_update_cb.is_null()); | 341 DCHECK(!session_expiration_update_cb.is_null()); |
340 | 342 |
341 scoped_refptr<CdmAdapter> cdm = | 343 scoped_refptr<CdmAdapter> cdm = new CdmAdapter( |
342 new CdmAdapter(key_system, cdm_config, session_message_cb, | 344 key_system, cdm_config, session_message_cb, session_closed_cb, |
343 session_closed_cb, legacy_session_error_cb, | 345 legacy_session_error_cb, session_keys_change_cb, |
344 session_keys_change_cb, session_expiration_update_cb); | 346 session_expiration_update_cb, allocator); |
345 | 347 |
346 // |cdm| ownership passed to the promise. | 348 // |cdm| ownership passed to the promise. |
347 scoped_ptr<CdmInitializedPromise> cdm_created_promise( | 349 scoped_ptr<CdmInitializedPromise> cdm_created_promise( |
348 new CdmInitializedPromise(cdm_created_cb, cdm)); | 350 new CdmInitializedPromise(cdm_created_cb, cdm)); |
349 | 351 |
350 cdm->Initialize(cdm_path, std::move(cdm_created_promise)); | 352 cdm->Initialize(cdm_path, std::move(cdm_created_promise)); |
351 } | 353 } |
352 | 354 |
353 CdmAdapter::CdmAdapter( | 355 CdmAdapter::CdmAdapter( |
354 const std::string& key_system, | 356 const std::string& key_system, |
355 const CdmConfig& cdm_config, | 357 const CdmConfig& cdm_config, |
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, |
363 CdmBufferAllocator* allocator) | |
361 : key_system_(key_system), | 364 : key_system_(key_system), |
362 cdm_config_(cdm_config), | 365 cdm_config_(cdm_config), |
363 session_message_cb_(session_message_cb), | 366 session_message_cb_(session_message_cb), |
364 session_closed_cb_(session_closed_cb), | 367 session_closed_cb_(session_closed_cb), |
365 legacy_session_error_cb_(legacy_session_error_cb), | 368 legacy_session_error_cb_(legacy_session_error_cb), |
366 session_keys_change_cb_(session_keys_change_cb), | 369 session_keys_change_cb_(session_keys_change_cb), |
367 session_expiration_update_cb_(session_expiration_update_cb), | 370 session_expiration_update_cb_(session_expiration_update_cb), |
368 audio_samples_per_second_(0), | 371 audio_samples_per_second_(0), |
369 audio_channel_layout_(CHANNEL_LAYOUT_NONE), | 372 audio_channel_layout_(CHANNEL_LAYOUT_NONE), |
373 allocator_(allocator), | |
370 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 374 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
371 weak_factory_(this) { | 375 weak_factory_(this) { |
372 DCHECK(!key_system_.empty()); | 376 DCHECK(!key_system_.empty()); |
373 DCHECK(!session_message_cb_.is_null()); | 377 DCHECK(!session_message_cb_.is_null()); |
374 DCHECK(!session_closed_cb_.is_null()); | 378 DCHECK(!session_closed_cb_.is_null()); |
375 DCHECK(!legacy_session_error_cb_.is_null()); | 379 DCHECK(!legacy_session_error_cb_.is_null()); |
376 DCHECK(!session_keys_change_cb_.is_null()); | 380 DCHECK(!session_keys_change_cb_.is_null()); |
377 DCHECK(!session_expiration_update_cb_.is_null()); | 381 DCHECK(!session_expiration_update_cb_.is_null()); |
382 DCHECK(allocator_); | |
378 } | 383 } |
379 | 384 |
380 CdmAdapter::~CdmAdapter() {} | 385 CdmAdapter::~CdmAdapter() {} |
381 | 386 |
382 CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system, | 387 CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system, |
383 const base::FilePath& cdm_path) { | 388 const base::FilePath& cdm_path) { |
384 DCHECK(task_runner_->BelongsToCurrentThread()); | 389 DCHECK(task_runner_->BelongsToCurrentThread()); |
385 | 390 |
386 // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and | 391 // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and |
387 // DeinitializeCdmModule(). However, that should only be done once for the | 392 // DeinitializeCdmModule(). However, that should only be done once for the |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
668 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); | 673 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); |
669 cdm::Status status = | 674 cdm::Status status = |
670 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); | 675 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); |
671 | 676 |
672 if (status != cdm::kSuccess) { | 677 if (status != cdm::kSuccess) { |
673 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; | 678 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; |
674 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr); | 679 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr); |
675 return; | 680 return; |
676 } | 681 } |
677 | 682 |
678 uint8_t* frame_data = video_frame->FrameBuffer()->Data(); | 683 CdmBuffer* cdm_buffer = |
679 gfx::Size frame_size(video_frame->Size().width, video_frame->Size().height); | 684 reinterpret_cast<CdmBuffer*>(video_frame->FrameBuffer()); |
xhwang
2016/02/09 18:27:32
Can we do static cast?
jrummell
2016/02/11 01:39:38
Done (now moved elsewhere).
| |
680 scoped_refptr<VideoFrame> decoded_frame = VideoFrame::WrapExternalYuvData( | 685 scoped_refptr<VideoFrame> decoded_frame = |
681 PIXEL_FORMAT_YV12, frame_size, gfx::Rect(frame_size), natural_size_, | 686 cdm_buffer->MakeVideoFrame(video_frame.get(), 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); | 687 video_decode_cb.Run(Decryptor::kSuccess, decoded_frame); |
690 } | 688 } |
691 | 689 |
692 void CdmAdapter::ResetDecoder(StreamType stream_type) { | 690 void CdmAdapter::ResetDecoder(StreamType stream_type) { |
693 DCHECK(task_runner_->BelongsToCurrentThread()); | 691 DCHECK(task_runner_->BelongsToCurrentThread()); |
694 cdm_->ResetDecoder(ToCdmStreamType(stream_type)); | 692 cdm_->ResetDecoder(ToCdmStreamType(stream_type)); |
695 } | 693 } |
696 | 694 |
697 void CdmAdapter::DeinitializeDecoder(StreamType stream_type) { | 695 void CdmAdapter::DeinitializeDecoder(StreamType stream_type) { |
698 DCHECK(task_runner_->BelongsToCurrentThread()); | 696 DCHECK(task_runner_->BelongsToCurrentThread()); |
699 cdm_->DeinitializeDecoder(ToCdmStreamType(stream_type)); | 697 cdm_->DeinitializeDecoder(ToCdmStreamType(stream_type)); |
700 | 698 |
701 // Reset the saved values from initializing the decoder. | 699 // Reset the saved values from initializing the decoder. |
702 switch (stream_type) { | 700 switch (stream_type) { |
703 case Decryptor::kAudio: | 701 case Decryptor::kAudio: |
704 audio_samples_per_second_ = 0; | 702 audio_samples_per_second_ = 0; |
705 audio_channel_layout_ = CHANNEL_LAYOUT_NONE; | 703 audio_channel_layout_ = CHANNEL_LAYOUT_NONE; |
706 break; | 704 break; |
707 case Decryptor::kVideo: | 705 case Decryptor::kVideo: |
708 natural_size_ = gfx::Size(); | 706 natural_size_ = gfx::Size(); |
709 break; | 707 break; |
710 } | 708 } |
711 } | 709 } |
712 | 710 |
713 cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) { | 711 cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) { |
714 DCHECK(task_runner_->BelongsToCurrentThread()); | 712 DCHECK(task_runner_->BelongsToCurrentThread()); |
715 return CdmBuffer::Create(capacity); | 713 return allocator_->Allocate(capacity); |
716 } | 714 } |
717 | 715 |
718 void CdmAdapter::SetTimer(int64_t delay_ms, void* context) { | 716 void CdmAdapter::SetTimer(int64_t delay_ms, void* context) { |
719 DCHECK(task_runner_->BelongsToCurrentThread()); | 717 DCHECK(task_runner_->BelongsToCurrentThread()); |
720 task_runner_->PostDelayedTask(FROM_HERE, | 718 task_runner_->PostDelayedTask(FROM_HERE, |
721 base::Bind(&CdmAdapter::TimerExpired, | 719 base::Bind(&CdmAdapter::TimerExpired, |
722 weak_factory_.GetWeakPtr(), context), | 720 weak_factory_.GetWeakPtr(), context), |
723 base::TimeDelta::FromMilliseconds(delay_ms)); | 721 base::TimeDelta::FromMilliseconds(delay_ms)); |
724 } | 722 } |
725 | 723 |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
951 result_frames->push_back(frame); | 949 result_frames->push_back(frame); |
952 | 950 |
953 data += frame_size; | 951 data += frame_size; |
954 bytes_left -= frame_size; | 952 bytes_left -= frame_size; |
955 } while (bytes_left > 0); | 953 } while (bytes_left > 0); |
956 | 954 |
957 return true; | 955 return true; |
958 } | 956 } |
959 | 957 |
960 } // namespace media | 958 } // namespace media |
OLD | NEW |