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/plugins/ppapi/content_decryptor_delegate.h" | 5 #include "webkit/plugins/ppapi/content_decryptor_delegate.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
10 #include "media/base/audio_decoder_config.h" | 10 #include "media/base/audio_decoder_config.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 static bool MakeEncryptedBlockInfo( | 85 static bool MakeEncryptedBlockInfo( |
86 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 86 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
87 uint32_t request_id, | 87 uint32_t request_id, |
88 PP_EncryptedBlockInfo* block_info) { | 88 PP_EncryptedBlockInfo* block_info) { |
89 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and | 89 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and |
90 // anywhere else. | 90 // anywhere else. |
91 memset(block_info, 0, sizeof(*block_info)); | 91 memset(block_info, 0, sizeof(*block_info)); |
92 block_info->tracking_info.request_id = request_id; | 92 block_info->tracking_info.request_id = request_id; |
93 | 93 |
94 // EOS buffers need a request ID and nothing more. | 94 // EOS buffers need a request ID and nothing more. |
95 if (encrypted_buffer->IsEndOfStream()) | 95 if (encrypted_buffer->end_of_stream()) |
96 return true; | 96 return true; |
97 | 97 |
98 DCHECK(encrypted_buffer->GetDataSize()) | 98 DCHECK(encrypted_buffer->data_size()) |
99 << "DecryptConfig is set on an empty buffer"; | 99 << "DecryptConfig is set on an empty buffer"; |
100 | 100 |
101 block_info->tracking_info.timestamp = | 101 block_info->tracking_info.timestamp = |
102 encrypted_buffer->GetTimestamp().InMicroseconds(); | 102 encrypted_buffer->timestamp().InMicroseconds(); |
103 block_info->data_size = encrypted_buffer->GetDataSize(); | 103 block_info->data_size = encrypted_buffer->data_size(); |
104 | 104 |
105 const media::DecryptConfig* decrypt_config = | 105 const media::DecryptConfig* decrypt_config = |
106 encrypted_buffer->GetDecryptConfig(); | 106 encrypted_buffer->decrypt_config(); |
107 block_info->data_offset = decrypt_config->data_offset(); | 107 block_info->data_offset = decrypt_config->data_offset(); |
108 | 108 |
109 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || | 109 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || |
110 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) | 110 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) |
111 return false; | 111 return false; |
112 | 112 |
113 block_info->key_id_size = decrypt_config->key_id().size(); | 113 block_info->key_id_size = decrypt_config->key_id().size(); |
114 block_info->iv_size = decrypt_config->iv().size(); | 114 block_info->iv_size = decrypt_config->iv().size(); |
115 | 115 |
116 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) | 116 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 stream_type, encrypted_buffer, &encrypted_resource) || | 357 stream_type, encrypted_buffer, &encrypted_resource) || |
358 !encrypted_resource.get()) { | 358 !encrypted_resource.get()) { |
359 return false; | 359 return false; |
360 } | 360 } |
361 ScopedPPResource pp_resource(encrypted_resource.get()); | 361 ScopedPPResource pp_resource(encrypted_resource.get()); |
362 | 362 |
363 const uint32_t request_id = next_decryption_request_id_++; | 363 const uint32_t request_id = next_decryption_request_id_++; |
364 DVLOG(2) << "Decrypt() - request_id " << request_id; | 364 DVLOG(2) << "Decrypt() - request_id " << request_id; |
365 | 365 |
366 PP_EncryptedBlockInfo block_info = {}; | 366 PP_EncryptedBlockInfo block_info = {}; |
367 DCHECK(encrypted_buffer->GetDecryptConfig()); | 367 DCHECK(encrypted_buffer->decrypt_config()); |
368 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 368 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
369 return false; | 369 return false; |
370 } | 370 } |
371 | 371 |
372 // There is only one pending decrypt request at any time per stream. This is | 372 // There is only one pending decrypt request at any time per stream. This is |
373 // enforced by the media pipeline. | 373 // enforced by the media pipeline. |
374 switch (stream_type) { | 374 switch (stream_type) { |
375 case media::Decryptor::kAudio: | 375 case media::Decryptor::kAudio: |
376 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); | 376 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); |
377 DCHECK(pending_audio_decrypt_cb_.is_null()); | 377 DCHECK(pending_audio_decrypt_cb_.is_null()); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 // because there is only one pending audio decode request at any time. | 528 // because there is only one pending audio decode request at any time. |
529 // This is enforced by the media pipeline. | 529 // This is enforced by the media pipeline. |
530 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 530 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
531 if (!MakeMediaBufferResource(media::Decryptor::kAudio, | 531 if (!MakeMediaBufferResource(media::Decryptor::kAudio, |
532 encrypted_buffer, | 532 encrypted_buffer, |
533 &encrypted_resource)) { | 533 &encrypted_resource)) { |
534 return false; | 534 return false; |
535 } | 535 } |
536 | 536 |
537 // The resource should not be NULL for non-EOS buffer. | 537 // The resource should not be NULL for non-EOS buffer. |
538 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 538 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
539 return false; | 539 return false; |
540 | 540 |
541 const uint32_t request_id = next_decryption_request_id_++; | 541 const uint32_t request_id = next_decryption_request_id_++; |
542 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; | 542 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
543 | 543 |
544 PP_EncryptedBlockInfo block_info = {}; | 544 PP_EncryptedBlockInfo block_info = {}; |
545 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 545 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
546 return false; | 546 return false; |
547 } | 547 } |
548 | 548 |
(...skipping 23 matching lines...) Expand all Loading... |
572 // because there is only one pending video decode request at any time. | 572 // because there is only one pending video decode request at any time. |
573 // This is enforced by the media pipeline. | 573 // This is enforced by the media pipeline. |
574 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 574 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
575 if (!MakeMediaBufferResource(media::Decryptor::kVideo, | 575 if (!MakeMediaBufferResource(media::Decryptor::kVideo, |
576 encrypted_buffer, | 576 encrypted_buffer, |
577 &encrypted_resource)) { | 577 &encrypted_resource)) { |
578 return false; | 578 return false; |
579 } | 579 } |
580 | 580 |
581 // The resource should not be 0 for non-EOS buffer. | 581 // The resource should not be 0 for non-EOS buffer. |
582 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 582 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
583 return false; | 583 return false; |
584 | 584 |
585 const uint32_t request_id = next_decryption_request_id_++; | 585 const uint32_t request_id = next_decryption_request_id_++; |
586 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; | 586 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
587 TRACE_EVENT_ASYNC_BEGIN0( | 587 TRACE_EVENT_ASYNC_BEGIN0( |
588 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); | 588 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); |
589 | 589 |
590 PP_EncryptedBlockInfo block_info = {}; | 590 PP_EncryptedBlockInfo block_info = {}; |
591 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 591 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
592 return false; | 592 return false; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 mapper.size() < block_info->data_size) { | 770 mapper.size() < block_info->data_size) { |
771 decrypt_cb.Run(media::Decryptor::kError, NULL); | 771 decrypt_cb.Run(media::Decryptor::kError, NULL); |
772 return; | 772 return; |
773 } | 773 } |
774 | 774 |
775 // TODO(tomfinegan): Find a way to take ownership of the shared memory | 775 // TODO(tomfinegan): Find a way to take ownership of the shared memory |
776 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | 776 // managed by the PPB_Buffer_Dev, and avoid the extra copy. |
777 scoped_refptr<media::DecoderBuffer> decrypted_buffer( | 777 scoped_refptr<media::DecoderBuffer> decrypted_buffer( |
778 media::DecoderBuffer::CopyFrom( | 778 media::DecoderBuffer::CopyFrom( |
779 static_cast<uint8*>(mapper.data()), block_info->data_size)); | 779 static_cast<uint8*>(mapper.data()), block_info->data_size)); |
780 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( | 780 decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds( |
781 block_info->tracking_info.timestamp)); | 781 block_info->tracking_info.timestamp)); |
782 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 782 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); |
783 } | 783 } |
784 | 784 |
785 // Use a non-class-member function here so that if for some reason | 785 // Use a non-class-member function here so that if for some reason |
786 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, | 786 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, |
787 // we can still get the shared memory unmapped. | 787 // we can still get the shared memory unmapped. |
788 static void BufferNoLongerNeeded( | 788 static void BufferNoLongerNeeded( |
789 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, | 789 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, |
790 base::Closure buffer_no_longer_needed_cb) { | 790 base::Closure buffer_no_longer_needed_cb) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 } | 951 } |
952 } | 952 } |
953 | 953 |
954 bool ContentDecryptorDelegate::MakeMediaBufferResource( | 954 bool ContentDecryptorDelegate::MakeMediaBufferResource( |
955 media::Decryptor::StreamType stream_type, | 955 media::Decryptor::StreamType stream_type, |
956 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 956 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
957 scoped_refptr<PPB_Buffer_Impl>* resource) { | 957 scoped_refptr<PPB_Buffer_Impl>* resource) { |
958 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); | 958 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); |
959 | 959 |
960 // End of stream buffers are represented as null resources. | 960 // End of stream buffers are represented as null resources. |
961 if (encrypted_buffer->IsEndOfStream()) { | 961 if (encrypted_buffer->end_of_stream()) { |
962 *resource = NULL; | 962 *resource = NULL; |
963 return true; | 963 return true; |
964 } | 964 } |
965 | 965 |
966 DCHECK(stream_type == media::Decryptor::kAudio || | 966 DCHECK(stream_type == media::Decryptor::kAudio || |
967 stream_type == media::Decryptor::kVideo); | 967 stream_type == media::Decryptor::kVideo); |
968 scoped_refptr<PPB_Buffer_Impl>& media_resource = | 968 scoped_refptr<PPB_Buffer_Impl>& media_resource = |
969 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : | 969 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : |
970 video_input_resource_; | 970 video_input_resource_; |
971 | 971 |
972 const size_t data_size = static_cast<size_t>(encrypted_buffer->GetDataSize()); | 972 const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); |
973 if (!media_resource.get() || media_resource->size() < data_size) { | 973 if (!media_resource.get() || media_resource->size() < data_size) { |
974 // Either the buffer hasn't been created yet, or we have one that isn't big | 974 // Either the buffer hasn't been created yet, or we have one that isn't big |
975 // enough to fit |size| bytes. | 975 // enough to fit |size| bytes. |
976 | 976 |
977 // Media resource size starts from |kMinimumMediaBufferSize| and grows | 977 // Media resource size starts from |kMinimumMediaBufferSize| and grows |
978 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, | 978 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, |
979 // which is usually expensive. Since input media buffers are compressed, | 979 // which is usually expensive. Since input media buffers are compressed, |
980 // they are usually small (compared to outputs). The over-allocated memory | 980 // they are usually small (compared to outputs). The over-allocated memory |
981 // should be negligible. | 981 // should be negligible. |
982 const uint32_t kMinimumMediaBufferSize = 1024; | 982 const uint32_t kMinimumMediaBufferSize = 1024; |
(...skipping 10 matching lines...) Expand all Loading... |
993 media_resource_size); | 993 media_resource_size); |
994 if (!media_resource.get()) | 994 if (!media_resource.get()) |
995 return false; | 995 return false; |
996 } | 996 } |
997 | 997 |
998 BufferAutoMapper mapper(media_resource.get()); | 998 BufferAutoMapper mapper(media_resource.get()); |
999 if (!mapper.data() || mapper.size() < data_size) { | 999 if (!mapper.data() || mapper.size() < data_size) { |
1000 media_resource = NULL; | 1000 media_resource = NULL; |
1001 return false; | 1001 return false; |
1002 } | 1002 } |
1003 memcpy(mapper.data(), encrypted_buffer->GetData(), data_size); | 1003 memcpy(mapper.data(), encrypted_buffer->data(), data_size); |
1004 | 1004 |
1005 *resource = media_resource; | 1005 *resource = media_resource; |
1006 return true; | 1006 return true; |
1007 } | 1007 } |
1008 | 1008 |
1009 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { | 1009 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { |
1010 if (buffer_id) | 1010 if (buffer_id) |
1011 free_buffers_.push(buffer_id); | 1011 free_buffers_.push(buffer_id); |
1012 } | 1012 } |
1013 | 1013 |
1014 void ContentDecryptorDelegate::SetBufferToFreeInTrackingInfo( | 1014 void ContentDecryptorDelegate::SetBufferToFreeInTrackingInfo( |
1015 PP_DecryptTrackingInfo* tracking_info) { | 1015 PP_DecryptTrackingInfo* tracking_info) { |
1016 DCHECK_EQ(tracking_info->buffer_id, 0u); | 1016 DCHECK_EQ(tracking_info->buffer_id, 0u); |
1017 | 1017 |
1018 if (free_buffers_.empty()) | 1018 if (free_buffers_.empty()) |
1019 return; | 1019 return; |
1020 | 1020 |
1021 tracking_info->buffer_id = free_buffers_.front(); | 1021 tracking_info->buffer_id = free_buffers_.front(); |
1022 free_buffers_.pop(); | 1022 free_buffers_.pop(); |
1023 } | 1023 } |
1024 | 1024 |
1025 } // namespace ppapi | 1025 } // namespace ppapi |
1026 } // namespace webkit | 1026 } // namespace webkit |
OLD | NEW |