summaryrefslogtreecommitdiffstats
path: root/webkit/plugins/ppapi/content_decryptor_delegate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/plugins/ppapi/content_decryptor_delegate.cc')
-rw-r--r--webkit/plugins/ppapi/content_decryptor_delegate.cc124
1 files changed, 73 insertions, 51 deletions
diff --git a/webkit/plugins/ppapi/content_decryptor_delegate.cc b/webkit/plugins/ppapi/content_decryptor_delegate.cc
index 1d3658a..6225a02 100644
--- a/webkit/plugins/ppapi/content_decryptor_delegate.cc
+++ b/webkit/plugins/ppapi/content_decryptor_delegate.cc
@@ -7,6 +7,8 @@
#include "base/callback_helpers.h"
#include "base/debug/trace_event.h"
#include "base/message_loop/message_loop_proxy.h"
+#include "base/safe_numerics.h"
+#include "media/base/audio_buffer.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/bind_to_loop.h"
#include "media/base/channel_layout.h"
@@ -127,56 +129,6 @@ static bool MakeEncryptedBlockInfo(
return true;
}
-// Deserializes audio data stored in |audio_frames| into individual audio
-// buffers in |frames|. Returns true upon success.
-bool DeserializeAudioFrames(PP_Resource audio_frames,
- int data_size,
- media::Decryptor::AudioBuffers* frames) {
- DCHECK(frames);
- EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true);
- if (!enter.succeeded())
- return false;
-
- BufferAutoMapper mapper(enter.object());
- if (!mapper.data() || !mapper.size() ||
- mapper.size() < static_cast<uint32_t>(data_size))
- return false;
-
- const uint8* cur = static_cast<uint8*>(mapper.data());
- int bytes_left = data_size;
-
- do {
- int64 timestamp = 0;
- int64 frame_size = -1;
- const int kHeaderSize = sizeof(timestamp) + sizeof(frame_size);
-
- if (bytes_left < kHeaderSize)
- return false;
-
- memcpy(&timestamp, cur, sizeof(timestamp));
- cur += sizeof(timestamp);
- bytes_left -= sizeof(timestamp);
-
- memcpy(&frame_size, cur, sizeof(frame_size));
- cur += sizeof(frame_size);
- bytes_left -= sizeof(frame_size);
-
- // We should *not* have empty frame in the list.
- if (frame_size <= 0 || bytes_left < frame_size)
- return false;
-
- scoped_refptr<media::DataBuffer> frame =
- media::DataBuffer::CopyFrom(cur, frame_size);
- frame->set_timestamp(base::TimeDelta::FromMicroseconds(timestamp));
- frames->push_back(frame);
-
- cur += frame_size;
- bytes_left -= frame_size;
- } while (bytes_left > 0);
-
- return true;
-}
-
PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) {
switch (codec) {
case media::kCodecVorbis:
@@ -282,7 +234,11 @@ ContentDecryptorDelegate::ContentDecryptorDelegate(
pending_audio_decode_request_id_(0),
pending_video_decode_request_id_(0),
weak_ptr_factory_(this),
- weak_this_(weak_ptr_factory_.GetWeakPtr()) {
+ weak_this_(weak_ptr_factory_.GetWeakPtr()),
+ audio_sample_format_(media::kUnknownSampleFormat),
+ audio_samples_per_second_(0),
+ audio_channel_count_(0),
+ audio_bytes_per_frame_(0) {
}
void ContentDecryptorDelegate::Initialize(const std::string& key_system) {
@@ -442,6 +398,11 @@ bool ContentDecryptorDelegate::InitializeAudioDecoder(
pp_decoder_config.samples_per_second = decoder_config.samples_per_second();
pp_decoder_config.request_id = next_decryption_request_id_++;
+ audio_sample_format_ = decoder_config.sample_format();
+ audio_samples_per_second_ = pp_decoder_config.samples_per_second;
+ audio_channel_count_ = pp_decoder_config.channel_count;
+ audio_bytes_per_frame_ = decoder_config.bytes_per_frame();
+
scoped_refptr<PPB_Buffer_Impl> extra_data_resource;
if (!MakeBufferResource(pp_instance_,
decoder_config.extra_data(),
@@ -1022,5 +983,66 @@ void ContentDecryptorDelegate::SetBufferToFreeInTrackingInfo(
free_buffers_.pop();
}
+bool ContentDecryptorDelegate::DeserializeAudioFrames(
+ PP_Resource audio_frames,
+ size_t data_size,
+ media::Decryptor::AudioBuffers* frames) {
+ DCHECK(frames);
+ EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true);
+ if (!enter.succeeded())
+ return false;
+
+ BufferAutoMapper mapper(enter.object());
+ if (!mapper.data() || !mapper.size() ||
+ mapper.size() < static_cast<uint32_t>(data_size))
+ return false;
+
+ // TODO(jrummell): Pass ownership of data() directly to AudioBuffer to avoid
+ // the copy. Since it is possible to get multiple buffers, it would need to be
+ // sliced and ref counted appropriately. http://crbug.com/255576.
+ const uint8* cur = static_cast<uint8*>(mapper.data());
+ size_t bytes_left = data_size;
+
+ do {
+ int64 timestamp = 0;
+ int64 frame_size = -1;
+ const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size);
+
+ if (bytes_left < kHeaderSize)
+ return false;
+
+ memcpy(&timestamp, cur, sizeof(timestamp));
+ cur += sizeof(timestamp);
+ bytes_left -= sizeof(timestamp);
+
+ memcpy(&frame_size, cur, sizeof(frame_size));
+ cur += sizeof(frame_size);
+ bytes_left -= sizeof(frame_size);
+
+ // We should *not* have empty frames in the list.
+ if (frame_size <= 0 ||
+ bytes_left < base::checked_numeric_cast<size_t>(frame_size)) {
+ return false;
+ }
+
+ const uint8* data[] = {cur};
+ int frame_count = frame_size / audio_bytes_per_frame_;
+ scoped_refptr<media::AudioBuffer> frame = media::AudioBuffer::CopyFrom(
+ audio_sample_format_,
+ audio_channel_count_,
+ frame_count,
+ data,
+ base::TimeDelta::FromMicroseconds(timestamp),
+ base::TimeDelta::FromMicroseconds(audio_samples_per_second_ /
+ frame_count));
+ frames->push_back(frame);
+
+ cur += frame_size;
+ bytes_left -= frame_size;
+ } while (bytes_left > 0);
+
+ return true;
+}
+
} // namespace ppapi
} // namespace webkit