Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Side by Side Diff: content/renderer/pepper/content_decryptor_delegate.cc

Issue 26956002: Plumb support for audio sample formats. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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(&timestamp, cur, sizeof(timestamp)); 1057 memcpy(&timestamp, 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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698