| 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 "content/renderer/pepper/content_decryptor_delegate.h" | 5 #include "content/renderer/pepper/content_decryptor_delegate.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 // |array_size| is smaller than the |str| length. | 88 // |array_size| is smaller than the |str| length. |
| 89 template <uint32_t array_size> | 89 template <uint32_t array_size> |
| 90 bool CopyStringToArray(const std::string& str, uint8_t(&array)[array_size]) { | 90 bool CopyStringToArray(const std::string& str, uint8_t(&array)[array_size]) { |
| 91 if (array_size < str.size()) | 91 if (array_size < str.size()) |
| 92 return false; | 92 return false; |
| 93 | 93 |
| 94 memcpy(array, str.data(), str.size()); | 94 memcpy(array, str.data(), str.size()); |
| 95 return true; | 95 return true; |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Fills the |block_info| with information from |encrypted_buffer|. | 98 // Fills the |block_info| with information from |buffer|. |
| 99 // | 99 // |
| 100 // Returns true if |block_info| is successfully filled. Returns false | 100 // Returns true if |block_info| is successfully filled. Returns false |
| 101 // otherwise. | 101 // otherwise. |
| 102 bool MakeEncryptedBlockInfo( | 102 bool MakeEncryptedBlockInfo(const scoped_refptr<media::DecoderBuffer>& buffer, |
| 103 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 103 uint32_t request_id, |
| 104 uint32_t request_id, | 104 PP_EncryptedBlockInfo* block_info) { |
| 105 PP_EncryptedBlockInfo* block_info) { | |
| 106 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and | 105 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and |
| 107 // anywhere else. | 106 // anywhere else. |
| 108 memset(block_info, 0, sizeof(*block_info)); | 107 memset(block_info, 0, sizeof(*block_info)); |
| 109 block_info->tracking_info.request_id = request_id; | 108 block_info->tracking_info.request_id = request_id; |
| 110 | 109 |
| 111 // EOS buffers need a request ID and nothing more. | 110 // EOS buffers need a request ID and nothing more. |
| 112 if (encrypted_buffer->end_of_stream()) | 111 if (buffer->end_of_stream()) |
| 113 return true; | 112 return true; |
| 114 | 113 |
| 115 DCHECK(encrypted_buffer->data_size()) | 114 DCHECK(buffer->data_size()) << "DecryptConfig is set on an empty buffer"; |
| 116 << "DecryptConfig is set on an empty buffer"; | |
| 117 | 115 |
| 118 block_info->tracking_info.timestamp = | 116 block_info->tracking_info.timestamp = buffer->timestamp().InMicroseconds(); |
| 119 encrypted_buffer->timestamp().InMicroseconds(); | 117 block_info->data_size = buffer->data_size(); |
| 120 block_info->data_size = encrypted_buffer->data_size(); | |
| 121 | 118 |
| 122 const media::DecryptConfig* decrypt_config = | 119 const media::DecryptConfig* decrypt_config = buffer->decrypt_config(); |
| 123 encrypted_buffer->decrypt_config(); | 120 // There's no need to fill encryption related fields for unencrypted buffer. |
| 121 if (!decrypt_config) |
| 122 return true; |
| 124 | 123 |
| 125 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || | 124 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || |
| 126 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) | 125 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) |
| 127 return false; | 126 return false; |
| 128 | 127 |
| 129 block_info->key_id_size = decrypt_config->key_id().size(); | 128 block_info->key_id_size = decrypt_config->key_id().size(); |
| 130 block_info->iv_size = decrypt_config->iv().size(); | 129 block_info->iv_size = decrypt_config->iv().size(); |
| 131 | 130 |
| 132 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) | 131 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) |
| 133 return false; | 132 return false; |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 stream_type, encrypted_buffer, &encrypted_resource) || | 521 stream_type, encrypted_buffer, &encrypted_resource) || |
| 523 !encrypted_resource.get()) { | 522 !encrypted_resource.get()) { |
| 524 return false; | 523 return false; |
| 525 } | 524 } |
| 526 ScopedPPResource pp_resource(encrypted_resource.get()); | 525 ScopedPPResource pp_resource(encrypted_resource.get()); |
| 527 | 526 |
| 528 const uint32_t request_id = next_decryption_request_id_++; | 527 const uint32_t request_id = next_decryption_request_id_++; |
| 529 DVLOG(2) << "Decrypt() - request_id " << request_id; | 528 DVLOG(2) << "Decrypt() - request_id " << request_id; |
| 530 | 529 |
| 531 PP_EncryptedBlockInfo block_info = {}; | 530 PP_EncryptedBlockInfo block_info = {}; |
| 532 DCHECK(encrypted_buffer->decrypt_config()); | |
| 533 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 531 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
| 534 return false; | 532 return false; |
| 535 } | 533 } |
| 536 | 534 |
| 537 // There is only one pending decrypt request at any time per stream. This is | 535 // There is only one pending decrypt request at any time per stream. This is |
| 538 // enforced by the media pipeline. | 536 // enforced by the media pipeline. |
| 539 switch (stream_type) { | 537 switch (stream_type) { |
| 540 case Decryptor::kAudio: | 538 case Decryptor::kAudio: |
| 541 audio_decrypt_cb_.Set(request_id, decrypt_cb); | 539 audio_decrypt_cb_.Set(request_id, decrypt_cb); |
| 542 break; | 540 break; |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 if (!video_decode_cb_.is_null()) | 1104 if (!video_decode_cb_.is_null()) |
| 1107 video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, NULL); | 1105 video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, NULL); |
| 1108 break; | 1106 break; |
| 1109 default: | 1107 default: |
| 1110 NOTREACHED(); | 1108 NOTREACHED(); |
| 1111 } | 1109 } |
| 1112 } | 1110 } |
| 1113 | 1111 |
| 1114 bool ContentDecryptorDelegate::MakeMediaBufferResource( | 1112 bool ContentDecryptorDelegate::MakeMediaBufferResource( |
| 1115 Decryptor::StreamType stream_type, | 1113 Decryptor::StreamType stream_type, |
| 1116 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 1114 const scoped_refptr<media::DecoderBuffer>& buffer, |
| 1117 scoped_refptr<PPB_Buffer_Impl>* resource) { | 1115 scoped_refptr<PPB_Buffer_Impl>* resource) { |
| 1118 TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource"); | 1116 TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource"); |
| 1119 | 1117 |
| 1120 // End of stream buffers are represented as null resources. | 1118 // End of stream buffers are represented as null resources. |
| 1121 if (encrypted_buffer->end_of_stream()) { | 1119 if (buffer->end_of_stream()) { |
| 1122 *resource = NULL; | 1120 *resource = NULL; |
| 1123 return true; | 1121 return true; |
| 1124 } | 1122 } |
| 1125 | 1123 |
| 1126 DCHECK(stream_type == Decryptor::kAudio || stream_type == Decryptor::kVideo); | 1124 DCHECK(stream_type == Decryptor::kAudio || stream_type == Decryptor::kVideo); |
| 1127 scoped_refptr<PPB_Buffer_Impl>& media_resource = | 1125 scoped_refptr<PPB_Buffer_Impl>& media_resource = |
| 1128 (stream_type == Decryptor::kAudio) ? audio_input_resource_ | 1126 (stream_type == Decryptor::kAudio) ? audio_input_resource_ |
| 1129 : video_input_resource_; | 1127 : video_input_resource_; |
| 1130 | 1128 |
| 1131 const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); | 1129 const size_t data_size = static_cast<size_t>(buffer->data_size()); |
| 1132 if (!media_resource.get() || media_resource->size() < data_size) { | 1130 if (!media_resource.get() || media_resource->size() < data_size) { |
| 1133 // Either the buffer hasn't been created yet, or we have one that isn't big | 1131 // Either the buffer hasn't been created yet, or we have one that isn't big |
| 1134 // enough to fit |size| bytes. | 1132 // enough to fit |size| bytes. |
| 1135 | 1133 |
| 1136 // Media resource size starts from |kMinimumMediaBufferSize| and grows | 1134 // Media resource size starts from |kMinimumMediaBufferSize| and grows |
| 1137 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, | 1135 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, |
| 1138 // which is usually expensive. Since input media buffers are compressed, | 1136 // which is usually expensive. Since input media buffers are compressed, |
| 1139 // they are usually small (compared to outputs). The over-allocated memory | 1137 // they are usually small (compared to outputs). The over-allocated memory |
| 1140 // should be negligible. | 1138 // should be negligible. |
| 1141 const uint32_t kMinimumMediaBufferSize = 1024; | 1139 const uint32_t kMinimumMediaBufferSize = 1024; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1152 PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource_size); | 1150 PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource_size); |
| 1153 if (!media_resource.get()) | 1151 if (!media_resource.get()) |
| 1154 return false; | 1152 return false; |
| 1155 } | 1153 } |
| 1156 | 1154 |
| 1157 BufferAutoMapper mapper(media_resource.get()); | 1155 BufferAutoMapper mapper(media_resource.get()); |
| 1158 if (!mapper.data() || mapper.size() < data_size) { | 1156 if (!mapper.data() || mapper.size() < data_size) { |
| 1159 media_resource = NULL; | 1157 media_resource = NULL; |
| 1160 return false; | 1158 return false; |
| 1161 } | 1159 } |
| 1162 memcpy(mapper.data(), encrypted_buffer->data(), data_size); | 1160 memcpy(mapper.data(), buffer->data(), data_size); |
| 1163 | 1161 |
| 1164 *resource = media_resource; | 1162 *resource = media_resource; |
| 1165 return true; | 1163 return true; |
| 1166 } | 1164 } |
| 1167 | 1165 |
| 1168 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { | 1166 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { |
| 1169 if (buffer_id) | 1167 if (buffer_id) |
| 1170 free_buffers_.push(buffer_id); | 1168 free_buffers_.push(buffer_id); |
| 1171 } | 1169 } |
| 1172 | 1170 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 | 1278 |
| 1281 if (!video_decode_cb_.is_null()) | 1279 if (!video_decode_cb_.is_null()) |
| 1282 video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); | 1280 video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); |
| 1283 | 1281 |
| 1284 cdm_promise_adapter_.Clear(); | 1282 cdm_promise_adapter_.Clear(); |
| 1285 | 1283 |
| 1286 cdm_session_tracker_.CloseRemainingSessions(session_closed_cb_); | 1284 cdm_session_tracker_.CloseRemainingSessions(session_closed_cb_); |
| 1287 } | 1285 } |
| 1288 | 1286 |
| 1289 } // namespace content | 1287 } // namespace content |
| OLD | NEW |