| 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 |