Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: media/cdm/cdm_adapter.cc

Issue 1673383002: Add allocator interface for use by cdm_adapter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Simple classes Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
31 #include "media/cdm/cdm_video_frame.h"
30 #include "media/cdm/cdm_wrapper.h" 32 #include "media/cdm/cdm_wrapper.h"
31 #include "ui/gfx/geometry/rect.h" 33 #include "ui/gfx/geometry/rect.h"
32 34
33 namespace media { 35 namespace media {
34 36
35 namespace { 37 namespace {
36 38
37 cdm::SessionType ToCdmSessionType(MediaKeys::SessionType session_type) { 39 cdm::SessionType ToCdmSessionType(MediaKeys::SessionType session_type) {
38 switch (session_type) { 40 switch (session_type) {
39 case MediaKeys::TEMPORARY_SESSION: 41 case MediaKeys::TEMPORARY_SESSION:
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 } 320 }
319 } 321 }
320 322
321 } // namespace 323 } // namespace
322 324
323 // static 325 // static
324 void CdmAdapter::Create( 326 void CdmAdapter::Create(
325 const std::string& key_system, 327 const std::string& key_system,
326 const base::FilePath& cdm_path, 328 const base::FilePath& cdm_path,
327 const CdmConfig& cdm_config, 329 const CdmConfig& cdm_config,
330 scoped_ptr<CdmBufferAllocator> allocator,
328 const SessionMessageCB& session_message_cb, 331 const SessionMessageCB& session_message_cb,
329 const SessionClosedCB& session_closed_cb, 332 const SessionClosedCB& session_closed_cb,
330 const LegacySessionErrorCB& legacy_session_error_cb, 333 const LegacySessionErrorCB& legacy_session_error_cb,
331 const SessionKeysChangeCB& session_keys_change_cb, 334 const SessionKeysChangeCB& session_keys_change_cb,
332 const SessionExpirationUpdateCB& session_expiration_update_cb, 335 const SessionExpirationUpdateCB& session_expiration_update_cb,
333 const CdmCreatedCB& cdm_created_cb) { 336 const CdmCreatedCB& cdm_created_cb) {
334 DCHECK(!key_system.empty()); 337 DCHECK(!key_system.empty());
335 DCHECK(!session_message_cb.is_null()); 338 DCHECK(!session_message_cb.is_null());
336 DCHECK(!session_closed_cb.is_null()); 339 DCHECK(!session_closed_cb.is_null());
337 DCHECK(!legacy_session_error_cb.is_null()); 340 DCHECK(!legacy_session_error_cb.is_null());
338 DCHECK(!session_keys_change_cb.is_null()); 341 DCHECK(!session_keys_change_cb.is_null());
339 DCHECK(!session_expiration_update_cb.is_null()); 342 DCHECK(!session_expiration_update_cb.is_null());
340 343
341 scoped_refptr<CdmAdapter> cdm = 344 scoped_refptr<CdmAdapter> cdm = new CdmAdapter(
342 new CdmAdapter(key_system, cdm_config, session_message_cb, 345 key_system, cdm_config, std::move(allocator), session_message_cb,
343 session_closed_cb, legacy_session_error_cb, 346 session_closed_cb, legacy_session_error_cb, session_keys_change_cb,
344 session_keys_change_cb, session_expiration_update_cb); 347 session_expiration_update_cb);
345 348
346 // |cdm| ownership passed to the promise. 349 // |cdm| ownership passed to the promise.
347 scoped_ptr<CdmInitializedPromise> cdm_created_promise( 350 scoped_ptr<CdmInitializedPromise> cdm_created_promise(
348 new CdmInitializedPromise(cdm_created_cb, cdm)); 351 new CdmInitializedPromise(cdm_created_cb, cdm));
349 352
350 cdm->Initialize(cdm_path, std::move(cdm_created_promise)); 353 cdm->Initialize(cdm_path, std::move(cdm_created_promise));
351 } 354 }
352 355
353 CdmAdapter::CdmAdapter( 356 CdmAdapter::CdmAdapter(
354 const std::string& key_system, 357 const std::string& key_system,
355 const CdmConfig& cdm_config, 358 const CdmConfig& cdm_config,
359 scoped_ptr<CdmBufferAllocator> allocator,
356 const SessionMessageCB& session_message_cb, 360 const SessionMessageCB& session_message_cb,
357 const SessionClosedCB& session_closed_cb, 361 const SessionClosedCB& session_closed_cb,
358 const LegacySessionErrorCB& legacy_session_error_cb, 362 const LegacySessionErrorCB& legacy_session_error_cb,
359 const SessionKeysChangeCB& session_keys_change_cb, 363 const SessionKeysChangeCB& session_keys_change_cb,
360 const SessionExpirationUpdateCB& session_expiration_update_cb) 364 const SessionExpirationUpdateCB& session_expiration_update_cb)
361 : key_system_(key_system), 365 : key_system_(key_system),
362 cdm_config_(cdm_config), 366 cdm_config_(cdm_config),
363 session_message_cb_(session_message_cb), 367 session_message_cb_(session_message_cb),
364 session_closed_cb_(session_closed_cb), 368 session_closed_cb_(session_closed_cb),
365 legacy_session_error_cb_(legacy_session_error_cb), 369 legacy_session_error_cb_(legacy_session_error_cb),
366 session_keys_change_cb_(session_keys_change_cb), 370 session_keys_change_cb_(session_keys_change_cb),
367 session_expiration_update_cb_(session_expiration_update_cb), 371 session_expiration_update_cb_(session_expiration_update_cb),
368 audio_samples_per_second_(0), 372 audio_samples_per_second_(0),
369 audio_channel_layout_(CHANNEL_LAYOUT_NONE), 373 audio_channel_layout_(CHANNEL_LAYOUT_NONE),
374 allocator_(std::move(allocator)),
370 task_runner_(base::ThreadTaskRunnerHandle::Get()), 375 task_runner_(base::ThreadTaskRunnerHandle::Get()),
371 weak_factory_(this) { 376 weak_factory_(this) {
372 DCHECK(!key_system_.empty()); 377 DCHECK(!key_system_.empty());
373 DCHECK(!session_message_cb_.is_null()); 378 DCHECK(!session_message_cb_.is_null());
374 DCHECK(!session_closed_cb_.is_null()); 379 DCHECK(!session_closed_cb_.is_null());
375 DCHECK(!legacy_session_error_cb_.is_null()); 380 DCHECK(!legacy_session_error_cb_.is_null());
376 DCHECK(!session_keys_change_cb_.is_null()); 381 DCHECK(!session_keys_change_cb_.is_null());
377 DCHECK(!session_expiration_update_cb_.is_null()); 382 DCHECK(!session_expiration_update_cb_.is_null());
383 DCHECK(allocator_);
378 } 384 }
379 385
380 CdmAdapter::~CdmAdapter() {} 386 CdmAdapter::~CdmAdapter() {}
381 387
382 CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system, 388 CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system,
383 const base::FilePath& cdm_path) { 389 const base::FilePath& cdm_path) {
384 DCHECK(task_runner_->BelongsToCurrentThread()); 390 DCHECK(task_runner_->BelongsToCurrentThread());
385 391
386 // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and 392 // TODO(jrummell): We need to call INITIALIZE_CDM_MODULE() and
387 // DeinitializeCdmModule(). However, that should only be done once for the 393 // DeinitializeCdmModule(). However, that should only be done once for the
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 662
657 void CdmAdapter::DecryptAndDecodeVideo( 663 void CdmAdapter::DecryptAndDecodeVideo(
658 const scoped_refptr<DecoderBuffer>& encrypted, 664 const scoped_refptr<DecoderBuffer>& encrypted,
659 const VideoDecodeCB& video_decode_cb) { 665 const VideoDecodeCB& video_decode_cb) {
660 DCHECK(task_runner_->BelongsToCurrentThread()); 666 DCHECK(task_runner_->BelongsToCurrentThread());
661 DVLOG(3) << __FUNCTION__ 667 DVLOG(3) << __FUNCTION__
662 << " encrypted: " << encrypted->AsHumanReadableString(); 668 << " encrypted: " << encrypted->AsHumanReadableString();
663 669
664 cdm::InputBuffer input_buffer; 670 cdm::InputBuffer input_buffer;
665 std::vector<cdm::SubsampleEntry> subsamples; 671 std::vector<cdm::SubsampleEntry> subsamples;
666 scoped_ptr<VideoFrameImpl> video_frame(new VideoFrameImpl()); 672 scoped_ptr<CdmVideoFrame> video_frame = allocator_->CreateCdmVideoFrame();
667 673
668 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer); 674 ToCdmInputBuffer(encrypted, &subsamples, &input_buffer);
669 cdm::Status status = 675 cdm::Status status =
670 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get()); 676 cdm_->DecryptAndDecodeFrame(input_buffer, video_frame.get());
671 677
672 if (status != cdm::kSuccess) { 678 if (status != cdm::kSuccess) {
673 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status; 679 DVLOG(1) << __FUNCTION__ << " failed with cdm::Error " << status;
674 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr); 680 video_decode_cb.Run(ToMediaDecryptorStatus(status), nullptr);
675 return; 681 return;
676 } 682 }
677 683
678 uint8_t* frame_data = video_frame->FrameBuffer()->Data(); 684 scoped_refptr<VideoFrame> decoded_frame =
679 gfx::Size frame_size(video_frame->Size().width, video_frame->Size().height); 685 video_frame->CreateVideoFrame(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); 686 video_decode_cb.Run(Decryptor::kSuccess, decoded_frame);
690 } 687 }
691 688
692 void CdmAdapter::ResetDecoder(StreamType stream_type) { 689 void CdmAdapter::ResetDecoder(StreamType stream_type) {
693 DCHECK(task_runner_->BelongsToCurrentThread()); 690 DCHECK(task_runner_->BelongsToCurrentThread());
694 cdm_->ResetDecoder(ToCdmStreamType(stream_type)); 691 cdm_->ResetDecoder(ToCdmStreamType(stream_type));
695 } 692 }
696 693
697 void CdmAdapter::DeinitializeDecoder(StreamType stream_type) { 694 void CdmAdapter::DeinitializeDecoder(StreamType stream_type) {
698 DCHECK(task_runner_->BelongsToCurrentThread()); 695 DCHECK(task_runner_->BelongsToCurrentThread());
699 cdm_->DeinitializeDecoder(ToCdmStreamType(stream_type)); 696 cdm_->DeinitializeDecoder(ToCdmStreamType(stream_type));
700 697
701 // Reset the saved values from initializing the decoder. 698 // Reset the saved values from initializing the decoder.
702 switch (stream_type) { 699 switch (stream_type) {
703 case Decryptor::kAudio: 700 case Decryptor::kAudio:
704 audio_samples_per_second_ = 0; 701 audio_samples_per_second_ = 0;
705 audio_channel_layout_ = CHANNEL_LAYOUT_NONE; 702 audio_channel_layout_ = CHANNEL_LAYOUT_NONE;
706 break; 703 break;
707 case Decryptor::kVideo: 704 case Decryptor::kVideo:
708 natural_size_ = gfx::Size(); 705 natural_size_ = gfx::Size();
709 break; 706 break;
710 } 707 }
711 } 708 }
712 709
713 cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) { 710 cdm::Buffer* CdmAdapter::Allocate(uint32_t capacity) {
714 DCHECK(task_runner_->BelongsToCurrentThread()); 711 DCHECK(task_runner_->BelongsToCurrentThread());
715 return CdmBuffer::Create(capacity); 712 scoped_refptr<CdmBuffer> buffer = allocator_->Allocate(capacity);
713
714 // Since the CDM only expects a pointer, we create a dummy reference to
715 // |buffer|. When the buffer is assigned to a helper object
716 // (DecryptedBlockImpl, VideoFrameImpl, AudioFramesImpl) it will take the
717 // ownership of the buffer.
718 buffer->AddRef();
719 return buffer.get();
716 } 720 }
717 721
718 void CdmAdapter::SetTimer(int64_t delay_ms, void* context) { 722 void CdmAdapter::SetTimer(int64_t delay_ms, void* context) {
719 DCHECK(task_runner_->BelongsToCurrentThread()); 723 DCHECK(task_runner_->BelongsToCurrentThread());
720 task_runner_->PostDelayedTask(FROM_HERE, 724 task_runner_->PostDelayedTask(FROM_HERE,
721 base::Bind(&CdmAdapter::TimerExpired, 725 base::Bind(&CdmAdapter::TimerExpired,
722 weak_factory_.GetWeakPtr(), context), 726 weak_factory_.GetWeakPtr(), context),
723 base::TimeDelta::FromMilliseconds(delay_ms)); 727 base::TimeDelta::FromMilliseconds(delay_ms));
724 } 728 }
725 729
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 result_frames->push_back(frame); 955 result_frames->push_back(frame);
952 956
953 data += frame_size; 957 data += frame_size;
954 bytes_left -= frame_size; 958 bytes_left -= frame_size;
955 } while (bytes_left > 0); 959 } while (bytes_left > 0);
956 960
957 return true; 961 return true;
958 } 962 }
959 963
960 } // namespace media 964 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698