Chromium Code Reviews| 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 "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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 case media::Decryptor::kAudio: | 211 case media::Decryptor::kAudio: |
| 212 return PP_DECRYPTORSTREAMTYPE_AUDIO; | 212 return PP_DECRYPTORSTREAMTYPE_AUDIO; |
| 213 case media::Decryptor::kVideo: | 213 case media::Decryptor::kVideo: |
| 214 return PP_DECRYPTORSTREAMTYPE_VIDEO; | 214 return PP_DECRYPTORSTREAMTYPE_VIDEO; |
| 215 default: | 215 default: |
| 216 NOTREACHED(); | 216 NOTREACHED(); |
| 217 return PP_DECRYPTORSTREAMTYPE_VIDEO; | 217 return PP_DECRYPTORSTREAMTYPE_VIDEO; |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 media::SampleFormat PpDecryptedSampleFormatToMediaSampleFormat( | |
| 222 PP_DecryptedSampleFormat result) { | |
| 223 switch (result) { | |
| 224 case PP_DECRYPTEDSAMPLEFORMAT_U8: | |
| 225 return media::kSampleFormatU8; | |
| 226 case PP_DECRYPTEDSAMPLEFORMAT_S16: | |
| 227 return media::kSampleFormatS16; | |
| 228 case PP_DECRYPTEDSAMPLEFORMAT_S32: | |
| 229 return media::kSampleFormatS32; | |
| 230 case PP_DECRYPTEDSAMPLEFORMAT_F32: | |
| 231 return media::kSampleFormatF32; | |
| 232 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_S16: | |
| 233 return media::kSampleFormatPlanarS16; | |
| 234 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_F32: | |
| 235 return media::kSampleFormatPlanarF32; | |
| 236 default: | |
| 237 NOTREACHED(); | |
| 238 return media::kUnknownSampleFormat; | |
| 239 } | |
| 240 } | |
| 241 | |
| 221 } // namespace | 242 } // namespace |
| 222 | 243 |
| 223 ContentDecryptorDelegate::ContentDecryptorDelegate( | 244 ContentDecryptorDelegate::ContentDecryptorDelegate( |
| 224 PP_Instance pp_instance, | 245 PP_Instance pp_instance, |
| 225 const PPP_ContentDecryptor_Private* plugin_decryption_interface) | 246 const PPP_ContentDecryptor_Private* plugin_decryption_interface) |
| 226 : pp_instance_(pp_instance), | 247 : pp_instance_(pp_instance), |
| 227 plugin_decryption_interface_(plugin_decryption_interface), | 248 plugin_decryption_interface_(plugin_decryption_interface), |
| 228 next_decryption_request_id_(1), | 249 next_decryption_request_id_(1), |
| 229 pending_audio_decrypt_request_id_(0), | 250 pending_audio_decrypt_request_id_(0), |
| 230 pending_video_decrypt_request_id_(0), | 251 pending_video_decrypt_request_id_(0), |
| 231 pending_audio_decoder_init_request_id_(0), | 252 pending_audio_decoder_init_request_id_(0), |
| 232 pending_video_decoder_init_request_id_(0), | 253 pending_video_decoder_init_request_id_(0), |
| 233 pending_audio_decode_request_id_(0), | 254 pending_audio_decode_request_id_(0), |
| 234 pending_video_decode_request_id_(0), | 255 pending_video_decode_request_id_(0), |
| 235 audio_sample_format_(media::kUnknownSampleFormat), | |
| 236 audio_samples_per_second_(0), | 256 audio_samples_per_second_(0), |
| 237 audio_channel_count_(0), | 257 audio_channel_count_(0), |
| 238 audio_bytes_per_frame_(0), | |
| 239 weak_ptr_factory_(this) { | 258 weak_ptr_factory_(this) { |
| 240 weak_this_ = weak_ptr_factory_.GetWeakPtr(); | 259 weak_this_ = weak_ptr_factory_.GetWeakPtr(); |
| 241 } | 260 } |
| 242 | 261 |
| 243 ContentDecryptorDelegate::~ContentDecryptorDelegate() { | 262 ContentDecryptorDelegate::~ContentDecryptorDelegate() { |
| 244 } | 263 } |
| 245 | 264 |
| 246 void ContentDecryptorDelegate::Initialize(const std::string& key_system, | 265 void ContentDecryptorDelegate::Initialize(const std::string& key_system, |
| 247 bool can_challenge_platform) { | 266 bool can_challenge_platform) { |
| 248 DCHECK(!key_system.empty()); | 267 DCHECK(!key_system.empty()); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 const media::Decryptor::DecoderInitCB& init_cb) { | 417 const media::Decryptor::DecoderInitCB& init_cb) { |
| 399 PP_AudioDecoderConfig pp_decoder_config; | 418 PP_AudioDecoderConfig pp_decoder_config; |
| 400 pp_decoder_config.codec = | 419 pp_decoder_config.codec = |
| 401 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); | 420 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); |
| 402 pp_decoder_config.channel_count = | 421 pp_decoder_config.channel_count = |
| 403 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); | 422 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); |
| 404 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); | 423 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); |
| 405 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); | 424 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); |
| 406 pp_decoder_config.request_id = next_decryption_request_id_++; | 425 pp_decoder_config.request_id = next_decryption_request_id_++; |
| 407 | 426 |
| 408 audio_sample_format_ = decoder_config.sample_format(); | |
| 409 audio_samples_per_second_ = pp_decoder_config.samples_per_second; | 427 audio_samples_per_second_ = pp_decoder_config.samples_per_second; |
| 410 audio_channel_count_ = pp_decoder_config.channel_count; | 428 audio_channel_count_ = pp_decoder_config.channel_count; |
| 411 audio_bytes_per_frame_ = decoder_config.bytes_per_frame(); | |
| 412 | 429 |
| 413 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; | 430 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; |
| 414 if (!MakeBufferResource(pp_instance_, | 431 if (!MakeBufferResource(pp_instance_, |
| 415 decoder_config.extra_data(), | 432 decoder_config.extra_data(), |
| 416 decoder_config.extra_data_size(), | 433 decoder_config.extra_data_size(), |
| 417 &extra_data_resource)) { | 434 &extra_data_resource)) { |
| 418 return false; | 435 return false; |
| 419 } | 436 } |
| 420 ScopedPPResource pp_resource(extra_data_resource.get()); | 437 ScopedPPResource pp_resource(extra_data_resource.get()); |
| 421 | 438 |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 845 ppb_buffer, | 862 ppb_buffer, |
| 846 base::Bind(&ContentDecryptorDelegate::FreeBuffer, | 863 base::Bind(&ContentDecryptorDelegate::FreeBuffer, |
| 847 weak_this_, | 864 weak_this_, |
| 848 frame_info->tracking_info.buffer_id)))); | 865 frame_info->tracking_info.buffer_id)))); |
| 849 | 866 |
| 850 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); | 867 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); |
| 851 } | 868 } |
| 852 | 869 |
| 853 void ContentDecryptorDelegate::DeliverSamples( | 870 void ContentDecryptorDelegate::DeliverSamples( |
| 854 PP_Resource audio_frames, | 871 PP_Resource audio_frames, |
| 855 const PP_DecryptedBlockInfo* block_info) { | 872 const PP_DecryptedSampleInfo* sample_info) { |
| 856 DCHECK(block_info); | 873 DCHECK(sample_info); |
| 857 | 874 |
| 858 FreeBuffer(block_info->tracking_info.buffer_id); | 875 FreeBuffer(sample_info->tracking_info.buffer_id); |
| 859 | 876 |
| 860 const uint32_t request_id = block_info->tracking_info.request_id; | 877 const uint32_t request_id = sample_info->tracking_info.request_id; |
| 861 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; | 878 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; |
| 862 | 879 |
| 863 // If the request ID is not valid or does not match what's saved, do nothing. | 880 // If the request ID is not valid or does not match what's saved, do nothing. |
| 864 if (request_id == 0 || request_id != pending_audio_decode_request_id_) { | 881 if (request_id == 0 || request_id != pending_audio_decode_request_id_) { |
| 865 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; | 882 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; |
| 866 return; | 883 return; |
| 867 } | 884 } |
| 868 | 885 |
| 869 DCHECK(!pending_audio_decode_cb_.is_null()); | 886 DCHECK(!pending_audio_decode_cb_.is_null()); |
| 870 pending_audio_decode_request_id_ = 0; | 887 pending_audio_decode_request_id_ = 0; |
| 871 media::Decryptor::AudioDecodeCB audio_decode_cb = | 888 media::Decryptor::AudioDecodeCB audio_decode_cb = |
| 872 base::ResetAndReturn(&pending_audio_decode_cb_); | 889 base::ResetAndReturn(&pending_audio_decode_cb_); |
| 873 | 890 |
| 874 const media::Decryptor::AudioBuffers empty_frames; | 891 const media::Decryptor::AudioBuffers empty_frames; |
| 875 | 892 |
| 876 media::Decryptor::Status status = | 893 media::Decryptor::Status status = |
| 877 PpDecryptResultToMediaDecryptorStatus(block_info->result); | 894 PpDecryptResultToMediaDecryptorStatus(sample_info->result); |
| 878 if (status != media::Decryptor::kSuccess) { | 895 if (status != media::Decryptor::kSuccess) { |
| 879 audio_decode_cb.Run(status, empty_frames); | 896 audio_decode_cb.Run(status, empty_frames); |
| 880 return; | 897 return; |
| 881 } | 898 } |
| 882 | 899 |
| 900 media::SampleFormat sample_format = | |
| 901 PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format); | |
| 902 | |
| 883 media::Decryptor::AudioBuffers audio_frame_list; | 903 media::Decryptor::AudioBuffers audio_frame_list; |
| 884 if (!DeserializeAudioFrames(audio_frames, | 904 if (!DeserializeAudioFrames(audio_frames, |
| 885 block_info->data_size, | 905 sample_info->data_size, |
| 906 sample_format, | |
| 886 &audio_frame_list)) { | 907 &audio_frame_list)) { |
| 887 NOTREACHED() << "CDM did not serialize the buffer correctly."; | 908 NOTREACHED() << "CDM did not serialize the buffer correctly."; |
| 888 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); | 909 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); |
| 889 return; | 910 return; |
| 890 } | 911 } |
| 891 | 912 |
| 892 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); | 913 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); |
| 893 } | 914 } |
| 894 | 915 |
| 895 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). | 916 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 if (free_buffers_.empty()) | 1009 if (free_buffers_.empty()) |
| 989 return; | 1010 return; |
| 990 | 1011 |
| 991 tracking_info->buffer_id = free_buffers_.front(); | 1012 tracking_info->buffer_id = free_buffers_.front(); |
| 992 free_buffers_.pop(); | 1013 free_buffers_.pop(); |
| 993 } | 1014 } |
| 994 | 1015 |
| 995 bool ContentDecryptorDelegate::DeserializeAudioFrames( | 1016 bool ContentDecryptorDelegate::DeserializeAudioFrames( |
| 996 PP_Resource audio_frames, | 1017 PP_Resource audio_frames, |
| 997 size_t data_size, | 1018 size_t data_size, |
| 1019 media::SampleFormat sample_format, | |
| 998 media::Decryptor::AudioBuffers* frames) { | 1020 media::Decryptor::AudioBuffers* frames) { |
| 999 DCHECK(frames); | 1021 DCHECK(frames); |
| 1000 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); | 1022 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); |
| 1001 if (!enter.succeeded()) | 1023 if (!enter.succeeded()) |
| 1002 return false; | 1024 return false; |
| 1003 | 1025 |
| 1004 BufferAutoMapper mapper(enter.object()); | 1026 BufferAutoMapper mapper(enter.object()); |
| 1005 if (!mapper.data() || !mapper.size() || | 1027 if (!mapper.data() || !mapper.size() || |
| 1006 mapper.size() < static_cast<uint32_t>(data_size)) | 1028 mapper.size() < static_cast<uint32_t>(data_size)) |
| 1007 return false; | 1029 return false; |
| 1008 | 1030 |
| 1009 // TODO(jrummell): Pass ownership of data() directly to AudioBuffer to avoid | 1031 // TODO(jrummell): Pass ownership of data() directly to AudioBuffer to avoid |
| 1010 // the copy. Since it is possible to get multiple buffers, it would need to be | 1032 // the copy. Since it is possible to get multiple buffers, it would need to be |
| 1011 // sliced and ref counted appropriately. http://crbug.com/255576. | 1033 // sliced and ref counted appropriately. http://crbug.com/255576. |
| 1012 const uint8* cur = static_cast<uint8*>(mapper.data()); | 1034 const uint8* cur = static_cast<uint8*>(mapper.data()); |
| 1013 size_t bytes_left = data_size; | 1035 size_t bytes_left = data_size; |
| 1014 | 1036 |
| 1037 const int audio_bytes_per_frame = | |
| 1038 media::SampleFormatToBytesPerChannel(sample_format) * | |
| 1039 audio_channel_count_; | |
| 1040 | |
| 1041 // Allocate space for the channel pointers given to AudioBuffer. | |
| 1042 int num_channel_ptrs = 1; | |
|
xhwang
2013/10/11 22:45:16
A brief comment why the default is 1? Interleaved
DaleCurtis
2013/10/12 01:51:05
Removed in favor of letting CopyFrom() handle samp
| |
| 1043 if (sample_format == media::kSampleFormatPlanarS16 || | |
| 1044 sample_format == media::kSampleFormatPlanarF32) { | |
| 1045 num_channel_ptrs = audio_channel_count_; | |
| 1046 } | |
| 1047 scoped_ptr<const uint8*[]> channel_ptrs(new const uint8*[num_channel_ptrs]); | |
| 1048 | |
| 1015 do { | 1049 do { |
| 1016 int64 timestamp = 0; | 1050 int64 timestamp = 0; |
| 1017 int64 frame_size = -1; | 1051 int64 frame_size = -1; |
| 1018 const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size); | 1052 const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size); |
| 1019 | 1053 |
| 1020 if (bytes_left < kHeaderSize) | 1054 if (bytes_left < kHeaderSize) |
| 1021 return false; | 1055 return false; |
| 1022 | 1056 |
| 1023 memcpy(×tamp, cur, sizeof(timestamp)); | 1057 memcpy(×tamp, cur, sizeof(timestamp)); |
| 1024 cur += sizeof(timestamp); | 1058 cur += sizeof(timestamp); |
| 1025 bytes_left -= sizeof(timestamp); | 1059 bytes_left -= sizeof(timestamp); |
| 1026 | 1060 |
| 1027 memcpy(&frame_size, cur, sizeof(frame_size)); | 1061 memcpy(&frame_size, cur, sizeof(frame_size)); |
| 1028 cur += sizeof(frame_size); | 1062 cur += sizeof(frame_size); |
| 1029 bytes_left -= sizeof(frame_size); | 1063 bytes_left -= sizeof(frame_size); |
| 1030 | 1064 |
| 1031 // We should *not* have empty frames in the list. | 1065 // We should *not* have empty frames in the list. |
| 1032 if (frame_size <= 0 || | 1066 if (frame_size <= 0 || |
| 1033 bytes_left < base::checked_numeric_cast<size_t>(frame_size)) { | 1067 bytes_left < base::checked_numeric_cast<size_t>(frame_size)) { |
| 1034 return false; | 1068 return false; |
| 1035 } | 1069 } |
| 1036 | 1070 |
| 1037 const uint8* data[] = {cur}; | 1071 // Setup channel pointers. |
| 1038 int frame_count = frame_size / audio_bytes_per_frame_; | 1072 const int size_per_channel = frame_size / audio_channel_count_; |
| 1073 for (int i = 0; i < num_channel_ptrs; ++i) | |
| 1074 channel_ptrs[i] = cur + i * size_per_channel; | |
| 1075 | |
| 1076 const int frame_count = frame_size / audio_bytes_per_frame; | |
| 1039 scoped_refptr<media::AudioBuffer> frame = media::AudioBuffer::CopyFrom( | 1077 scoped_refptr<media::AudioBuffer> frame = media::AudioBuffer::CopyFrom( |
| 1040 audio_sample_format_, | 1078 sample_format, |
| 1041 audio_channel_count_, | 1079 audio_channel_count_, |
| 1042 frame_count, | 1080 frame_count, |
| 1043 data, | 1081 channel_ptrs.get(), |
| 1044 base::TimeDelta::FromMicroseconds(timestamp), | 1082 base::TimeDelta::FromMicroseconds(timestamp), |
| 1045 base::TimeDelta::FromMicroseconds(audio_samples_per_second_ / | 1083 base::TimeDelta::FromMicroseconds(audio_samples_per_second_ / |
| 1046 frame_count)); | 1084 frame_count)); |
| 1047 frames->push_back(frame); | 1085 frames->push_back(frame); |
| 1048 | 1086 |
| 1049 cur += frame_size; | 1087 cur += frame_size; |
| 1050 bytes_left -= frame_size; | 1088 bytes_left -= frame_size; |
| 1051 } while (bytes_left > 0); | 1089 } while (bytes_left > 0); |
| 1052 | 1090 |
| 1053 return true; | 1091 return true; |
| 1054 } | 1092 } |
| 1055 | 1093 |
| 1056 } // namespace content | 1094 } // namespace content |
| OLD | NEW |