| 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 "base/safe_numerics.h" | 10 #include "base/safe_numerics.h" |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 static bool MakeEncryptedBlockInfo( | 87 static bool MakeEncryptedBlockInfo( |
| 88 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 88 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 89 uint32_t request_id, | 89 uint32_t request_id, |
| 90 PP_EncryptedBlockInfo* block_info) { | 90 PP_EncryptedBlockInfo* block_info) { |
| 91 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and | 91 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and |
| 92 // anywhere else. | 92 // anywhere else. |
| 93 memset(block_info, 0, sizeof(*block_info)); | 93 memset(block_info, 0, sizeof(*block_info)); |
| 94 block_info->tracking_info.request_id = request_id; | 94 block_info->tracking_info.request_id = request_id; |
| 95 | 95 |
| 96 // EOS buffers need a request ID and nothing more. | 96 // EOS buffers need a request ID and nothing more. |
| 97 if (encrypted_buffer->IsEndOfStream()) | 97 if (encrypted_buffer->end_of_stream()) |
| 98 return true; | 98 return true; |
| 99 | 99 |
| 100 DCHECK(encrypted_buffer->GetDataSize()) | 100 DCHECK(encrypted_buffer->data_size()) |
| 101 << "DecryptConfig is set on an empty buffer"; | 101 << "DecryptConfig is set on an empty buffer"; |
| 102 | 102 |
| 103 block_info->tracking_info.timestamp = | 103 block_info->tracking_info.timestamp = |
| 104 encrypted_buffer->GetTimestamp().InMicroseconds(); | 104 encrypted_buffer->timestamp().InMicroseconds(); |
| 105 block_info->data_size = encrypted_buffer->GetDataSize(); | 105 block_info->data_size = encrypted_buffer->data_size(); |
| 106 | 106 |
| 107 const media::DecryptConfig* decrypt_config = | 107 const media::DecryptConfig* decrypt_config = |
| 108 encrypted_buffer->GetDecryptConfig(); | 108 encrypted_buffer->decrypt_config(); |
| 109 block_info->data_offset = decrypt_config->data_offset(); | 109 block_info->data_offset = decrypt_config->data_offset(); |
| 110 | 110 |
| 111 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || | 111 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || |
| 112 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) | 112 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) |
| 113 return false; | 113 return false; |
| 114 | 114 |
| 115 block_info->key_id_size = decrypt_config->key_id().size(); | 115 block_info->key_id_size = decrypt_config->key_id().size(); |
| 116 block_info->iv_size = decrypt_config->iv().size(); | 116 block_info->iv_size = decrypt_config->iv().size(); |
| 117 | 117 |
| 118 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) | 118 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 stream_type, encrypted_buffer, &encrypted_resource) || | 313 stream_type, encrypted_buffer, &encrypted_resource) || |
| 314 !encrypted_resource.get()) { | 314 !encrypted_resource.get()) { |
| 315 return false; | 315 return false; |
| 316 } | 316 } |
| 317 ScopedPPResource pp_resource(encrypted_resource.get()); | 317 ScopedPPResource pp_resource(encrypted_resource.get()); |
| 318 | 318 |
| 319 const uint32_t request_id = next_decryption_request_id_++; | 319 const uint32_t request_id = next_decryption_request_id_++; |
| 320 DVLOG(2) << "Decrypt() - request_id " << request_id; | 320 DVLOG(2) << "Decrypt() - request_id " << request_id; |
| 321 | 321 |
| 322 PP_EncryptedBlockInfo block_info = {}; | 322 PP_EncryptedBlockInfo block_info = {}; |
| 323 DCHECK(encrypted_buffer->GetDecryptConfig()); | 323 DCHECK(encrypted_buffer->decrypt_config()); |
| 324 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 324 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
| 325 return false; | 325 return false; |
| 326 } | 326 } |
| 327 | 327 |
| 328 // There is only one pending decrypt request at any time per stream. This is | 328 // There is only one pending decrypt request at any time per stream. This is |
| 329 // enforced by the media pipeline. | 329 // enforced by the media pipeline. |
| 330 switch (stream_type) { | 330 switch (stream_type) { |
| 331 case media::Decryptor::kAudio: | 331 case media::Decryptor::kAudio: |
| 332 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); | 332 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); |
| 333 DCHECK(pending_audio_decrypt_cb_.is_null()); | 333 DCHECK(pending_audio_decrypt_cb_.is_null()); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 // because there is only one pending audio decode request at any time. | 489 // because there is only one pending audio decode request at any time. |
| 490 // This is enforced by the media pipeline. | 490 // This is enforced by the media pipeline. |
| 491 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 491 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
| 492 if (!MakeMediaBufferResource(media::Decryptor::kAudio, | 492 if (!MakeMediaBufferResource(media::Decryptor::kAudio, |
| 493 encrypted_buffer, | 493 encrypted_buffer, |
| 494 &encrypted_resource)) { | 494 &encrypted_resource)) { |
| 495 return false; | 495 return false; |
| 496 } | 496 } |
| 497 | 497 |
| 498 // The resource should not be NULL for non-EOS buffer. | 498 // The resource should not be NULL for non-EOS buffer. |
| 499 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 499 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
| 500 return false; | 500 return false; |
| 501 | 501 |
| 502 const uint32_t request_id = next_decryption_request_id_++; | 502 const uint32_t request_id = next_decryption_request_id_++; |
| 503 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; | 503 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
| 504 | 504 |
| 505 PP_EncryptedBlockInfo block_info = {}; | 505 PP_EncryptedBlockInfo block_info = {}; |
| 506 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 506 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
| 507 return false; | 507 return false; |
| 508 } | 508 } |
| 509 | 509 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 533 // because there is only one pending video decode request at any time. | 533 // because there is only one pending video decode request at any time. |
| 534 // This is enforced by the media pipeline. | 534 // This is enforced by the media pipeline. |
| 535 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 535 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
| 536 if (!MakeMediaBufferResource(media::Decryptor::kVideo, | 536 if (!MakeMediaBufferResource(media::Decryptor::kVideo, |
| 537 encrypted_buffer, | 537 encrypted_buffer, |
| 538 &encrypted_resource)) { | 538 &encrypted_resource)) { |
| 539 return false; | 539 return false; |
| 540 } | 540 } |
| 541 | 541 |
| 542 // The resource should not be 0 for non-EOS buffer. | 542 // The resource should not be 0 for non-EOS buffer. |
| 543 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 543 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
| 544 return false; | 544 return false; |
| 545 | 545 |
| 546 const uint32_t request_id = next_decryption_request_id_++; | 546 const uint32_t request_id = next_decryption_request_id_++; |
| 547 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; | 547 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
| 548 TRACE_EVENT_ASYNC_BEGIN0( | 548 TRACE_EVENT_ASYNC_BEGIN0( |
| 549 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); | 549 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); |
| 550 | 550 |
| 551 PP_EncryptedBlockInfo block_info = {}; | 551 PP_EncryptedBlockInfo block_info = {}; |
| 552 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 552 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
| 553 return false; | 553 return false; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 mapper.size() < block_info->data_size) { | 731 mapper.size() < block_info->data_size) { |
| 732 decrypt_cb.Run(media::Decryptor::kError, NULL); | 732 decrypt_cb.Run(media::Decryptor::kError, NULL); |
| 733 return; | 733 return; |
| 734 } | 734 } |
| 735 | 735 |
| 736 // TODO(tomfinegan): Find a way to take ownership of the shared memory | 736 // TODO(tomfinegan): Find a way to take ownership of the shared memory |
| 737 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | 737 // managed by the PPB_Buffer_Dev, and avoid the extra copy. |
| 738 scoped_refptr<media::DecoderBuffer> decrypted_buffer( | 738 scoped_refptr<media::DecoderBuffer> decrypted_buffer( |
| 739 media::DecoderBuffer::CopyFrom( | 739 media::DecoderBuffer::CopyFrom( |
| 740 static_cast<uint8*>(mapper.data()), block_info->data_size)); | 740 static_cast<uint8*>(mapper.data()), block_info->data_size)); |
| 741 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( | 741 decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds( |
| 742 block_info->tracking_info.timestamp)); | 742 block_info->tracking_info.timestamp)); |
| 743 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 743 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); |
| 744 } | 744 } |
| 745 | 745 |
| 746 // Use a non-class-member function here so that if for some reason | 746 // Use a non-class-member function here so that if for some reason |
| 747 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, | 747 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, |
| 748 // we can still get the shared memory unmapped. | 748 // we can still get the shared memory unmapped. |
| 749 static void BufferNoLongerNeeded( | 749 static void BufferNoLongerNeeded( |
| 750 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, | 750 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, |
| 751 base::Closure buffer_no_longer_needed_cb) { | 751 base::Closure buffer_no_longer_needed_cb) { |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 } | 912 } |
| 913 } | 913 } |
| 914 | 914 |
| 915 bool ContentDecryptorDelegate::MakeMediaBufferResource( | 915 bool ContentDecryptorDelegate::MakeMediaBufferResource( |
| 916 media::Decryptor::StreamType stream_type, | 916 media::Decryptor::StreamType stream_type, |
| 917 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 917 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 918 scoped_refptr<PPB_Buffer_Impl>* resource) { | 918 scoped_refptr<PPB_Buffer_Impl>* resource) { |
| 919 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); | 919 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); |
| 920 | 920 |
| 921 // End of stream buffers are represented as null resources. | 921 // End of stream buffers are represented as null resources. |
| 922 if (encrypted_buffer->IsEndOfStream()) { | 922 if (encrypted_buffer->end_of_stream()) { |
| 923 *resource = NULL; | 923 *resource = NULL; |
| 924 return true; | 924 return true; |
| 925 } | 925 } |
| 926 | 926 |
| 927 DCHECK(stream_type == media::Decryptor::kAudio || | 927 DCHECK(stream_type == media::Decryptor::kAudio || |
| 928 stream_type == media::Decryptor::kVideo); | 928 stream_type == media::Decryptor::kVideo); |
| 929 scoped_refptr<PPB_Buffer_Impl>& media_resource = | 929 scoped_refptr<PPB_Buffer_Impl>& media_resource = |
| 930 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : | 930 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : |
| 931 video_input_resource_; | 931 video_input_resource_; |
| 932 | 932 |
| 933 const size_t data_size = static_cast<size_t>(encrypted_buffer->GetDataSize()); | 933 const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); |
| 934 if (!media_resource.get() || media_resource->size() < data_size) { | 934 if (!media_resource.get() || media_resource->size() < data_size) { |
| 935 // Either the buffer hasn't been created yet, or we have one that isn't big | 935 // Either the buffer hasn't been created yet, or we have one that isn't big |
| 936 // enough to fit |size| bytes. | 936 // enough to fit |size| bytes. |
| 937 | 937 |
| 938 // Media resource size starts from |kMinimumMediaBufferSize| and grows | 938 // Media resource size starts from |kMinimumMediaBufferSize| and grows |
| 939 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, | 939 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, |
| 940 // which is usually expensive. Since input media buffers are compressed, | 940 // which is usually expensive. Since input media buffers are compressed, |
| 941 // they are usually small (compared to outputs). The over-allocated memory | 941 // they are usually small (compared to outputs). The over-allocated memory |
| 942 // should be negligible. | 942 // should be negligible. |
| 943 const uint32_t kMinimumMediaBufferSize = 1024; | 943 const uint32_t kMinimumMediaBufferSize = 1024; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 954 media_resource_size); | 954 media_resource_size); |
| 955 if (!media_resource.get()) | 955 if (!media_resource.get()) |
| 956 return false; | 956 return false; |
| 957 } | 957 } |
| 958 | 958 |
| 959 BufferAutoMapper mapper(media_resource.get()); | 959 BufferAutoMapper mapper(media_resource.get()); |
| 960 if (!mapper.data() || mapper.size() < data_size) { | 960 if (!mapper.data() || mapper.size() < data_size) { |
| 961 media_resource = NULL; | 961 media_resource = NULL; |
| 962 return false; | 962 return false; |
| 963 } | 963 } |
| 964 memcpy(mapper.data(), encrypted_buffer->GetData(), data_size); | 964 memcpy(mapper.data(), encrypted_buffer->data(), data_size); |
| 965 | 965 |
| 966 *resource = media_resource; | 966 *resource = media_resource; |
| 967 return true; | 967 return true; |
| 968 } | 968 } |
| 969 | 969 |
| 970 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { | 970 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { |
| 971 if (buffer_id) | 971 if (buffer_id) |
| 972 free_buffers_.push(buffer_id); | 972 free_buffers_.push(buffer_id); |
| 973 } | 973 } |
| 974 | 974 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 | 1039 |
| 1040 cur += frame_size; | 1040 cur += frame_size; |
| 1041 bytes_left -= frame_size; | 1041 bytes_left -= frame_size; |
| 1042 } while (bytes_left > 0); | 1042 } while (bytes_left > 0); |
| 1043 | 1043 |
| 1044 return true; | 1044 return true; |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 } // namespace ppapi | 1047 } // namespace ppapi |
| 1048 } // namespace webkit | 1048 } // namespace webkit |
| OLD | NEW |