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