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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 // otherwise. | 83 // otherwise. |
84 static bool MakeEncryptedBlockInfo( | 84 static bool MakeEncryptedBlockInfo( |
85 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 85 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
86 uint32_t request_id, PP_EncryptedBlockInfo* block_info) { | 86 uint32_t request_id, PP_EncryptedBlockInfo* block_info) { |
87 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and | 87 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and |
88 // anywhere else. | 88 // anywhere else. |
89 memset(block_info, 0, sizeof(*block_info)); | 89 memset(block_info, 0, sizeof(*block_info)); |
90 block_info->tracking_info.request_id = request_id; | 90 block_info->tracking_info.request_id = request_id; |
91 | 91 |
92 // EOS buffers need a request ID and nothing more. | 92 // EOS buffers need a request ID and nothing more. |
93 if (encrypted_buffer->IsEndOfStream()) | 93 if (encrypted_buffer->end_of_stream()) |
94 return true; | 94 return true; |
95 | 95 |
96 DCHECK(encrypted_buffer->GetDataSize()) | 96 DCHECK(encrypted_buffer->data_size()) |
97 << "DecryptConfig is set on an empty buffer"; | 97 << "DecryptConfig is set on an empty buffer"; |
98 | 98 |
99 block_info->tracking_info.timestamp = | 99 block_info->tracking_info.timestamp = |
100 encrypted_buffer->GetTimestamp().InMicroseconds(); | 100 encrypted_buffer->timestamp().InMicroseconds(); |
101 block_info->data_size = encrypted_buffer->GetDataSize(); | 101 block_info->data_size = encrypted_buffer->data_size(); |
102 | 102 |
103 const media::DecryptConfig* decrypt_config = | 103 const media::DecryptConfig* decrypt_config = |
104 encrypted_buffer->GetDecryptConfig(); | 104 encrypted_buffer->decrypt_config(); |
105 block_info->data_offset = decrypt_config->data_offset(); | 105 block_info->data_offset = decrypt_config->data_offset(); |
106 | 106 |
107 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || | 107 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || |
108 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) | 108 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) |
109 return false; | 109 return false; |
110 | 110 |
111 block_info->key_id_size = decrypt_config->key_id().size(); | 111 block_info->key_id_size = decrypt_config->key_id().size(); |
112 block_info->iv_size = decrypt_config->iv().size(); | 112 block_info->iv_size = decrypt_config->iv().size(); |
113 | 113 |
114 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) | 114 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 &encrypted_resource) || | 347 &encrypted_resource) || |
348 !encrypted_resource.get()) { | 348 !encrypted_resource.get()) { |
349 return false; | 349 return false; |
350 } | 350 } |
351 ScopedPPResource pp_resource(encrypted_resource.get()); | 351 ScopedPPResource pp_resource(encrypted_resource.get()); |
352 | 352 |
353 const uint32_t request_id = next_decryption_request_id_++; | 353 const uint32_t request_id = next_decryption_request_id_++; |
354 DVLOG(2) << "Decrypt() - request_id " << request_id; | 354 DVLOG(2) << "Decrypt() - request_id " << request_id; |
355 | 355 |
356 PP_EncryptedBlockInfo block_info = {}; | 356 PP_EncryptedBlockInfo block_info = {}; |
357 DCHECK(encrypted_buffer->GetDecryptConfig()); | 357 DCHECK(encrypted_buffer->decrypt_config()); |
358 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 358 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
359 return false; | 359 return false; |
360 } | 360 } |
361 | 361 |
362 // There is only one pending decrypt request at any time per stream. This is | 362 // There is only one pending decrypt request at any time per stream. This is |
363 // enforced by the media pipeline. | 363 // enforced by the media pipeline. |
364 switch (stream_type) { | 364 switch (stream_type) { |
365 case media::Decryptor::kAudio: | 365 case media::Decryptor::kAudio: |
366 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); | 366 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); |
367 DCHECK(pending_audio_decrypt_cb_.is_null()); | 367 DCHECK(pending_audio_decrypt_cb_.is_null()); |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 // |audio_input_resource_| is not being used by the plugin now | 511 // |audio_input_resource_| is not being used by the plugin now |
512 // because there is only one pending audio decode request at any time. | 512 // because there is only one pending audio decode request at any time. |
513 // This is enforced by the media pipeline. | 513 // This is enforced by the media pipeline. |
514 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 514 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
515 if (!MakeMediaBufferResource(media::Decryptor::kAudio, encrypted_buffer, | 515 if (!MakeMediaBufferResource(media::Decryptor::kAudio, encrypted_buffer, |
516 &encrypted_resource)) { | 516 &encrypted_resource)) { |
517 return false; | 517 return false; |
518 } | 518 } |
519 | 519 |
520 // The resource should not be NULL for non-EOS buffer. | 520 // The resource should not be NULL for non-EOS buffer. |
521 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 521 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
522 return false; | 522 return false; |
523 | 523 |
524 const uint32_t request_id = next_decryption_request_id_++; | 524 const uint32_t request_id = next_decryption_request_id_++; |
525 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; | 525 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
526 | 526 |
527 PP_EncryptedBlockInfo block_info = {}; | 527 PP_EncryptedBlockInfo block_info = {}; |
528 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 528 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
529 return false; | 529 return false; |
530 } | 530 } |
531 | 531 |
(...skipping 20 matching lines...) Expand all Loading... |
552 // |video_input_resource_| is not being used by the plugin now | 552 // |video_input_resource_| is not being used by the plugin now |
553 // because there is only one pending video decode request at any time. | 553 // because there is only one pending video decode request at any time. |
554 // This is enforced by the media pipeline. | 554 // This is enforced by the media pipeline. |
555 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 555 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
556 if (!MakeMediaBufferResource(media::Decryptor::kVideo, encrypted_buffer, | 556 if (!MakeMediaBufferResource(media::Decryptor::kVideo, encrypted_buffer, |
557 &encrypted_resource)) { | 557 &encrypted_resource)) { |
558 return false; | 558 return false; |
559 } | 559 } |
560 | 560 |
561 // The resource should not be 0 for non-EOS buffer. | 561 // The resource should not be 0 for non-EOS buffer. |
562 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 562 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
563 return false; | 563 return false; |
564 | 564 |
565 const uint32_t request_id = next_decryption_request_id_++; | 565 const uint32_t request_id = next_decryption_request_id_++; |
566 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; | 566 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
567 TRACE_EVENT_ASYNC_BEGIN0( | 567 TRACE_EVENT_ASYNC_BEGIN0( |
568 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); | 568 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); |
569 | 569 |
570 PP_EncryptedBlockInfo block_info = {}; | 570 PP_EncryptedBlockInfo block_info = {}; |
571 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 571 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
572 return false; | 572 return false; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 mapper.size() < block_info->data_size) { | 738 mapper.size() < block_info->data_size) { |
739 decrypt_cb.Run(media::Decryptor::kError, NULL); | 739 decrypt_cb.Run(media::Decryptor::kError, NULL); |
740 return; | 740 return; |
741 } | 741 } |
742 | 742 |
743 // TODO(tomfinegan): Find a way to take ownership of the shared memory | 743 // TODO(tomfinegan): Find a way to take ownership of the shared memory |
744 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | 744 // managed by the PPB_Buffer_Dev, and avoid the extra copy. |
745 scoped_refptr<media::DecoderBuffer> decrypted_buffer( | 745 scoped_refptr<media::DecoderBuffer> decrypted_buffer( |
746 media::DecoderBuffer::CopyFrom(static_cast<uint8*>(mapper.data()), | 746 media::DecoderBuffer::CopyFrom(static_cast<uint8*>(mapper.data()), |
747 block_info->data_size)); | 747 block_info->data_size)); |
748 decrypted_buffer->SetTimestamp( | 748 decrypted_buffer->set_timestamp( |
749 base::TimeDelta::FromMicroseconds(block_info->tracking_info.timestamp)); | 749 base::TimeDelta::FromMicroseconds(block_info->tracking_info.timestamp)); |
750 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 750 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); |
751 } | 751 } |
752 | 752 |
753 // Use a non-class-member function here so that if for some reason | 753 // Use a non-class-member function here so that if for some reason |
754 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, | 754 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, |
755 // we can still get the shared memory unmapped. | 755 // we can still get the shared memory unmapped. |
756 static void BufferNoLongerNeeded( | 756 static void BufferNoLongerNeeded( |
757 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, | 757 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, |
758 base::Closure buffer_no_longer_needed_cb) { | 758 base::Closure buffer_no_longer_needed_cb) { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 } | 914 } |
915 } | 915 } |
916 | 916 |
917 bool ContentDecryptorDelegate::MakeMediaBufferResource( | 917 bool ContentDecryptorDelegate::MakeMediaBufferResource( |
918 media::Decryptor::StreamType stream_type, | 918 media::Decryptor::StreamType stream_type, |
919 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 919 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
920 scoped_refptr<PPB_Buffer_Impl>* resource) { | 920 scoped_refptr<PPB_Buffer_Impl>* resource) { |
921 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); | 921 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); |
922 | 922 |
923 // End of stream buffers are represented as null resources. | 923 // End of stream buffers are represented as null resources. |
924 if (encrypted_buffer->IsEndOfStream()) { | 924 if (encrypted_buffer->end_of_stream()) { |
925 *resource = NULL; | 925 *resource = NULL; |
926 return true; | 926 return true; |
927 } | 927 } |
928 | 928 |
929 DCHECK(stream_type == media::Decryptor::kAudio || | 929 DCHECK(stream_type == media::Decryptor::kAudio || |
930 stream_type == media::Decryptor::kVideo); | 930 stream_type == media::Decryptor::kVideo); |
931 scoped_refptr<PPB_Buffer_Impl>& media_resource = | 931 scoped_refptr<PPB_Buffer_Impl>& media_resource = |
932 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ | 932 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ |
933 : video_input_resource_; | 933 : video_input_resource_; |
934 | 934 |
935 const size_t data_size = static_cast<size_t>(encrypted_buffer->GetDataSize()); | 935 const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); |
936 if (!media_resource.get() || media_resource->size() < data_size) { | 936 if (!media_resource.get() || media_resource->size() < data_size) { |
937 // Either the buffer hasn't been created yet, or we have one that isn't big | 937 // Either the buffer hasn't been created yet, or we have one that isn't big |
938 // enough to fit |size| bytes. | 938 // enough to fit |size| bytes. |
939 | 939 |
940 // Media resource size starts from |kMinimumMediaBufferSize| and grows | 940 // Media resource size starts from |kMinimumMediaBufferSize| and grows |
941 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, | 941 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, |
942 // which is usually expensive. Since input media buffers are compressed, | 942 // which is usually expensive. Since input media buffers are compressed, |
943 // they are usually small (compared to outputs). The over-allocated memory | 943 // they are usually small (compared to outputs). The over-allocated memory |
944 // should be negligible. | 944 // should be negligible. |
945 const uint32_t kMinimumMediaBufferSize = 1024; | 945 const uint32_t kMinimumMediaBufferSize = 1024; |
(...skipping 10 matching lines...) Expand all Loading... |
956 PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource_size); | 956 PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource_size); |
957 if (!media_resource.get()) | 957 if (!media_resource.get()) |
958 return false; | 958 return false; |
959 } | 959 } |
960 | 960 |
961 BufferAutoMapper mapper(media_resource.get()); | 961 BufferAutoMapper mapper(media_resource.get()); |
962 if (!mapper.data() || mapper.size() < data_size) { | 962 if (!mapper.data() || mapper.size() < data_size) { |
963 media_resource = NULL; | 963 media_resource = NULL; |
964 return false; | 964 return false; |
965 } | 965 } |
966 memcpy(mapper.data(), encrypted_buffer->GetData(), data_size); | 966 memcpy(mapper.data(), encrypted_buffer->data(), data_size); |
967 | 967 |
968 *resource = media_resource; | 968 *resource = media_resource; |
969 return true; | 969 return true; |
970 } | 970 } |
971 | 971 |
972 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { | 972 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { |
973 if (buffer_id) | 973 if (buffer_id) |
974 free_buffers_.push(buffer_id); | 974 free_buffers_.push(buffer_id); |
975 } | 975 } |
976 | 976 |
977 void ContentDecryptorDelegate::SetBufferToFreeInTrackingInfo( | 977 void ContentDecryptorDelegate::SetBufferToFreeInTrackingInfo( |
978 PP_DecryptTrackingInfo* tracking_info) { | 978 PP_DecryptTrackingInfo* tracking_info) { |
979 DCHECK_EQ(tracking_info->buffer_id, 0u); | 979 DCHECK_EQ(tracking_info->buffer_id, 0u); |
980 | 980 |
981 if (free_buffers_.empty()) | 981 if (free_buffers_.empty()) |
982 return; | 982 return; |
983 | 983 |
984 tracking_info->buffer_id = free_buffers_.front(); | 984 tracking_info->buffer_id = free_buffers_.front(); |
985 free_buffers_.pop(); | 985 free_buffers_.pop(); |
986 } | 986 } |
987 | 987 |
988 } // namespace ppapi | 988 } // namespace ppapi |
989 } // namespace webkit | 989 } // namespace webkit |
OLD | NEW |