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 |