summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webkit/glue/webkit_glue.gypi2
-rw-r--r--webkit/media/crypto/ppapi_decryptor.cc58
-rw-r--r--webkit/media/crypto/ppapi_decryptor.h14
-rw-r--r--webkit/media/crypto/proxy_decryptor.cc2
-rw-r--r--webkit/plugins/ppapi/content_decryptor_delegate.cc871
-rw-r--r--webkit/plugins/ppapi/content_decryptor_delegate.h132
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.cc859
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.h84
8 files changed, 1100 insertions, 922 deletions
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index 4f39a61..c8e36f8 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -164,6 +164,8 @@
'../plugins/ppapi/audio_helper.cc',
'../plugins/ppapi/audio_helper.h',
'../plugins/ppapi/common.h',
+ '../plugins/ppapi/content_decryptor_delegate.cc',
+ '../plugins/ppapi/content_decryptor_delegate.h',
'../plugins/ppapi/event_conversion.cc',
'../plugins/ppapi/event_conversion.h',
'../plugins/ppapi/file_callbacks.cc',
diff --git a/webkit/media/crypto/ppapi_decryptor.cc b/webkit/media/crypto/ppapi_decryptor.cc
index 5da0800..836f71d 100644
--- a/webkit/media/crypto/ppapi_decryptor.cc
+++ b/webkit/media/crypto/ppapi_decryptor.cc
@@ -18,25 +18,29 @@
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
#include "webkit/media/crypto/key_systems.h"
+#include "webkit/plugins/ppapi/content_decryptor_delegate.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
namespace webkit_media {
PpapiDecryptor::PpapiDecryptor(
- media::DecryptorClient* client,
- const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance)
+ media::DecryptorClient* client,
+ const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance)
: client_(client),
- cdm_plugin_(plugin_instance),
+ plugin_instance_(plugin_instance),
+ plugin_cdm_delegate_(NULL),
render_loop_proxy_(base::MessageLoopProxy::current()),
weak_ptr_factory_(this),
weak_this_(weak_ptr_factory_.GetWeakPtr()) {
DCHECK(client_);
- DCHECK(cdm_plugin_);
- cdm_plugin_->set_decrypt_client(client);
+ DCHECK(plugin_instance_);
}
PpapiDecryptor::~PpapiDecryptor() {
- cdm_plugin_->set_decrypt_client(NULL);
+ if (plugin_cdm_delegate_)
+ plugin_cdm_delegate_->set_decrypt_client(NULL);
+ plugin_cdm_delegate_ = NULL;
+ plugin_instance_ = NULL;
}
bool PpapiDecryptor::GenerateKeyRequest(const std::string& key_system,
@@ -45,11 +49,19 @@ bool PpapiDecryptor::GenerateKeyRequest(const std::string& key_system,
int init_data_length) {
DVLOG(2) << "GenerateKeyRequest()";
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- DCHECK(cdm_plugin_);
+
+ if (!plugin_cdm_delegate_) {
+ plugin_cdm_delegate_ = plugin_instance_->GetContentDecryptorDelegate();
+ if (!plugin_cdm_delegate_) {
+ DVLOG(1) << "PpapiDecryptor: plugin cdm delegate creation failed.";
+ return false;
+ }
+ plugin_cdm_delegate_->set_decrypt_client(client_);
+ }
// TODO(xhwang): Finalize the data type for |init_data| to avoid unnecessary
// data type conversions.
- if (!cdm_plugin_->GenerateKeyRequest(
+ if (!plugin_cdm_delegate_->GenerateKeyRequest(
key_system,
type,
std::string(reinterpret_cast<const char*>(init_data),
@@ -69,13 +81,12 @@ void PpapiDecryptor::AddKey(const std::string& key_system,
const std::string& session_id) {
DVLOG(2) << "AddKey()";
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- DCHECK(cdm_plugin_);
- if (!cdm_plugin_->AddKey(session_id,
- std::string(reinterpret_cast<const char*>(key),
- key_length),
- std::string(reinterpret_cast<const char*>(init_data),
- init_data_length))) {
+ if (!plugin_cdm_delegate_->AddKey(
+ session_id,
+ std::string(reinterpret_cast<const char*>(key), key_length),
+ std::string(reinterpret_cast<const char*>(init_data),
+ init_data_length))) {
ReportFailureToCallPlugin(key_system, session_id);
}
@@ -90,9 +101,8 @@ void PpapiDecryptor::CancelKeyRequest(const std::string& key_system,
const std::string& session_id) {
DVLOG(2) << "CancelKeyRequest()";
DCHECK(render_loop_proxy_->BelongsToCurrentThread());
- DCHECK(cdm_plugin_);
- if (!cdm_plugin_->CancelKeyRequest(session_id))
+ if (!plugin_cdm_delegate_->CancelKeyRequest(session_id))
ReportFailureToCallPlugin(key_system, session_id);
}
@@ -122,13 +132,13 @@ void PpapiDecryptor::Decrypt(
}
DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
- if (!cdm_plugin_->Decrypt(stream_type, encrypted, decrypt_cb))
+ if (!plugin_cdm_delegate_->Decrypt(stream_type, encrypted, decrypt_cb))
decrypt_cb.Run(kError, NULL);
}
void PpapiDecryptor::CancelDecrypt(StreamType stream_type) {
DVLOG(1) << "CancelDecrypt() - stream_type: " << stream_type;
- cdm_plugin_->CancelDecrypt(stream_type);
+ plugin_cdm_delegate_->CancelDecrypt(stream_type);
}
void PpapiDecryptor::InitializeAudioDecoder(
@@ -146,7 +156,7 @@ void PpapiDecryptor::InitializeAudioDecoder(
DCHECK(config->IsValidConfig());
audio_decoder_init_cb_ = init_cb;
- if (!cdm_plugin_->InitializeAudioDecoder(*config, base::Bind(
+ if (!plugin_cdm_delegate_->InitializeAudioDecoder(*config, base::Bind(
&PpapiDecryptor::OnDecoderInitialized, weak_this_, kAudio))) {
base::ResetAndReturn(&audio_decoder_init_cb_).Run(false);
return;
@@ -168,7 +178,7 @@ void PpapiDecryptor::InitializeVideoDecoder(
DCHECK(config->IsValidConfig());
video_decoder_init_cb_ = init_cb;
- if (!cdm_plugin_->InitializeVideoDecoder(*config, base::Bind(
+ if (!plugin_cdm_delegate_->InitializeVideoDecoder(*config, base::Bind(
&PpapiDecryptor::OnDecoderInitialized, weak_this_, kVideo))) {
base::ResetAndReturn(&video_decoder_init_cb_).Run(false);
return;
@@ -186,7 +196,7 @@ void PpapiDecryptor::DecryptAndDecodeAudio(
}
DVLOG(1) << "DecryptAndDecodeAudio()";
- if (!cdm_plugin_->DecryptAndDecodeAudio(encrypted, audio_decode_cb))
+ if (!plugin_cdm_delegate_->DecryptAndDecodeAudio(encrypted, audio_decode_cb))
audio_decode_cb.Run(kError, AudioBuffers());
}
@@ -201,7 +211,7 @@ void PpapiDecryptor::DecryptAndDecodeVideo(
}
DVLOG(3) << "DecryptAndDecodeVideo()";
- if (!cdm_plugin_->DecryptAndDecodeVideo(encrypted, video_decode_cb))
+ if (!plugin_cdm_delegate_->DecryptAndDecodeVideo(encrypted, video_decode_cb))
video_decode_cb.Run(kError, NULL);
}
@@ -213,7 +223,7 @@ void PpapiDecryptor::ResetDecoder(StreamType stream_type) {
}
DVLOG(2) << "ResetDecoder() - stream_type: " << stream_type;
- cdm_plugin_->ResetDecoder(stream_type);
+ plugin_cdm_delegate_->ResetDecoder(stream_type);
}
void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) {
@@ -224,7 +234,7 @@ void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) {
}
DVLOG(2) << "DeinitializeDecoder() - stream_type: " << stream_type;
- cdm_plugin_->DeinitializeDecoder(stream_type);
+ plugin_cdm_delegate_->DeinitializeDecoder(stream_type);
}
void PpapiDecryptor::ReportFailureToCallPlugin(const std::string& key_system,
diff --git a/webkit/media/crypto/ppapi_decryptor.h b/webkit/media/crypto/ppapi_decryptor.h
index 4ac5c1e..63b536b 100644
--- a/webkit/media/crypto/ppapi_decryptor.h
+++ b/webkit/media/crypto/ppapi_decryptor.h
@@ -22,6 +22,7 @@ class DecryptorClient;
namespace webkit {
namespace ppapi {
+class ContentDecryptorDelegate;
class PluginInstance;
}
}
@@ -34,8 +35,8 @@ namespace webkit_media {
class PpapiDecryptor : public media::Decryptor {
public:
PpapiDecryptor(
- media::DecryptorClient* client,
- const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance);
+ media::DecryptorClient* client,
+ const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance);
virtual ~PpapiDecryptor();
// media::Decryptor implementation.
@@ -79,7 +80,14 @@ class PpapiDecryptor : public media::Decryptor {
void OnDecoderInitialized(StreamType stream_type, bool success);
media::DecryptorClient* client_;
- scoped_refptr<webkit::ppapi::PluginInstance> cdm_plugin_;
+
+ // Hold a reference of the plugin instance to make sure the plugin outlives
+ // the |plugin_cdm_delegate_|. This is needed because |plugin_cdm_delegate_|
+ // is owned by the |plugin_instance_|.
+ scoped_refptr<webkit::ppapi::PluginInstance> plugin_instance_;
+
+ webkit::ppapi::ContentDecryptorDelegate* plugin_cdm_delegate_;
+
scoped_refptr<base::MessageLoopProxy> render_loop_proxy_;
DecoderInitCB audio_decoder_init_cb_;
diff --git a/webkit/media/crypto/proxy_decryptor.cc b/webkit/media/crypto/proxy_decryptor.cc
index 12dd3b6..ddf186a 100644
--- a/webkit/media/crypto/proxy_decryptor.cc
+++ b/webkit/media/crypto/proxy_decryptor.cc
@@ -257,7 +257,7 @@ scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor(
const scoped_refptr<webkit::ppapi::PluginInstance>& plugin_instance =
CreatePluginInstance(plugin_type, web_media_player_client_, web_frame_);
if (!plugin_instance) {
- DVLOG(1) << "PpapiDecryptor: plugin instance creation failed.";
+ DVLOG(1) << "ProxyDecryptor: plugin instance creation failed.";
return scoped_ptr<media::Decryptor>();
}
diff --git a/webkit/plugins/ppapi/content_decryptor_delegate.cc b/webkit/plugins/ppapi/content_decryptor_delegate.cc
new file mode 100644
index 0000000..3c00865
--- /dev/null
+++ b/webkit/plugins/ppapi/content_decryptor_delegate.cc
@@ -0,0 +1,871 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/plugins/ppapi/content_decryptor_delegate.h"
+
+#include "base/callback_helpers.h"
+#include "base/debug/trace_event.h"
+#include "media/base/audio_decoder_config.h"
+#include "media/base/channel_layout.h"
+#include "media/base/data_buffer.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/decryptor_client.h"
+#include "media/base/video_decoder_config.h"
+#include "media/base/video_frame.h"
+#include "media/base/video_util.h"
+#include "ppapi/shared_impl/scoped_pp_resource.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_buffer_api.h"
+#include "webkit/plugins/ppapi/ppb_buffer_impl.h"
+
+using ppapi::PpapiGlobals;
+using ppapi::ScopedPPResource;
+using ppapi::StringVar;
+using ppapi::thunk::EnterResourceNoLock;
+using ppapi::thunk::PPB_Buffer_API;
+
+namespace webkit {
+namespace ppapi {
+
+namespace {
+
+// Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the
+// buffer resource, and returns it. Returns a an invalid PP_Resource with an ID
+// of 0 on failure. Upon success, the returned Buffer resource has a reference
+// count of 1.
+PP_Resource MakeBufferResource(PP_Instance instance,
+ const uint8* data, int size) {
+ if (!data || !size)
+ return 0;
+
+ ScopedPPResource resource(PPB_Buffer_Impl::Create(instance, size));
+ if (!resource.get())
+ return 0;
+
+ EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
+ if (enter.failed())
+ return 0;
+
+ BufferAutoMapper mapper(enter.object());
+ if (!mapper.data() || mapper.size() < static_cast<size_t>(size))
+ return 0;
+
+ memcpy(mapper.data(), data, size);
+ return resource.get();
+}
+
+// Copies the content of |str| into |array|.
+// Returns true if copy succeeded. Returns false if copy failed, e.g. if the
+// |array_size| is smaller than the |str| length.
+template <uint32_t array_size>
+bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) {
+ if (array_size < str.size())
+ return false;
+
+ memcpy(array, str.data(), str.size());
+ return true;
+}
+
+// Fills the |block_info| with information from |decrypt_config|, |timestamp|
+// and |request_id|. |decrypt_config| can be NULL if the block is not encrypted.
+// This is useful for end-of-stream blocks.
+// Returns true if |block_info| is successfully filled. Returns false
+// otherwise.
+bool MakeEncryptedBlockInfo(
+ const media::DecryptConfig* decrypt_config,
+ int64_t timestamp,
+ uint32_t request_id,
+ PP_EncryptedBlockInfo* block_info) {
+ DCHECK(block_info);
+
+ // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and
+ // anywhere else.
+ memset(block_info, 0, sizeof(*block_info));
+
+ block_info->tracking_info.request_id = request_id;
+ block_info->tracking_info.timestamp = timestamp;
+
+ if (!decrypt_config)
+ return true;
+
+ block_info->data_offset = decrypt_config->data_offset();
+
+ if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) ||
+ !CopyStringToArray(decrypt_config->iv(), block_info->iv))
+ return false;
+
+ block_info->key_id_size = decrypt_config->key_id().size();
+ block_info->iv_size = decrypt_config->iv().size();
+
+ if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples))
+ return false;
+
+ block_info->num_subsamples = decrypt_config->subsamples().size();
+ for (uint32_t i = 0; i < block_info->num_subsamples; ++i) {
+ block_info->subsamples[i].clear_bytes =
+ decrypt_config->subsamples()[i].clear_bytes;
+ block_info->subsamples[i].cipher_bytes =
+ decrypt_config->subsamples()[i].cypher_bytes;
+ }
+
+ 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,
+ 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())
+ return false;
+
+ const uint8* cur = static_cast<uint8*>(mapper.data());
+ int bytes_left = mapper.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(new media::DataBuffer(cur,
+ frame_size));
+ frame->SetTimestamp(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:
+ return PP_AUDIOCODEC_VORBIS;
+ case media::kCodecAAC:
+ return PP_AUDIOCODEC_AAC;
+ default:
+ return PP_AUDIOCODEC_UNKNOWN;
+ }
+}
+
+PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) {
+ switch (codec) {
+ case media::kCodecVP8:
+ return PP_VIDEOCODEC_VP8;
+ case media::kCodecH264:
+ return PP_VIDEOCODEC_H264;
+ default:
+ return PP_VIDEOCODEC_UNKNOWN;
+ }
+}
+
+PP_VideoCodecProfile MediaVideoCodecProfileToPpVideoCodecProfile(
+ media::VideoCodecProfile profile) {
+ switch (profile) {
+ case media::VP8PROFILE_MAIN:
+ return PP_VIDEOCODECPROFILE_VP8_MAIN;
+ case media::H264PROFILE_BASELINE:
+ return PP_VIDEOCODECPROFILE_H264_BASELINE;
+ case media::H264PROFILE_MAIN:
+ return PP_VIDEOCODECPROFILE_H264_MAIN;
+ case media::H264PROFILE_EXTENDED:
+ return PP_VIDEOCODECPROFILE_H264_EXTENDED;
+ case media::H264PROFILE_HIGH:
+ return PP_VIDEOCODECPROFILE_H264_HIGH;
+ case media::H264PROFILE_HIGH10PROFILE:
+ return PP_VIDEOCODECPROFILE_H264_HIGH_10;
+ case media::H264PROFILE_HIGH422PROFILE:
+ return PP_VIDEOCODECPROFILE_H264_HIGH_422;
+ case media::H264PROFILE_HIGH444PREDICTIVEPROFILE:
+ return PP_VIDEOCODECPROFILE_H264_HIGH_444_PREDICTIVE;
+ default:
+ return PP_VIDEOCODECPROFILE_UNKNOWN;
+ }
+}
+
+PP_DecryptedFrameFormat MediaVideoFormatToPpDecryptedFrameFormat(
+ media::VideoFrame::Format format) {
+ switch (format) {
+ case media::VideoFrame::YV12:
+ return PP_DECRYPTEDFRAMEFORMAT_YV12;
+ case media::VideoFrame::I420:
+ return PP_DECRYPTEDFRAMEFORMAT_I420;
+ default:
+ return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN;
+ }
+}
+
+media::Decryptor::Status PpDecryptResultToMediaDecryptorStatus(
+ PP_DecryptResult result) {
+ switch (result) {
+ case PP_DECRYPTRESULT_SUCCESS:
+ return media::Decryptor::kSuccess;
+ case PP_DECRYPTRESULT_DECRYPT_NOKEY:
+ return media::Decryptor::kNoKey;
+ case PP_DECRYPTRESULT_NEEDMOREDATA:
+ return media::Decryptor::kNeedMoreData;
+ case PP_DECRYPTRESULT_DECRYPT_ERROR:
+ return media::Decryptor::kError;
+ case PP_DECRYPTRESULT_DECODE_ERROR:
+ return media::Decryptor::kError;
+ default:
+ NOTREACHED();
+ return media::Decryptor::kError;
+ }
+}
+
+PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType(
+ media::Decryptor::StreamType stream_type) {
+ switch (stream_type) {
+ case media::Decryptor::kAudio:
+ return PP_DECRYPTORSTREAMTYPE_AUDIO;
+ case media::Decryptor::kVideo:
+ return PP_DECRYPTORSTREAMTYPE_VIDEO;
+ default:
+ NOTREACHED();
+ return PP_DECRYPTORSTREAMTYPE_VIDEO;
+ }
+}
+
+} // namespace
+
+ContentDecryptorDelegate::ContentDecryptorDelegate(
+ PP_Instance pp_instance,
+ const PPP_ContentDecryptor_Private* plugin_decryption_interface)
+ : pp_instance_(pp_instance),
+ plugin_decryption_interface_(plugin_decryption_interface),
+ decryptor_client_(NULL),
+ next_decryption_request_id_(1),
+ pending_audio_decrypt_request_id_(0),
+ pending_video_decrypt_request_id_(0),
+ pending_audio_decoder_init_request_id_(0),
+ pending_video_decoder_init_request_id_(0),
+ pending_audio_decode_request_id_(0),
+ pending_video_decode_request_id_(0) {
+}
+
+void ContentDecryptorDelegate::set_decrypt_client(
+ media::DecryptorClient* decryptor_client) {
+ decryptor_client_ = decryptor_client;
+}
+
+bool ContentDecryptorDelegate::GenerateKeyRequest(
+ const std::string& key_system,
+ const std::string& type,
+ const std::string& init_data) {
+ if (key_system.empty())
+ return false;
+
+ PP_Var init_data_array =
+ PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
+ init_data.size(), init_data.data());
+
+ plugin_decryption_interface_->GenerateKeyRequest(
+ pp_instance_,
+ StringVar::StringToPPVar(key_system),
+ StringVar::StringToPPVar(type),
+ init_data_array);
+ return true;
+}
+
+bool ContentDecryptorDelegate::AddKey(const std::string& session_id,
+ const std::string& key,
+ const std::string& init_data) {
+ PP_Var key_array =
+ PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(key.size(),
+ key.data());
+ PP_Var init_data_array =
+ PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
+ init_data.size(),
+ init_data.data());
+
+ plugin_decryption_interface_->AddKey(
+ pp_instance_,
+ StringVar::StringToPPVar(session_id),
+ key_array,
+ init_data_array);
+ return true;
+}
+
+bool ContentDecryptorDelegate::CancelKeyRequest(const std::string& session_id) {
+ plugin_decryption_interface_->CancelKeyRequest(
+ pp_instance_,
+ StringVar::StringToPPVar(session_id));
+ return true;
+}
+
+// TODO(xhwang): Remove duplication of code in Decrypt(),
+// DecryptAndDecodeAudio() and DecryptAndDecodeVideo().
+bool ContentDecryptorDelegate::Decrypt(
+ media::Decryptor::StreamType stream_type,
+ const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
+ const media::Decryptor::DecryptCB& decrypt_cb) {
+ DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
+ ScopedPPResource encrypted_resource(
+ ScopedPPResource::PassRef(),
+ MakeBufferResource(pp_instance_,
+ encrypted_buffer->GetData(),
+ encrypted_buffer->GetDataSize()));
+ if (!encrypted_resource.get())
+ return false;
+
+ const uint32_t request_id = next_decryption_request_id_++;
+ DVLOG(2) << "Decrypt() - request_id " << request_id;
+
+ PP_EncryptedBlockInfo block_info;
+ DCHECK(encrypted_buffer->GetDecryptConfig());
+ if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(),
+ encrypted_buffer->GetTimestamp().InMicroseconds(),
+ request_id,
+ &block_info)) {
+ return false;
+ }
+
+ // There is only one pending decrypt request at any time per stream. This is
+ // enforced by the media pipeline.
+ switch (stream_type) {
+ case media::Decryptor::kAudio:
+ DCHECK_EQ(pending_audio_decrypt_request_id_, 0u);
+ DCHECK(pending_audio_decrypt_cb_.is_null());
+ pending_audio_decrypt_request_id_ = request_id;
+ pending_audio_decrypt_cb_ = decrypt_cb;
+ break;
+ case media::Decryptor::kVideo:
+ DCHECK_EQ(pending_video_decrypt_request_id_, 0u);
+ DCHECK(pending_video_decrypt_cb_.is_null());
+ pending_video_decrypt_request_id_ = request_id;
+ pending_video_decrypt_cb_ = decrypt_cb;
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+
+ plugin_decryption_interface_->Decrypt(pp_instance_,
+ encrypted_resource,
+ &block_info);
+ return true;
+}
+
+bool ContentDecryptorDelegate::CancelDecrypt(
+ media::Decryptor::StreamType stream_type) {
+ DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type;
+
+ media::Decryptor::DecryptCB decrypt_cb;
+ switch (stream_type) {
+ case media::Decryptor::kAudio:
+ pending_audio_decrypt_request_id_ = 0;
+ decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_);
+ break;
+ case media::Decryptor::kVideo:
+ pending_video_decrypt_request_id_ = 0;
+ decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_);
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+
+ if (!decrypt_cb.is_null())
+ decrypt_cb.Run(media::Decryptor::kSuccess, NULL);
+
+ return true;
+}
+
+bool ContentDecryptorDelegate::InitializeAudioDecoder(
+ const media::AudioDecoderConfig& decoder_config,
+ const media::Decryptor::DecoderInitCB& init_cb) {
+ PP_AudioDecoderConfig pp_decoder_config;
+ pp_decoder_config.codec =
+ MediaAudioCodecToPpAudioCodec(decoder_config.codec());
+ pp_decoder_config.channel_count =
+ media::ChannelLayoutToChannelCount(decoder_config.channel_layout());
+ pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel();
+ pp_decoder_config.samples_per_second = decoder_config.samples_per_second();
+ pp_decoder_config.request_id = next_decryption_request_id_++;
+
+ ScopedPPResource extra_data_resource(
+ ScopedPPResource::PassRef(),
+ MakeBufferResource(pp_instance_,
+ decoder_config.extra_data(),
+ decoder_config.extra_data_size()));
+
+ DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u);
+ DCHECK(pending_audio_decoder_init_cb_.is_null());
+ pending_audio_decoder_init_request_id_ = pp_decoder_config.request_id;
+ pending_audio_decoder_init_cb_ = init_cb;
+
+ plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_,
+ &pp_decoder_config,
+ extra_data_resource);
+ return true;
+}
+
+bool ContentDecryptorDelegate::InitializeVideoDecoder(
+ const media::VideoDecoderConfig& decoder_config,
+ const media::Decryptor::DecoderInitCB& init_cb) {
+ PP_VideoDecoderConfig pp_decoder_config;
+ pp_decoder_config.codec =
+ MediaVideoCodecToPpVideoCodec(decoder_config.codec());
+ pp_decoder_config.profile =
+ MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile());
+ pp_decoder_config.format =
+ MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format());
+ pp_decoder_config.width = decoder_config.coded_size().width();
+ pp_decoder_config.height = decoder_config.coded_size().height();
+ pp_decoder_config.request_id = next_decryption_request_id_++;
+
+ ScopedPPResource extra_data_resource(
+ ScopedPPResource::PassRef(),
+ MakeBufferResource(pp_instance_,
+ decoder_config.extra_data(),
+ decoder_config.extra_data_size()));
+
+ DCHECK_EQ(pending_video_decoder_init_request_id_, 0u);
+ DCHECK(pending_video_decoder_init_cb_.is_null());
+ pending_video_decoder_init_request_id_ = pp_decoder_config.request_id;
+ pending_video_decoder_init_cb_ = init_cb;
+
+ plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_,
+ &pp_decoder_config,
+ extra_data_resource);
+ return true;
+}
+
+bool ContentDecryptorDelegate::DeinitializeDecoder(
+ media::Decryptor::StreamType stream_type) {
+ CancelDecode(stream_type);
+
+ // TODO(tomfinegan): Add decoder deinitialize request tracking, and get
+ // stream type from media stack.
+ plugin_decryption_interface_->DeinitializeDecoder(
+ pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0);
+ return true;
+}
+
+bool ContentDecryptorDelegate::ResetDecoder(
+ media::Decryptor::StreamType stream_type) {
+ CancelDecode(stream_type);
+
+ // TODO(tomfinegan): Add decoder reset request tracking.
+ plugin_decryption_interface_->ResetDecoder(
+ pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0);
+ return true;
+}
+
+bool ContentDecryptorDelegate::DecryptAndDecodeAudio(
+ const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
+ const media::Decryptor::AudioDecodeCB& audio_decode_cb) {
+ // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize()
+ // return NULL and 0 respectively. In that case, we'll just create a 0
+ // resource.
+ ScopedPPResource encrypted_resource(
+ ScopedPPResource::PassRef(),
+ MakeBufferResource(pp_instance_,
+ encrypted_buffer->GetData(),
+ encrypted_buffer->GetDataSize()));
+ if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get())
+ return false;
+
+ const uint32_t request_id = next_decryption_request_id_++;
+ DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id;
+
+ PP_EncryptedBlockInfo block_info;
+ if (!MakeEncryptedBlockInfo(
+ encrypted_buffer->GetDecryptConfig(),
+ encrypted_buffer->GetTimestamp().InMicroseconds(),
+ request_id,
+ &block_info)) {
+ return false;
+ }
+
+ // There is only one pending audio decode request at any time. This is
+ // enforced by the media pipeline.
+ DCHECK_EQ(pending_audio_decode_request_id_, 0u);
+ DCHECK(pending_audio_decode_cb_.is_null());
+ pending_audio_decode_request_id_ = request_id;
+ pending_audio_decode_cb_ = audio_decode_cb;
+
+ plugin_decryption_interface_->DecryptAndDecode(pp_instance_,
+ PP_DECRYPTORSTREAMTYPE_AUDIO,
+ encrypted_resource,
+ &block_info);
+ return true;
+}
+
+bool ContentDecryptorDelegate::DecryptAndDecodeVideo(
+ const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
+ const media::Decryptor::VideoDecodeCB& video_decode_cb) {
+ // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize()
+ // return NULL and 0 respectively. In that case, we'll just create a 0
+ // resource.
+ ScopedPPResource encrypted_resource(
+ ScopedPPResource::PassRef(),
+ MakeBufferResource(pp_instance_,
+ encrypted_buffer->GetData(),
+ encrypted_buffer->GetDataSize()));
+ if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get())
+ return false;
+
+ const uint32_t request_id = next_decryption_request_id_++;
+ DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id;
+ TRACE_EVENT_ASYNC_BEGIN0(
+ "eme", "PluginInstance::DecryptAndDecodeVideo", request_id);
+
+ PP_EncryptedBlockInfo block_info;
+ if (!MakeEncryptedBlockInfo(
+ encrypted_buffer->GetDecryptConfig(),
+ encrypted_buffer->GetTimestamp().InMicroseconds(),
+ request_id,
+ &block_info)) {
+ return false;
+ }
+
+ // Only one pending video decode request at any time. This is enforced by the
+ // media pipeline.
+ DCHECK_EQ(pending_video_decode_request_id_, 0u);
+ DCHECK(pending_video_decode_cb_.is_null());
+ pending_video_decode_request_id_ = request_id;
+ pending_video_decode_cb_ = video_decode_cb;
+
+ // TODO(tomfinegan): Need to get stream type from media stack.
+ plugin_decryption_interface_->DecryptAndDecode(pp_instance_,
+ PP_DECRYPTORSTREAMTYPE_VIDEO,
+ encrypted_resource,
+ &block_info);
+ return true;
+}
+
+void ContentDecryptorDelegate::NeedKey(PP_Var key_system_var,
+ PP_Var session_id_var,
+ PP_Var init_data_var) {
+ // TODO(tomfinegan): send the data to media stack.
+}
+
+void ContentDecryptorDelegate::KeyAdded(PP_Var key_system_var,
+ PP_Var session_id_var) {
+ if (!decryptor_client_)
+ return;
+
+ StringVar* key_system_string = StringVar::FromPPVar(key_system_var);
+ StringVar* session_id_string = StringVar::FromPPVar(session_id_var);
+ if (!key_system_string || !session_id_string) {
+ decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0);
+ return;
+ }
+
+ decryptor_client_->KeyAdded(key_system_string->value(),
+ session_id_string->value());
+}
+
+void ContentDecryptorDelegate::KeyMessage(PP_Var key_system_var,
+ PP_Var session_id_var,
+ PP_Resource message_resource,
+ PP_Var default_url_var) {
+ if (!decryptor_client_)
+ return;
+
+ StringVar* key_system_string = StringVar::FromPPVar(key_system_var);
+ StringVar* session_id_string = StringVar::FromPPVar(session_id_var);
+ StringVar* default_url_string = StringVar::FromPPVar(default_url_var);
+
+ if (!key_system_string || !session_id_string || !default_url_string) {
+ decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0);
+ return;
+ }
+
+ EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true);
+ if (!enter.succeeded()) {
+ decryptor_client_->KeyError(key_system_string->value(),
+ session_id_string->value(),
+ media::Decryptor::kUnknownError,
+ 0);
+ return;
+ }
+
+ BufferAutoMapper mapper(enter.object());
+ scoped_array<uint8> message_array(new uint8[mapper.size()]);
+ if (mapper.data() && mapper.size())
+ memcpy(message_array.get(), mapper.data(), mapper.size());
+
+ decryptor_client_->KeyMessage(key_system_string->value(),
+ session_id_string->value(),
+ message_array.Pass(),
+ mapper.size(),
+ default_url_string->value());
+}
+
+void ContentDecryptorDelegate::KeyError(PP_Var key_system_var,
+ PP_Var session_id_var,
+ int32_t media_error,
+ int32_t system_code) {
+ if (!decryptor_client_)
+ return;
+
+ StringVar* key_system_string = StringVar::FromPPVar(key_system_var);
+ StringVar* session_id_string = StringVar::FromPPVar(session_id_var);
+ if (!key_system_string || !session_id_string) {
+ decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0);
+ return;
+ }
+
+ decryptor_client_->KeyError(
+ key_system_string->value(),
+ session_id_string->value(),
+ static_cast<media::Decryptor::KeyError>(media_error),
+ system_code);
+}
+
+void ContentDecryptorDelegate::DecoderInitializeDone(
+ PP_DecryptorStreamType decoder_type,
+ uint32_t request_id,
+ PP_Bool success) {
+ if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) {
+ // If the request ID is not valid or does not match what's saved, do
+ // nothing.
+ if (request_id == 0 ||
+ request_id != pending_audio_decoder_init_request_id_)
+ return;
+
+ DCHECK(!pending_audio_decoder_init_cb_.is_null());
+ pending_audio_decoder_init_request_id_ = 0;
+ base::ResetAndReturn(
+ &pending_audio_decoder_init_cb_).Run(PP_ToBool(success));
+ } else {
+ if (request_id == 0 ||
+ request_id != pending_video_decoder_init_request_id_)
+ return;
+
+ DCHECK(!pending_video_decoder_init_cb_.is_null());
+ pending_video_decoder_init_request_id_ = 0;
+ base::ResetAndReturn(
+ &pending_video_decoder_init_cb_).Run(PP_ToBool(success));
+ }
+}
+
+void ContentDecryptorDelegate::DecoderDeinitializeDone(
+ PP_DecryptorStreamType decoder_type,
+ uint32_t request_id) {
+ // TODO(tomfinegan): Add decoder stop completion handling.
+}
+
+void ContentDecryptorDelegate::DecoderResetDone(
+ PP_DecryptorStreamType decoder_type,
+ uint32_t request_id) {
+ // TODO(tomfinegan): Add decoder reset completion handling.
+}
+
+void ContentDecryptorDelegate::DeliverBlock(
+ PP_Resource decrypted_block,
+ const PP_DecryptedBlockInfo* block_info) {
+ DCHECK(block_info);
+ const uint32_t request_id = block_info->tracking_info.request_id;
+ DVLOG(2) << "DeliverBlock() - request_id: " << request_id;
+
+ // If the request ID is not valid or does not match what's saved, do nothing.
+ if (request_id == 0) {
+ DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id;
+ return;
+ }
+
+ media::Decryptor::DecryptCB decrypt_cb;
+ if (request_id == pending_audio_decrypt_request_id_) {
+ DCHECK(!pending_audio_decrypt_cb_.is_null());
+ pending_audio_decrypt_request_id_ = 0;
+ decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_);
+ } else if (request_id == pending_video_decrypt_request_id_) {
+ DCHECK(!pending_video_decrypt_cb_.is_null());
+ pending_video_decrypt_request_id_ = 0;
+ decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_);
+ } else {
+ DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found";
+ return;
+ }
+
+ media::Decryptor::Status status =
+ PpDecryptResultToMediaDecryptorStatus(block_info->result);
+ if (status != media::Decryptor::kSuccess) {
+ decrypt_cb.Run(status, NULL);
+ return;
+ }
+
+ EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true);
+ if (!enter.succeeded()) {
+ decrypt_cb.Run(media::Decryptor::kError, NULL);
+ return;
+ }
+ BufferAutoMapper mapper(enter.object());
+ if (!mapper.data() || !mapper.size()) {
+ decrypt_cb.Run(media::Decryptor::kError, NULL);
+ return;
+ }
+
+ // TODO(tomfinegan): Find a way to take ownership of the shared memory
+ // managed by the PPB_Buffer_Dev, and avoid the extra copy.
+ scoped_refptr<media::DecoderBuffer> decrypted_buffer(
+ media::DecoderBuffer::CopyFrom(
+ static_cast<uint8*>(mapper.data()), mapper.size()));
+ decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds(
+ block_info->tracking_info.timestamp));
+ decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer);
+}
+
+void ContentDecryptorDelegate::DeliverFrame(
+ PP_Resource decrypted_frame,
+ const PP_DecryptedFrameInfo* frame_info) {
+ DCHECK(frame_info);
+ const uint32_t request_id = frame_info->tracking_info.request_id;
+ DVLOG(2) << "DeliverFrame() - request_id: " << request_id;
+
+ // If the request ID is not valid or does not match what's saved, do nothing.
+ if (request_id == 0 || request_id != pending_video_decode_request_id_) {
+ DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found";
+ return;
+ }
+
+ TRACE_EVENT_ASYNC_END0(
+ "eme", "PluginInstance::DecryptAndDecodeVideo", request_id);
+
+ DCHECK(!pending_video_decode_cb_.is_null());
+ pending_video_decode_request_id_ = 0;
+ media::Decryptor::VideoDecodeCB video_decode_cb =
+ base::ResetAndReturn(&pending_video_decode_cb_);
+
+ media::Decryptor::Status status =
+ PpDecryptResultToMediaDecryptorStatus(frame_info->result);
+ if (status != media::Decryptor::kSuccess) {
+ video_decode_cb.Run(status, NULL);
+ return;
+ }
+
+ EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_frame, true);
+ if (!enter.succeeded()) {
+ video_decode_cb.Run(media::Decryptor::kError, NULL);
+ return;
+ }
+ BufferAutoMapper mapper(enter.object());
+ if (!mapper.data() || !mapper.size()) {
+ video_decode_cb.Run(media::Decryptor::kError, NULL);
+ return;
+ }
+
+ const uint8* frame_data = static_cast<uint8*>(mapper.data());
+ gfx::Size frame_size(frame_info->width, frame_info->height);
+
+ DCHECK(frame_info->format == PP_DECRYPTEDFRAMEFORMAT_YV12);
+ const media::VideoFrame::Format format = media::VideoFrame::YV12;
+
+ // TODO(tomfinegan): Find a way to take ownership of the shared memory
+ // managed by the PPB_Buffer_Dev, and avoid the extra copy.
+ scoped_refptr<media::VideoFrame> decoded_frame(
+ media::VideoFrame::CreateFrame(
+ format, frame_size, frame_size,
+ base::TimeDelta::FromMicroseconds(
+ frame_info->tracking_info.timestamp)));
+
+ media::CopyYPlane(
+ frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y],
+ frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y],
+ frame_info->height,
+ decoded_frame.get());
+
+ media::CopyUPlane(
+ frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U],
+ frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U],
+ frame_info->height,
+ decoded_frame.get());
+
+ media::CopyVPlane(
+ frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V],
+ frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V],
+ frame_info->height,
+ decoded_frame.get());
+
+ video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame);
+}
+
+void ContentDecryptorDelegate::DeliverSamples(
+ PP_Resource audio_frames,
+ const PP_DecryptedBlockInfo* block_info) {
+ DCHECK(block_info);
+ const uint32_t request_id = block_info->tracking_info.request_id;
+ DVLOG(2) << "DeliverSamples() - request_id: " << request_id;
+
+ // If the request ID is not valid or does not match what's saved, do nothing.
+ if (request_id == 0 || request_id != pending_audio_decode_request_id_) {
+ DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found";
+ return;
+ }
+
+ DCHECK(!pending_audio_decode_cb_.is_null());
+ pending_audio_decode_request_id_ = 0;
+ media::Decryptor::AudioDecodeCB audio_decode_cb =
+ base::ResetAndReturn(&pending_audio_decode_cb_);
+
+ const media::Decryptor::AudioBuffers empty_frames;
+
+ media::Decryptor::Status status =
+ PpDecryptResultToMediaDecryptorStatus(block_info->result);
+ if (status != media::Decryptor::kSuccess) {
+ audio_decode_cb.Run(status, empty_frames);
+ return;
+ }
+
+ media::Decryptor::AudioBuffers audio_frame_list;
+ if (!DeserializeAudioFrames(audio_frames, &audio_frame_list)) {
+ NOTREACHED() << "CDM did not serialize the buffer correctly.";
+ audio_decode_cb.Run(media::Decryptor::kError, empty_frames);
+ return;
+ }
+
+ audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list);
+}
+
+// TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt().
+void ContentDecryptorDelegate::CancelDecode(
+ media::Decryptor::StreamType stream_type) {
+ switch (stream_type) {
+ case media::Decryptor::kAudio:
+ pending_audio_decode_request_id_ = 0;
+ if (!pending_audio_decode_cb_.is_null())
+ base::ResetAndReturn(&pending_audio_decode_cb_).Run(
+ media::Decryptor::kSuccess, media::Decryptor::AudioBuffers());
+ break;
+ case media::Decryptor::kVideo:
+ pending_video_decode_request_id_ = 0;
+ if (!pending_video_decode_cb_.is_null())
+ base::ResetAndReturn(&pending_video_decode_cb_).Run(
+ media::Decryptor::kSuccess, NULL);
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace ppapi
+} // namespace webkit
diff --git a/webkit/plugins/ppapi/content_decryptor_delegate.h b/webkit/plugins/ppapi/content_decryptor_delegate.h
new file mode 100644
index 0000000..9d2d331
--- /dev/null
+++ b/webkit/plugins/ppapi/content_decryptor_delegate.h
@@ -0,0 +1,132 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_PLUGINS_PPAPI_CONTENT_DECRYPTOR_DELEGATE_H_
+#define WEBKIT_PLUGINS_PPAPI_CONTENT_DECRYPTOR_DELEGATE_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "base/memory/ref_counted.h"
+#include "media/base/decryptor.h"
+#include "ppapi/c/private/pp_content_decryptor.h"
+#include "ppapi/c/private/ppp_content_decryptor_private.h"
+#include "webkit/plugins/webkit_plugins_export.h"
+
+namespace media {
+class AudioDecoderConfig;
+class DecoderBuffer;
+class DecryptorClient;
+class VideoDecoderConfig;
+}
+
+namespace webkit {
+namespace ppapi {
+
+class WEBKIT_PLUGINS_EXPORT ContentDecryptorDelegate {
+ public:
+ // ContentDecryptorDelegate does not take ownership of
+ // |plugin_decryption_interface|. Therefore |plugin_decryption_interface|
+ // must outlive this object.
+ ContentDecryptorDelegate(
+ PP_Instance pp_instance,
+ const PPP_ContentDecryptor_Private* plugin_decryption_interface);
+
+ // Provides access to PPP_ContentDecryptor_Private.
+ void set_decrypt_client(media::DecryptorClient* decryptor_client);
+ bool GenerateKeyRequest(const std::string& key_system,
+ const std::string& type,
+ const std::string& init_data);
+ bool AddKey(const std::string& session_id,
+ const std::string& key,
+ const std::string& init_data);
+ bool CancelKeyRequest(const std::string& session_id);
+ bool Decrypt(media::Decryptor::StreamType stream_type,
+ const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
+ const media::Decryptor::DecryptCB& decrypt_cb);
+ bool CancelDecrypt(media::Decryptor::StreamType stream_type);
+ bool InitializeAudioDecoder(
+ const media::AudioDecoderConfig& decoder_config,
+ const media::Decryptor::DecoderInitCB& decoder_init_cb);
+ bool InitializeVideoDecoder(
+ const media::VideoDecoderConfig& decoder_config,
+ const media::Decryptor::DecoderInitCB& decoder_init_cb);
+ // TODO(tomfinegan): Add callback args for DeinitializeDecoder() and
+ // ResetDecoder()
+ bool DeinitializeDecoder(media::Decryptor::StreamType stream_type);
+ bool ResetDecoder(media::Decryptor::StreamType stream_type);
+ // Note: These methods can be used with unencrypted data.
+ bool DecryptAndDecodeAudio(
+ const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
+ const media::Decryptor::AudioDecodeCB& audio_decode_cb);
+ bool DecryptAndDecodeVideo(
+ const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
+ const media::Decryptor::VideoDecodeCB& video_decode_cb);
+
+ // PPB_ContentDecryptor_Private dispatching methods.
+ void NeedKey(PP_Var key_system, PP_Var session_id, PP_Var init_data);
+ void KeyAdded(PP_Var key_system, PP_Var session_id);
+ void KeyMessage(PP_Var key_system,
+ PP_Var session_id,
+ PP_Resource message,
+ PP_Var default_url);
+ void KeyError(PP_Var key_system,
+ PP_Var session_id,
+ int32_t media_error,
+ int32_t system_code);
+ void DeliverBlock(PP_Resource decrypted_block,
+ const PP_DecryptedBlockInfo* block_info);
+ void DecoderInitializeDone(PP_DecryptorStreamType decoder_type,
+ uint32_t request_id,
+ PP_Bool success);
+ void DecoderDeinitializeDone(PP_DecryptorStreamType decoder_type,
+ uint32_t request_id);
+ void DecoderResetDone(PP_DecryptorStreamType decoder_type,
+ uint32_t request_id);
+ void DeliverFrame(PP_Resource decrypted_frame,
+ const PP_DecryptedFrameInfo* frame_info);
+ void DeliverSamples(PP_Resource audio_frames,
+ const PP_DecryptedBlockInfo* block_info);
+
+ private:
+ // Cancels the pending decrypt-and-decode callback for |stream_type|.
+ void CancelDecode(media::Decryptor::StreamType stream_type);
+
+ const PP_Instance pp_instance_;
+ const PPP_ContentDecryptor_Private* const plugin_decryption_interface_;
+
+ media::DecryptorClient* decryptor_client_;
+
+ // Request ID for tracking pending content decryption callbacks.
+ // Note that zero indicates an invalid request ID.
+ // TODO(xhwang): Add completion callbacks for Reset/Stop and remove the use
+ // of request IDs.
+ uint32_t next_decryption_request_id_;
+
+ uint32_t pending_audio_decrypt_request_id_;
+ media::Decryptor::DecryptCB pending_audio_decrypt_cb_;
+
+ uint32_t pending_video_decrypt_request_id_;
+ media::Decryptor::DecryptCB pending_video_decrypt_cb_;
+
+ uint32_t pending_audio_decoder_init_request_id_;
+ media::Decryptor::DecoderInitCB pending_audio_decoder_init_cb_;
+
+ uint32_t pending_video_decoder_init_request_id_;
+ media::Decryptor::DecoderInitCB pending_video_decoder_init_cb_;
+
+ uint32_t pending_audio_decode_request_id_;
+ media::Decryptor::AudioDecodeCB pending_audio_decode_cb_;
+
+ uint32_t pending_video_decode_request_id_;
+ media::Decryptor::VideoDecodeCB pending_video_decode_cb_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContentDecryptorDelegate);
+};
+
+} // namespace ppapi
+} // namespace webkit
+
+#endif // WEBKIT_PLUGINS_PPAPI_CONTENT_DECRYPTOR_DELEGATE_H_
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
index 795a00e..4aa3f99 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
@@ -15,15 +15,6 @@
#include "base/time.h"
#include "base/utf_offset_string_conversions.h"
#include "base/utf_string_conversions.h"
-// TODO(xhwang): Move media specific code out of this class.
-#include "media/base/audio_decoder_config.h"
-#include "media/base/channel_layout.h"
-#include "media/base/data_buffer.h"
-#include "media/base/decoder_buffer.h"
-#include "media/base/decryptor_client.h"
-#include "media/base/video_decoder_config.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_util.h"
#include "ppapi/c/dev/ppb_find_dev.h"
#include "ppapi/c/dev/ppb_zoom_dev.h"
#include "ppapi/c/dev/ppp_find_dev.h"
@@ -38,7 +29,6 @@
#include "ppapi/c/ppp_instance.h"
#include "ppapi/c/ppp_messaging.h"
#include "ppapi/c/ppp_mouse_lock.h"
-#include "ppapi/c/private/pp_content_decryptor.h"
#include "ppapi/c/private/ppp_instance_private.h"
#include "ppapi/shared_impl/ppapi_preferences.h"
#include "ppapi/shared_impl/ppb_gamepad_shared.h"
@@ -77,6 +67,7 @@
#include "ui/gfx/rect_conversions.h"
#include "webkit/plugins/plugin_constants.h"
#include "webkit/plugins/ppapi/common.h"
+#include "webkit/plugins/ppapi/content_decryptor_delegate.h"
#include "webkit/plugins/ppapi/event_conversion.h"
#include "webkit/plugins/ppapi/fullscreen_container.h"
#include "webkit/plugins/ppapi/gfx_conversion.h"
@@ -90,8 +81,8 @@
#include "webkit/plugins/ppapi/ppb_graphics_3d_impl.h"
#include "webkit/plugins/ppapi/ppb_image_data_impl.h"
#include "webkit/plugins/ppapi/ppb_url_loader_impl.h"
-#include "webkit/plugins/ppapi/url_request_info_util.h"
#include "webkit/plugins/ppapi/ppp_pdf.h"
+#include "webkit/plugins/ppapi/url_request_info_util.h"
#include "webkit/plugins/sad_plugin.h"
#if defined(OS_MACOSX)
@@ -312,226 +303,6 @@ scoped_array<const char*> StringVectorToArgArray(
return array.Pass();
}
-// Creates a PP_Resource containing a PPB_Buffer_Impl, copies |data| into the
-// buffer resource, and returns it. Returns a an invalid PP_Resource with an ID
-// of 0 on failure. Upon success, the returned Buffer resource has a reference
-// count of 1.
-PP_Resource MakeBufferResource(PP_Instance instance,
- const uint8* data, int size) {
- if (!data || !size)
- return 0;
-
- ScopedPPResource resource(PPB_Buffer_Impl::Create(instance, size));
- if (!resource.get())
- return 0;
-
- EnterResourceNoLock<PPB_Buffer_API> enter(resource, true);
- if (enter.failed())
- return 0;
-
- BufferAutoMapper mapper(enter.object());
- if (!mapper.data() || mapper.size() < static_cast<size_t>(size))
- return 0;
-
- memcpy(mapper.data(), data, size);
- return resource.get();
-}
-
-// Copies the content of |str| into |array|.
-// Returns true if copy succeeded. Returns false if copy failed, e.g. if the
-// |array_size| is smaller than the |str| length.
-template <uint32_t array_size>
-bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) {
- if (array_size < str.size())
- return false;
-
- memcpy(array, str.data(), str.size());
- return true;
-}
-
-// Fills the |block_info| with information from |decrypt_config|, |timestamp|
-// and |request_id|. |decrypt_config| can be NULL if the block is not encrypted.
-// This is useful for end-of-stream blocks.
-// Returns true if |block_info| is successfully filled. Returns false
-// otherwise.
-bool MakeEncryptedBlockInfo(
- const media::DecryptConfig* decrypt_config,
- int64_t timestamp,
- uint32_t request_id,
- PP_EncryptedBlockInfo* block_info) {
- DCHECK(block_info);
-
- // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and
- // anywhere else.
- memset(block_info, 0, sizeof(*block_info));
-
- block_info->tracking_info.request_id = request_id;
- block_info->tracking_info.timestamp = timestamp;
-
- if (!decrypt_config)
- return true;
-
- block_info->data_offset = decrypt_config->data_offset();
-
- if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) ||
- !CopyStringToArray(decrypt_config->iv(), block_info->iv))
- return false;
-
- block_info->key_id_size = decrypt_config->key_id().size();
- block_info->iv_size = decrypt_config->iv().size();
-
- if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples))
- return false;
-
- block_info->num_subsamples = decrypt_config->subsamples().size();
- for (uint32_t i = 0; i < block_info->num_subsamples; ++i) {
- block_info->subsamples[i].clear_bytes =
- decrypt_config->subsamples()[i].clear_bytes;
- block_info->subsamples[i].cipher_bytes =
- decrypt_config->subsamples()[i].cypher_bytes;
- }
-
- 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,
- 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())
- return false;
-
- const uint8* cur = static_cast<uint8*>(mapper.data());
- int bytes_left = mapper.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(new media::DataBuffer(cur,
- frame_size));
- frame->SetTimestamp(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:
- return PP_AUDIOCODEC_VORBIS;
- case media::kCodecAAC:
- return PP_AUDIOCODEC_AAC;
- default:
- return PP_AUDIOCODEC_UNKNOWN;
- }
-}
-
-PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) {
- switch (codec) {
- case media::kCodecVP8:
- return PP_VIDEOCODEC_VP8;
- case media::kCodecH264:
- return PP_VIDEOCODEC_H264;
- default:
- return PP_VIDEOCODEC_UNKNOWN;
- }
-}
-
-PP_VideoCodecProfile MediaVideoCodecProfileToPpVideoCodecProfile(
- media::VideoCodecProfile profile) {
- switch (profile) {
- case media::VP8PROFILE_MAIN:
- return PP_VIDEOCODECPROFILE_VP8_MAIN;
- case media::H264PROFILE_BASELINE:
- return PP_VIDEOCODECPROFILE_H264_BASELINE;
- case media::H264PROFILE_MAIN:
- return PP_VIDEOCODECPROFILE_H264_MAIN;
- case media::H264PROFILE_EXTENDED:
- return PP_VIDEOCODECPROFILE_H264_EXTENDED;
- case media::H264PROFILE_HIGH:
- return PP_VIDEOCODECPROFILE_H264_HIGH;
- case media::H264PROFILE_HIGH10PROFILE:
- return PP_VIDEOCODECPROFILE_H264_HIGH_10;
- case media::H264PROFILE_HIGH422PROFILE:
- return PP_VIDEOCODECPROFILE_H264_HIGH_422;
- case media::H264PROFILE_HIGH444PREDICTIVEPROFILE:
- return PP_VIDEOCODECPROFILE_H264_HIGH_444_PREDICTIVE;
- default:
- return PP_VIDEOCODECPROFILE_UNKNOWN;
- }
-}
-
-PP_DecryptedFrameFormat MediaVideoFormatToPpDecryptedFrameFormat(
- media::VideoFrame::Format format) {
- switch (format) {
- case media::VideoFrame::YV12:
- return PP_DECRYPTEDFRAMEFORMAT_YV12;
- case media::VideoFrame::I420:
- return PP_DECRYPTEDFRAMEFORMAT_I420;
- default:
- return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN;
- }
-}
-
-media::Decryptor::Status PpDecryptResultToMediaDecryptorStatus(
- PP_DecryptResult result) {
- switch (result) {
- case PP_DECRYPTRESULT_SUCCESS:
- return media::Decryptor::kSuccess;
- case PP_DECRYPTRESULT_DECRYPT_NOKEY:
- return media::Decryptor::kNoKey;
- case PP_DECRYPTRESULT_NEEDMOREDATA:
- return media::Decryptor::kNeedMoreData;
- case PP_DECRYPTRESULT_DECRYPT_ERROR:
- return media::Decryptor::kError;
- case PP_DECRYPTRESULT_DECODE_ERROR:
- return media::Decryptor::kError;
- default:
- NOTREACHED();
- return media::Decryptor::kError;
- }
-}
-
-PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType(
- media::Decryptor::StreamType stream_type) {
- switch (stream_type) {
- case media::Decryptor::kAudio:
- return PP_DECRYPTORSTREAMTYPE_AUDIO;
- case media::Decryptor::kVideo:
- return PP_DECRYPTORSTREAMTYPE_VIDEO;
- default:
- NOTREACHED();
- return PP_DECRYPTORSTREAMTYPE_VIDEO;
- }
-}
-
} // namespace
// static
@@ -572,7 +343,6 @@ PluginInstance::PluginInstance(
has_webkit_focus_(false),
has_content_area_focus_(false),
find_identifier_(-1),
- plugin_decryption_interface_(NULL),
plugin_find_interface_(NULL),
plugin_input_event_interface_(NULL),
plugin_messaging_interface_(NULL),
@@ -603,15 +373,7 @@ PluginInstance::PluginInstance(
selection_caret_(0),
selection_anchor_(0),
pending_user_gesture_(0.0),
- flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
- decryptor_client_(NULL),
- next_decryption_request_id_(1),
- pending_audio_decrypt_request_id_(0),
- pending_video_decrypt_request_id_(0),
- pending_audio_decoder_init_request_id_(0),
- pending_video_decoder_init_request_id_(0),
- pending_audio_decode_request_id_(0),
- pending_video_decode_request_id_(0) {
+ flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
pp_instance_ = HostGlobals::Get()->AddInstance(this);
memset(&current_print_settings_, 0, sizeof(current_print_settings_));
@@ -1295,16 +1057,6 @@ void PluginInstance::StopFind() {
plugin_find_interface_->StopFind(pp_instance());
}
-bool PluginInstance::LoadContentDecryptorInterface() {
- if (!plugin_decryption_interface_) {
- plugin_decryption_interface_ =
- static_cast<const PPP_ContentDecryptor_Private*>(
- module_->GetPluginInterface(
- PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE));
- }
- return !!plugin_decryption_interface_;
-}
-
bool PluginInstance::LoadFindInterface() {
if (!plugin_find_interface_) {
plugin_find_interface_ =
@@ -1623,336 +1375,6 @@ void PluginInstance::RotateView(WebPlugin::RotationType type) {
// NOTE: plugin instance may have been deleted.
}
-void PluginInstance::set_decrypt_client(
- media::DecryptorClient* decryptor_client) {
- decryptor_client_ = decryptor_client;
-}
-
-bool PluginInstance::GenerateKeyRequest(const std::string& key_system,
- const std::string& type,
- const std::string& init_data) {
- if (!LoadContentDecryptorInterface())
- return false;
- if (key_system.empty())
- return false;
-
- PP_Var init_data_array =
- PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
- init_data.size(), init_data.data());
-
- plugin_decryption_interface_->GenerateKeyRequest(
- pp_instance(),
- StringVar::StringToPPVar(key_system),
- StringVar::StringToPPVar(type),
- init_data_array);
- return true;
-}
-
-bool PluginInstance::AddKey(const std::string& session_id,
- const std::string& key,
- const std::string& init_data) {
- if (!LoadContentDecryptorInterface())
- return false;
- PP_Var key_array =
- PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(key.size(),
- key.data());
- PP_Var init_data_array =
- PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
- init_data.size(),
- init_data.data());
-
- plugin_decryption_interface_->AddKey(
- pp_instance(),
- StringVar::StringToPPVar(session_id),
- key_array,
- init_data_array);
- return true;
-}
-
-bool PluginInstance::CancelKeyRequest(const std::string& session_id) {
- if (!LoadContentDecryptorInterface())
- return false;
- plugin_decryption_interface_->CancelKeyRequest(
- pp_instance(),
- StringVar::StringToPPVar(session_id));
- return true;
-}
-
-// TODO(xhwang): Remove duplication of code in Decrypt(),
-// DecryptAndDecodeAudio() and DecryptAndDecodeVideo().
-bool PluginInstance::Decrypt(
- media::Decryptor::StreamType stream_type,
- const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
- const media::Decryptor::DecryptCB& decrypt_cb) {
- DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
- if (!LoadContentDecryptorInterface())
- return false;
-
- ScopedPPResource encrypted_resource(
- ScopedPPResource::PassRef(),
- MakeBufferResource(pp_instance(),
- encrypted_buffer->GetData(),
- encrypted_buffer->GetDataSize()));
- if (!encrypted_resource.get())
- return false;
-
- const uint32_t request_id = next_decryption_request_id_++;
- DVLOG(2) << "Decrypt() - request_id " << request_id;
-
- PP_EncryptedBlockInfo block_info;
- DCHECK(encrypted_buffer->GetDecryptConfig());
- if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(),
- encrypted_buffer->GetTimestamp().InMicroseconds(),
- request_id,
- &block_info)) {
- return false;
- }
-
- // There is only one pending decrypt request at any time per stream. This is
- // enforced by the media pipeline.
- switch (stream_type) {
- case media::Decryptor::kAudio:
- DCHECK_EQ(pending_audio_decrypt_request_id_, 0u);
- DCHECK(pending_audio_decrypt_cb_.is_null());
- pending_audio_decrypt_request_id_ = request_id;
- pending_audio_decrypt_cb_ = decrypt_cb;
- break;
- case media::Decryptor::kVideo:
- DCHECK_EQ(pending_video_decrypt_request_id_, 0u);
- DCHECK(pending_video_decrypt_cb_.is_null());
- pending_video_decrypt_request_id_ = request_id;
- pending_video_decrypt_cb_ = decrypt_cb;
- break;
- default:
- NOTREACHED();
- return false;
- }
-
- plugin_decryption_interface_->Decrypt(pp_instance(),
- encrypted_resource,
- &block_info);
- return true;
-}
-
-bool PluginInstance::CancelDecrypt(media::Decryptor::StreamType stream_type) {
- DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type;
-
- media::Decryptor::DecryptCB decrypt_cb;
- switch (stream_type) {
- case media::Decryptor::kAudio:
- pending_audio_decrypt_request_id_ = 0;
- decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_);
- break;
- case media::Decryptor::kVideo:
- pending_video_decrypt_request_id_ = 0;
- decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_);
- break;
- default:
- NOTREACHED();
- return false;
- }
-
- if (!decrypt_cb.is_null())
- decrypt_cb.Run(media::Decryptor::kSuccess, NULL);
-
- return true;
-}
-
-bool PluginInstance::InitializeAudioDecoder(
- const media::AudioDecoderConfig& decoder_config,
- const media::Decryptor::DecoderInitCB& init_cb) {
- PP_AudioDecoderConfig pp_decoder_config;
- pp_decoder_config.codec =
- MediaAudioCodecToPpAudioCodec(decoder_config.codec());
- pp_decoder_config.channel_count =
- media::ChannelLayoutToChannelCount(decoder_config.channel_layout());
- pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel();
- pp_decoder_config.samples_per_second = decoder_config.samples_per_second();
- pp_decoder_config.request_id = next_decryption_request_id_++;
-
- ScopedPPResource extra_data_resource(
- ScopedPPResource::PassRef(),
- MakeBufferResource(pp_instance(),
- decoder_config.extra_data(),
- decoder_config.extra_data_size()));
-
- DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u);
- DCHECK(pending_audio_decoder_init_cb_.is_null());
- pending_audio_decoder_init_request_id_ = pp_decoder_config.request_id;
- pending_audio_decoder_init_cb_ = init_cb;
-
- plugin_decryption_interface_->InitializeAudioDecoder(pp_instance(),
- &pp_decoder_config,
- extra_data_resource);
- return true;
-}
-
-bool PluginInstance::InitializeVideoDecoder(
- const media::VideoDecoderConfig& decoder_config,
- const media::Decryptor::DecoderInitCB& init_cb) {
- PP_VideoDecoderConfig pp_decoder_config;
- pp_decoder_config.codec =
- MediaVideoCodecToPpVideoCodec(decoder_config.codec());
- pp_decoder_config.profile =
- MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile());
- pp_decoder_config.format =
- MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format());
- pp_decoder_config.width = decoder_config.coded_size().width();
- pp_decoder_config.height = decoder_config.coded_size().height();
- pp_decoder_config.request_id = next_decryption_request_id_++;
-
- ScopedPPResource extra_data_resource(
- ScopedPPResource::PassRef(),
- MakeBufferResource(pp_instance(),
- decoder_config.extra_data(),
- decoder_config.extra_data_size()));
-
- DCHECK_EQ(pending_video_decoder_init_request_id_, 0u);
- DCHECK(pending_video_decoder_init_cb_.is_null());
- pending_video_decoder_init_request_id_ = pp_decoder_config.request_id;
- pending_video_decoder_init_cb_ = init_cb;
-
- plugin_decryption_interface_->InitializeVideoDecoder(pp_instance(),
- &pp_decoder_config,
- extra_data_resource);
- return true;
-}
-
-// TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt().
-void PluginInstance::CancelDecode(media::Decryptor::StreamType stream_type) {
- switch (stream_type) {
- case media::Decryptor::kAudio:
- pending_audio_decode_request_id_ = 0;
- if (!pending_audio_decode_cb_.is_null())
- base::ResetAndReturn(&pending_audio_decode_cb_).Run(
- media::Decryptor::kSuccess, media::Decryptor::AudioBuffers());
- break;
- case media::Decryptor::kVideo:
- pending_video_decode_request_id_ = 0;
- if (!pending_video_decode_cb_.is_null())
- base::ResetAndReturn(&pending_video_decode_cb_).Run(
- media::Decryptor::kSuccess, NULL);
- break;
- default:
- NOTREACHED();
- }
-}
-
-bool PluginInstance::DeinitializeDecoder(
- media::Decryptor::StreamType stream_type) {
- if (!LoadContentDecryptorInterface())
- return false;
-
- CancelDecode(stream_type);
-
- // TODO(tomfinegan): Add decoder deinitialize request tracking, and get
- // stream type from media stack.
- plugin_decryption_interface_->DeinitializeDecoder(
- pp_instance(), MediaDecryptorStreamTypeToPpStreamType(stream_type), 0);
- return true;
-}
-
-bool PluginInstance::ResetDecoder(media::Decryptor::StreamType stream_type) {
- if (!LoadContentDecryptorInterface())
- return false;
-
- CancelDecode(stream_type);
-
- // TODO(tomfinegan): Add decoder reset request tracking.
- plugin_decryption_interface_->ResetDecoder(
- pp_instance(), MediaDecryptorStreamTypeToPpStreamType(stream_type), 0);
- return true;
-}
-
-bool PluginInstance::DecryptAndDecodeAudio(
- const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
- const media::Decryptor::AudioDecodeCB& audio_decode_cb) {
- if (!LoadContentDecryptorInterface())
- return false;
-
- // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize()
- // return NULL and 0 respectively. In that case, we'll just create a 0
- // resource.
- ScopedPPResource encrypted_resource(
- ScopedPPResource::PassRef(),
- MakeBufferResource(pp_instance(),
- encrypted_buffer->GetData(),
- encrypted_buffer->GetDataSize()));
- if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get())
- return false;
-
- const uint32_t request_id = next_decryption_request_id_++;
- DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id;
-
- PP_EncryptedBlockInfo block_info;
- if (!MakeEncryptedBlockInfo(
- encrypted_buffer->GetDecryptConfig(),
- encrypted_buffer->GetTimestamp().InMicroseconds(),
- request_id,
- &block_info)) {
- return false;
- }
-
- // There is only one pending audio decode request at any time. This is
- // enforced by the media pipeline.
- DCHECK_EQ(pending_audio_decode_request_id_, 0u);
- DCHECK(pending_audio_decode_cb_.is_null());
- pending_audio_decode_request_id_ = request_id;
- pending_audio_decode_cb_ = audio_decode_cb;
-
- plugin_decryption_interface_->DecryptAndDecode(pp_instance(),
- PP_DECRYPTORSTREAMTYPE_AUDIO,
- encrypted_resource,
- &block_info);
- return true;
-}
-
-bool PluginInstance::DecryptAndDecodeVideo(
- const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
- const media::Decryptor::VideoDecodeCB& video_decode_cb) {
- if (!LoadContentDecryptorInterface())
- return false;
-
- // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize()
- // return NULL and 0 respectively. In that case, we'll just create a 0
- // resource.
- ScopedPPResource encrypted_resource(
- ScopedPPResource::PassRef(),
- MakeBufferResource(pp_instance(),
- encrypted_buffer->GetData(),
- encrypted_buffer->GetDataSize()));
- if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get())
- return false;
-
- const uint32_t request_id = next_decryption_request_id_++;
- DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id;
- TRACE_EVENT_ASYNC_BEGIN0(
- "eme", "PluginInstance::DecryptAndDecodeVideo", request_id);
-
- PP_EncryptedBlockInfo block_info;
- if (!MakeEncryptedBlockInfo(
- encrypted_buffer->GetDecryptConfig(),
- encrypted_buffer->GetTimestamp().InMicroseconds(),
- request_id,
- &block_info)) {
- return false;
- }
-
- // Only one pending video decode request at any time. This is enforced by the
- // media pipeline.
- DCHECK_EQ(pending_video_decode_request_id_, 0u);
- DCHECK(pending_video_decode_cb_.is_null());
- pending_video_decode_request_id_ = request_id;
- pending_video_decode_cb_ = video_decode_cb;
-
- // TODO(tomfinegan): Need to get stream type from media stack.
- plugin_decryption_interface_->DecryptAndDecode(pp_instance(),
- PP_DECRYPTORSTREAMTYPE_VIDEO,
- encrypted_resource,
- &block_info);
- return true;
-}
-
bool PluginInstance::FlashIsFullscreenOrPending() {
return fullscreen_container_ != NULL;
}
@@ -2400,6 +1822,22 @@ void PluginInstance::SimulateImeSetCompositionEvent(
utf16_text, underlines, offsets[0], offsets[1]);
}
+ContentDecryptorDelegate* PluginInstance::GetContentDecryptorDelegate() {
+ if (content_decryptor_delegate_)
+ return content_decryptor_delegate_.get();
+
+ const PPP_ContentDecryptor_Private* plugin_decryption_interface =
+ static_cast<const PPP_ContentDecryptor_Private*>(
+ module_->GetPluginInterface(
+ PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE));
+ if (!plugin_decryption_interface)
+ return NULL;
+
+ content_decryptor_delegate_.reset(
+ new ContentDecryptorDelegate(pp_instance_, plugin_decryption_interface));
+ return content_decryptor_delegate_.get();
+}
+
void PluginInstance::ClosePendingUserGesture(PP_Instance instance,
PP_TimeTicks timestamp) {
// Do nothing so that the pending user gesture will stay open for
@@ -2566,28 +2004,22 @@ PP_Var PluginInstance::GetFontFamilies(PP_Instance instance) {
return PP_MakeUndefined();
}
+// These PPB_ContentDecryptor_Private calls are responses to
+// PPP_ContentDecryptor_Private calls made on |content_decryptor_delegate_|.
+// Therefore, |content_decryptor_delegate_| must have been initialized when
+// the following methods are called.
void PluginInstance::NeedKey(PP_Instance instance,
PP_Var key_system_var,
PP_Var session_id_var,
PP_Var init_data_var) {
- // TODO(tomfinegan): send the data to media stack.
+ content_decryptor_delegate_->NeedKey(
+ key_system_var, session_id_var, init_data_var);
}
void PluginInstance::KeyAdded(PP_Instance instance,
PP_Var key_system_var,
PP_Var session_id_var) {
- if (!decryptor_client_)
- return;
-
- StringVar* key_system_string = StringVar::FromPPVar(key_system_var);
- StringVar* session_id_string = StringVar::FromPPVar(session_id_var);
- if (!key_system_string || !session_id_string) {
- decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0);
- return;
- }
-
- decryptor_client_->KeyAdded(key_system_string->value(),
- session_id_string->value());
+ content_decryptor_delegate_->KeyAdded(key_system_var, session_id_var);
}
void PluginInstance::KeyMessage(PP_Instance instance,
@@ -2595,37 +2027,8 @@ void PluginInstance::KeyMessage(PP_Instance instance,
PP_Var session_id_var,
PP_Resource message_resource,
PP_Var default_url_var) {
- if (!decryptor_client_)
- return;
-
- StringVar* key_system_string = StringVar::FromPPVar(key_system_var);
- StringVar* session_id_string = StringVar::FromPPVar(session_id_var);
- StringVar* default_url_string = StringVar::FromPPVar(default_url_var);
-
- if (!key_system_string || !session_id_string || !default_url_string) {
- decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0);
- return;
- }
-
- EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true);
- if (!enter.succeeded()) {
- decryptor_client_->KeyError(key_system_string->value(),
- session_id_string->value(),
- media::Decryptor::kUnknownError,
- 0);
- return;
- }
-
- BufferAutoMapper mapper(enter.object());
- scoped_array<uint8> message_array(new uint8[mapper.size()]);
- if (mapper.data() && mapper.size())
- memcpy(message_array.get(), mapper.data(), mapper.size());
-
- decryptor_client_->KeyMessage(key_system_string->value(),
- session_id_string->value(),
- message_array.Pass(),
- mapper.size(),
- default_url_string->value());
+ content_decryptor_delegate_->KeyMessage(
+ key_system_var, session_id_var, message_resource, default_url_var);
}
void PluginInstance::KeyError(PP_Instance instance,
@@ -2633,227 +2036,49 @@ void PluginInstance::KeyError(PP_Instance instance,
PP_Var session_id_var,
int32_t media_error,
int32_t system_code) {
- if (!decryptor_client_)
- return;
-
- StringVar* key_system_string = StringVar::FromPPVar(key_system_var);
- StringVar* session_id_string = StringVar::FromPPVar(session_id_var);
- if (!key_system_string || !session_id_string) {
- decryptor_client_->KeyError("", "", media::Decryptor::kUnknownError, 0);
- return;
- }
+ content_decryptor_delegate_->KeyError(
+ key_system_var, session_id_var, media_error, system_code);
+}
- decryptor_client_->KeyError(
- key_system_string->value(),
- session_id_string->value(),
- static_cast<media::Decryptor::KeyError>(media_error),
- system_code);
+void PluginInstance::DeliverBlock(PP_Instance instance,
+ PP_Resource decrypted_block,
+ const PP_DecryptedBlockInfo* block_info) {
+ content_decryptor_delegate_->DeliverBlock(decrypted_block, block_info);
}
void PluginInstance::DecoderInitializeDone(PP_Instance instance,
PP_DecryptorStreamType decoder_type,
uint32_t request_id,
PP_Bool success) {
- if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) {
- // If the request ID is not valid or does not match what's saved, do
- // nothing.
- if (request_id == 0 ||
- request_id != pending_audio_decoder_init_request_id_)
- return;
-
- DCHECK(!pending_audio_decoder_init_cb_.is_null());
- pending_audio_decoder_init_request_id_ = 0;
- base::ResetAndReturn(
- &pending_audio_decoder_init_cb_).Run(PP_ToBool(success));
- } else {
- if (request_id == 0 ||
- request_id != pending_video_decoder_init_request_id_)
- return;
-
- DCHECK(!pending_video_decoder_init_cb_.is_null());
- pending_video_decoder_init_request_id_ = 0;
- base::ResetAndReturn(
- &pending_video_decoder_init_cb_).Run(PP_ToBool(success));
- }
+ content_decryptor_delegate_->DecoderInitializeDone(
+ decoder_type, request_id, success);
}
void PluginInstance::DecoderDeinitializeDone(
PP_Instance instance,
PP_DecryptorStreamType decoder_type,
uint32_t request_id) {
- // TODO(tomfinegan): Add decoder stop completion handling.
+ content_decryptor_delegate_->DecoderDeinitializeDone(decoder_type,
+ request_id);
}
void PluginInstance::DecoderResetDone(PP_Instance instance,
PP_DecryptorStreamType decoder_type,
uint32_t request_id) {
- // TODO(tomfinegan): Add decoder reset completion handling.
+ content_decryptor_delegate_->DecoderResetDone(decoder_type, request_id);
}
-void PluginInstance::DeliverBlock(PP_Instance instance,
- PP_Resource decrypted_block,
- const PP_DecryptedBlockInfo* block_info) {
- DCHECK(block_info);
- const uint32_t request_id = block_info->tracking_info.request_id;
- DVLOG(2) << "DeliverBlock() - request_id: " << request_id;
-
- // If the request ID is not valid or does not match what's saved, do nothing.
- if (request_id == 0) {
- DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id;
- return;
- }
-
- media::Decryptor::DecryptCB decrypt_cb;
- if (request_id == pending_audio_decrypt_request_id_) {
- DCHECK(!pending_audio_decrypt_cb_.is_null());
- pending_audio_decrypt_request_id_ = 0;
- decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_);
- } else if (request_id == pending_video_decrypt_request_id_) {
- DCHECK(!pending_video_decrypt_cb_.is_null());
- pending_video_decrypt_request_id_ = 0;
- decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_);
- } else {
- DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found";
- return;
- }
-
- media::Decryptor::Status status =
- PpDecryptResultToMediaDecryptorStatus(block_info->result);
- if (status != media::Decryptor::kSuccess) {
- decrypt_cb.Run(status, NULL);
- return;
- }
-
- EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true);
- if (!enter.succeeded()) {
- decrypt_cb.Run(media::Decryptor::kError, NULL);
- return;
- }
- BufferAutoMapper mapper(enter.object());
- if (!mapper.data() || !mapper.size()) {
- decrypt_cb.Run(media::Decryptor::kError, NULL);
- return;
- }
-
- // TODO(tomfinegan): Find a way to take ownership of the shared memory
- // managed by the PPB_Buffer_Dev, and avoid the extra copy.
- scoped_refptr<media::DecoderBuffer> decrypted_buffer(
- media::DecoderBuffer::CopyFrom(
- static_cast<uint8*>(mapper.data()), mapper.size()));
- decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds(
- block_info->tracking_info.timestamp));
- decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer);
-}
void PluginInstance::DeliverFrame(PP_Instance instance,
PP_Resource decrypted_frame,
const PP_DecryptedFrameInfo* frame_info) {
- DCHECK(frame_info);
- const uint32_t request_id = frame_info->tracking_info.request_id;
- DVLOG(2) << "DeliverFrame() - request_id: " << request_id;
-
- // If the request ID is not valid or does not match what's saved, do nothing.
- if (request_id == 0 || request_id != pending_video_decode_request_id_) {
- DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found";
- return;
- }
-
- TRACE_EVENT_ASYNC_END0(
- "eme", "PluginInstance::DecryptAndDecodeVideo", request_id);
-
- DCHECK(!pending_video_decode_cb_.is_null());
- pending_video_decode_request_id_ = 0;
- media::Decryptor::VideoDecodeCB video_decode_cb =
- base::ResetAndReturn(&pending_video_decode_cb_);
-
- media::Decryptor::Status status =
- PpDecryptResultToMediaDecryptorStatus(frame_info->result);
- if (status != media::Decryptor::kSuccess) {
- video_decode_cb.Run(status, NULL);
- return;
- }
-
- EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_frame, true);
- if (!enter.succeeded()) {
- video_decode_cb.Run(media::Decryptor::kError, NULL);
- return;
- }
- BufferAutoMapper mapper(enter.object());
- if (!mapper.data() || !mapper.size()) {
- video_decode_cb.Run(media::Decryptor::kError, NULL);
- return;
- }
-
- const uint8* frame_data = static_cast<uint8*>(mapper.data());
- gfx::Size frame_size(frame_info->width, frame_info->height);
-
- DCHECK(frame_info->format == PP_DECRYPTEDFRAMEFORMAT_YV12);
- const media::VideoFrame::Format format = media::VideoFrame::YV12;
-
- // TODO(tomfinegan): Find a way to take ownership of the shared memory
- // managed by the PPB_Buffer_Dev, and avoid the extra copy.
- scoped_refptr<media::VideoFrame> decoded_frame(
- media::VideoFrame::CreateFrame(
- format, frame_size, frame_size,
- base::TimeDelta::FromMicroseconds(
- frame_info->tracking_info.timestamp)));
-
- media::CopyYPlane(
- frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y],
- frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y],
- frame_info->height,
- decoded_frame.get());
-
- media::CopyUPlane(
- frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U],
- frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U],
- frame_info->height,
- decoded_frame.get());
-
- media::CopyVPlane(
- frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V],
- frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V],
- frame_info->height,
- decoded_frame.get());
-
- video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame);
+ content_decryptor_delegate_->DeliverFrame(decrypted_frame, frame_info);
}
void PluginInstance::DeliverSamples(PP_Instance instance,
PP_Resource audio_frames,
const PP_DecryptedBlockInfo* block_info) {
- DCHECK(block_info);
- const uint32_t request_id = block_info->tracking_info.request_id;
- DVLOG(2) << "DeliverSamples() - request_id: " << request_id;
-
- // If the request ID is not valid or does not match what's saved, do nothing.
- if (request_id == 0 || request_id != pending_audio_decode_request_id_) {
- DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found";
- return;
- }
-
- DCHECK(!pending_audio_decode_cb_.is_null());
- pending_audio_decode_request_id_ = 0;
- media::Decryptor::AudioDecodeCB audio_decode_cb =
- base::ResetAndReturn(&pending_audio_decode_cb_);
-
- const media::Decryptor::AudioBuffers empty_frames;
-
- media::Decryptor::Status status =
- PpDecryptResultToMediaDecryptorStatus(block_info->result);
- if (status != media::Decryptor::kSuccess) {
- audio_decode_cb.Run(status, empty_frames);
- return;
- }
-
- media::Decryptor::AudioBuffers audio_frame_list;
- if (!DeserializeAudioFrames(audio_frames, &audio_frame_list)) {
- NOTREACHED() << "CDM did not serialize the buffer correctly.";
- audio_decode_cb.Run(media::Decryptor::kError, empty_frames);
- return;
- }
-
- audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list);
+ content_decryptor_delegate_->DeliverSamples(audio_frames, block_info);
}
void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance,
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h
index 426106e..762510a 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.h
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h
@@ -5,20 +5,17 @@
#ifndef WEBKIT_PLUGINS_PPAPI_PPAPI_PLUGIN_INSTANCE_H_
#define WEBKIT_PLUGINS_PPAPI_PPAPI_PLUGIN_INSTANCE_H_
-#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/basictypes.h"
-#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/string16.h"
#include "googleurl/src/gurl.h"
-#include "media/base/decryptor.h"
#include "ppapi/c/dev/pp_cursor_type_dev.h"
#include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/dev/ppp_find_dev.h"
@@ -38,7 +35,6 @@
#include "ppapi/c/ppp_messaging.h"
#include "ppapi/c/ppp_mouse_lock.h"
#include "ppapi/c/private/ppb_content_decryptor_private.h"
-#include "ppapi/c/private/ppp_content_decryptor_private.h"
#include "ppapi/c/private/ppp_instance_private.h"
#include "ppapi/shared_impl/ppb_instance_shared.h"
#include "ppapi/shared_impl/ppb_view_shared.h"
@@ -58,7 +54,6 @@
#include "webkit/plugins/ppapi/ppp_pdf.h"
#include "webkit/plugins/webkit_plugins_export.h"
-struct PP_DecryptedBlockInfo;
struct PP_Point;
class SkBitmap;
@@ -73,13 +68,6 @@ struct WebCursorInfo;
struct WebPrintParams;
}
-namespace media {
-class AudioDecoderConfig;
-class DecoderBuffer;
-class DecryptorClient;
-class VideoDecoderConfig;
-}
-
namespace ppapi {
struct InputEventData;
struct PPP_Instance_Combined;
@@ -94,6 +82,7 @@ class Range;
namespace webkit {
namespace ppapi {
+class ContentDecryptorDelegate;
class FullscreenContainer;
class MessageChannel;
class PluginDelegate;
@@ -254,38 +243,6 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
void Graphics3DContextLost();
- // Provides access to PPP_ContentDecryptor_Private.
- // TODO(tomfinegan): Move decryptor methods to delegate class.
- void set_decrypt_client(media::DecryptorClient* client);
- bool GenerateKeyRequest(const std::string& key_system,
- const std::string& type,
- const std::string& init_data);
- bool AddKey(const std::string& session_id,
- const std::string& key,
- const std::string& init_data);
- bool CancelKeyRequest(const std::string& session_id);
- bool Decrypt(media::Decryptor::StreamType stream_type,
- const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
- const media::Decryptor::DecryptCB& decrypt_cb);
- bool CancelDecrypt(media::Decryptor::StreamType stream_type);
- bool InitializeAudioDecoder(
- const media::AudioDecoderConfig& decoder_config,
- const media::Decryptor::DecoderInitCB& decoder_init_cb);
- bool InitializeVideoDecoder(
- const media::VideoDecoderConfig& decoder_config,
- const media::Decryptor::DecoderInitCB& decoder_init_cb);
- // TODO(tomfinegan): Add callback args for DeinitializeDecoder() and
- // ResetDecoder()
- bool DeinitializeDecoder(media::Decryptor::StreamType stream_type);
- bool ResetDecoder(media::Decryptor::StreamType stream_type);
- // Note: These methods can be used with unencrypted data.
- bool DecryptAndDecodeAudio(
- const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
- const media::Decryptor::AudioDecodeCB& audio_decode_cb);
- bool DecryptAndDecodeVideo(
- const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
- const media::Decryptor::VideoDecodeCB& video_decode_cb);
-
// There are 2 implementations of the fullscreen interface
// PPB_FlashFullscreen is used by Pepper Flash.
// PPB_Fullscreen is intended for other applications including NaCl.
@@ -381,6 +338,8 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
void SimulateImeSetCompositionEvent(
const ::ppapi::InputEventData& input_event);
+ ContentDecryptorDelegate* GetContentDecryptorDelegate();
+
// PPB_Instance_API implementation.
virtual PP_Bool BindGraphics(PP_Instance instance,
PP_Resource device) OVERRIDE;
@@ -458,9 +417,7 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
PP_Instance instance,
PP_URLComponents_Dev* components) OVERRIDE;
- // PPB_ContentDecryptor_Private
- // TODO(tomfinegan): Move the PPB_ContentDecryptor_Private methods to a
- // delegate class.
+ // PPB_ContentDecryptor_Private implementation.
virtual void NeedKey(PP_Instance instance,
PP_Var key_system,
PP_Var session_id,
@@ -525,7 +482,6 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
PluginModule* module,
::ppapi::PPP_Instance_Combined* instance_interface);
- bool LoadContentDecryptorInterface();
bool LoadFindInterface();
bool LoadInputEventInterface();
bool LoadMessagingInterface();
@@ -605,9 +561,6 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
void SetSizeAttributesForFullscreen();
void ResetSizeAttributesAfterFullscreen();
- // Cancels the pending decrypt-and-decode callback for |stream_type|.
- void CancelDecode(media::Decryptor::StreamType stream_type);
-
PluginDelegate* delegate_;
scoped_refptr<PluginModule> module_;
scoped_ptr< ::ppapi::PPP_Instance_Combined> instance_interface_;
@@ -662,7 +615,6 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
// The plugin-provided interfaces.
// When adding PPP interfaces, make sure to reset them in ResetAsProxied.
- const PPP_ContentDecryptor_Private* plugin_decryption_interface_;
const PPP_Find_Dev* plugin_find_interface_;
const PPP_InputEvent* plugin_input_event_interface_;
const PPP_Messaging* plugin_messaging_interface_;
@@ -796,31 +748,9 @@ class WEBKIT_PLUGINS_EXPORT PluginInstance :
// the pointer so we can re-send it later if we are reset to talk to NaCl.
scoped_refptr<PPB_URLLoader_Impl> document_loader_;
- media::DecryptorClient* decryptor_client_;
-
- // Request ID for tracking pending content decryption callbacks.
- // Note that zero indicates an invalid request ID.
- // TODO(xhwang): Add completion callbacks for Reset/Stop and remove the use
- // of request IDs.
- uint32_t next_decryption_request_id_;
-
- uint32_t pending_audio_decrypt_request_id_;
- media::Decryptor::DecryptCB pending_audio_decrypt_cb_;
-
- uint32_t pending_video_decrypt_request_id_;
- media::Decryptor::DecryptCB pending_video_decrypt_cb_;
-
- uint32_t pending_audio_decoder_init_request_id_;
- media::Decryptor::DecoderInitCB pending_audio_decoder_init_cb_;
-
- uint32_t pending_video_decoder_init_request_id_;
- media::Decryptor::DecoderInitCB pending_video_decoder_init_cb_;
-
- uint32_t pending_audio_decode_request_id_;
- media::Decryptor::AudioDecodeCB pending_audio_decode_cb_;
-
- uint32_t pending_video_decode_request_id_;
- media::Decryptor::VideoDecodeCB pending_video_decode_cb_;
+ // The ContentDecryptorDelegate forwards PPP_ContentDecryptor_Private
+ // calls and handles PPB_ContentDecryptor_Private calls.
+ scoped_ptr<ContentDecryptorDelegate> content_decryptor_delegate_;
DISALLOW_COPY_AND_ASSIGN(PluginInstance);
};