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

Unified Diff: webkit/media/crypto/ppapi/cdm_wrapper.cc

Issue 10914028: Add CDM allocator interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | webkit/media/crypto/ppapi/clear_key_cdm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/media/crypto/ppapi/cdm_wrapper.cc
diff --git a/webkit/media/crypto/ppapi/cdm_wrapper.cc b/webkit/media/crypto/ppapi/cdm_wrapper.cc
index ef9afddc39fa755ae0abfc35821f05ba2d6cd628..8300171af8cdac37082c92f3c6f783c0f8020245 100644
--- a/webkit/media/crypto/ppapi/cdm_wrapper.cc
+++ b/webkit/media/crypto/ppapi/cdm_wrapper.cc
@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <cstring> // For memcpy.
+#include <cstring>
+#include <string>
#include <vector>
-#include "base/compiler_specific.h" // For OVERRIDE.
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/private/pp_content_decryptor.h"
@@ -21,6 +23,7 @@
#include "ppapi/cpp/dev/buffer_dev.h"
#include "ppapi/cpp/private/content_decryptor_private.h"
#include "ppapi/utility/completion_callback_factory.h"
+#include "webkit/media/crypto/ppapi/linked_ptr.h"
#include "webkit/media/crypto/ppapi/content_decryption_module.h"
namespace {
@@ -55,6 +58,155 @@ void CallOnMain(pp::CompletionCallback cb) {
namespace webkit_media {
+// Provides access to memory owned by a pp::Buffer_Dev created by
+// PpbBufferAllocator::Allocate(). This class holds a reference to the
+// Buffer_Dev throughout its lifetime.
+class PpbBuffer : public cdm::Buffer {
+ public:
+ // cdm::Buffer methods.
+ virtual void Destroy() OVERRIDE { delete this; }
+
+ virtual uint8_t* buffer() OVERRIDE {
+ return static_cast<uint8_t*>(buffer_.data());
+ }
+
+ virtual int32_t size() const OVERRIDE { return buffer_.size(); }
+
+ pp::Buffer_Dev buffer_dev() const { return buffer_; }
+
+ private:
+ explicit PpbBuffer(pp::Buffer_Dev buffer) : buffer_(buffer) {}
+ virtual ~PpbBuffer() {}
+
+ pp::Buffer_Dev buffer_;
+
+ friend class PpbBufferAllocator;
+
+ DISALLOW_COPY_AND_ASSIGN(PpbBuffer);
+};
+
+class PpbBufferAllocator : public cdm::Allocator {
+ public:
+ explicit PpbBufferAllocator(pp::Instance* instance);
+ virtual ~PpbBufferAllocator();
+
+ // cdm::Allocator methods.
+ // Allocates a pp::Buffer_Dev of the specified size and wraps it in a
+ // PpbBuffer, which it returns. The caller own the returned buffer and must
+ // free it by calling ReleaseBuffer(). Returns NULL on failure.
+ virtual cdm::Buffer* Allocate(int32_t size) OVERRIDE;
+
+ private:
+ pp::Instance* const instance_;
+
+ DISALLOW_COPY_AND_ASSIGN(PpbBufferAllocator);
+};
+
+class KeyMessageImpl : public cdm::KeyMessage {
+ public:
+ KeyMessageImpl() : message_(NULL) {}
+ virtual ~KeyMessageImpl();
+
+ // cdm::KeyMessage methods.
+ virtual void set_session_id(const char* session_id, int32_t length) OVERRIDE;
+ virtual const char* session_id() const OVERRIDE;
+ virtual int32_t session_id_length() const OVERRIDE;
+
+ virtual void set_message(cdm::Buffer* message) OVERRIDE;
+ virtual cdm::Buffer* message() const OVERRIDE;
+
+ virtual void set_default_url(const char* default_url,
+ int32_t length) OVERRIDE;
+ virtual const char* default_url() const OVERRIDE;
+ virtual int32_t default_url_length() const OVERRIDE;
+
+ std::string session_id_string() const { return session_id_; }
+ std::string default_url_string() const { return default_url_; }
+
+ private:
+ PpbBuffer* message_;
+ std::string session_id_;
+ std::string default_url_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyMessageImpl);
+};
+
+class OutputBufferImpl : public cdm::OutputBuffer {
+ public:
+ OutputBufferImpl() : buffer_(NULL), timestamp_(0) {}
+ virtual ~OutputBufferImpl();
+
+ virtual void set_buffer(cdm::Buffer* buffer) OVERRIDE;
+ virtual cdm::Buffer* buffer() const OVERRIDE;
+
+ virtual void set_timestamp(int64_t timestamp) OVERRIDE;
+ virtual int64_t timestamp() const OVERRIDE;
+
+ private:
+ PpbBuffer* buffer_;
+ int64_t timestamp_;
+
+ DISALLOW_COPY_AND_ASSIGN(OutputBufferImpl);
+};
+
+KeyMessageImpl::~KeyMessageImpl() {
+ if (message_)
+ message_->Destroy();
+}
+
+void KeyMessageImpl::set_session_id(const char* session_id, int32_t length) {
+ session_id_.assign(session_id, length);
+}
+
+const char* KeyMessageImpl::session_id() const {
+ return session_id_.c_str();
+}
+
+int32_t KeyMessageImpl::session_id_length() const {
+ return session_id_.length();
+}
+
+void KeyMessageImpl::set_message(cdm::Buffer* buffer) {
+ message_ = static_cast<PpbBuffer*>(buffer);
+}
+
+cdm::Buffer* KeyMessageImpl::message() const {
+ return message_;
+}
+
+void KeyMessageImpl::set_default_url(const char* default_url, int32_t length) {
+ default_url_.assign(default_url, length);
+}
+
+const char* KeyMessageImpl::default_url() const {
+ return default_url_.c_str();
+}
+
+int32_t KeyMessageImpl::default_url_length() const {
+ return default_url_.length();
+}
+
+OutputBufferImpl::~OutputBufferImpl() {
+ if (buffer_)
+ buffer_->Destroy();
+}
+
+void OutputBufferImpl::set_buffer(cdm::Buffer* buffer) {
+ buffer_ = static_cast<PpbBuffer*>(buffer);
+}
+
+cdm::Buffer* OutputBufferImpl::buffer() const {
+ return buffer_;
+}
+
+void OutputBufferImpl::set_timestamp(int64_t timestamp) {
+ timestamp_ = timestamp;
+}
+
+int64_t OutputBufferImpl::timestamp() const {
+ return timestamp_;
+}
+
// A wrapper class for abstracting away PPAPI interaction and threading for a
// Content Decryption Module (CDM).
class CdmWrapper : public pp::Instance,
@@ -62,7 +214,6 @@ class CdmWrapper : public pp::Instance,
public:
CdmWrapper(PP_Instance instance, pp::Module* module);
virtual ~CdmWrapper();
-
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
return true;
}
@@ -86,31 +237,47 @@ class CdmWrapper : public pp::Instance,
const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
private:
- // 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::Buffer_Dev MakeBufferResource(const uint8_t* data, uint32_t data_size);
+ typedef linked_ptr<KeyMessageImpl> LinkedKeyMessage;
+ typedef linked_ptr<OutputBufferImpl> LinkedOutputBuffer;
// <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to
// <code>callback_factory_</code> to ensure that calls into
// <code>PPP_ContentDecryptor_Private</code> are asynchronous.
void KeyAdded(int32_t result, const std::string& session_id);
- void KeyMessage(int32_t result, cdm::KeyMessage& key_message);
+ void KeyMessage(int32_t result, const LinkedKeyMessage& message);
void KeyError(int32_t result, const std::string& session_id);
void DeliverBlock(int32_t result,
const cdm::Status& status,
- cdm::OutputBuffer& output_buffer,
+ const LinkedOutputBuffer& output_buffer,
const PP_DecryptTrackingInfo& tracking_info);
+ PpbBufferAllocator allocator_;
pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
cdm::ContentDecryptionModule* cdm_;
std::string key_system_;
};
+PpbBufferAllocator::PpbBufferAllocator(pp::Instance* instance)
+ : instance_(instance) {
+}
+
+PpbBufferAllocator::~PpbBufferAllocator() {
+}
+
+cdm::Buffer* PpbBufferAllocator::Allocate(int32_t size) {
+ PP_DCHECK(size > 0);
+
+ pp::Buffer_Dev buffer(instance_, size);
+ if (buffer.is_null())
+ return NULL;
+
+ return new PpbBuffer(buffer);
+}
+
CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
: pp::Instance(instance),
pp::ContentDecryptor_Private(this),
+ allocator_(this),
cdm_(NULL) {
callback_factory_.Initialize(this);
}
@@ -125,20 +292,20 @@ void CdmWrapper::GenerateKeyRequest(const std::string& key_system,
PP_DCHECK(!key_system.empty());
if (!cdm_) {
- cdm_ = CreateCdmInstance();
+ cdm_ = CreateCdmInstance(&allocator_);
if (!cdm_)
return;
}
- cdm::KeyMessage key_request;
+ LinkedKeyMessage key_request(new KeyMessageImpl());
cdm::Status status = cdm_->GenerateKeyRequest(
reinterpret_cast<const uint8_t*>(init_data.Map()),
init_data.ByteLength(),
- &key_request);
+ key_request.get());
if (status != cdm::kSuccess ||
- !key_request.message ||
- key_request.message_size == 0) {
+ !key_request->message() ||
+ key_request->message()->size() == 0) {
CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError,
std::string()));
return;
@@ -222,9 +389,16 @@ void CdmWrapper::Decrypt(pp::Buffer_Dev encrypted_buffer,
input_buffer.timestamp = encrypted_block_info.tracking_info.timestamp;
- cdm::OutputBuffer output_buffer;
- cdm::Status status = cdm_->Decrypt(input_buffer, &output_buffer);
+ LinkedOutputBuffer output_buffer(new OutputBufferImpl());
+ cdm::Status status = cdm_->Decrypt(input_buffer, output_buffer.get());
+ if (status != cdm::kSuccess || !output_buffer->buffer()) {
+ CallOnMain(callback_factory_.NewCallback(&CdmWrapper::KeyError,
+ std::string()));
+ return;
+ }
+
+ PP_DCHECK(output_buffer->buffer());
CallOnMain(callback_factory_.NewCallback(
&CdmWrapper::DeliverBlock,
status,
@@ -237,41 +411,19 @@ void CdmWrapper::DecryptAndDecode(
const PP_EncryptedBlockInfo& encrypted_block_info) {
}
-pp::Buffer_Dev CdmWrapper::MakeBufferResource(const uint8_t* data,
- uint32_t data_size) {
- if (!data || !data_size)
- return pp::Buffer_Dev();
-
- pp::Buffer_Dev buffer(this, data_size);
- if (!buffer.data())
- return pp::Buffer_Dev();
-
- memcpy(buffer.data(), data, data_size);
- return buffer;
-}
-
void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) {
pp::ContentDecryptor_Private::KeyAdded(key_system_, session_id);
}
void CdmWrapper::KeyMessage(int32_t result,
- cdm::KeyMessage& key_message) {
- pp::Buffer_Dev message_buffer(MakeBufferResource(key_message.message,
- key_message.message_size));
+ const LinkedKeyMessage& key_message) {
+ pp::Buffer_Dev message_buffer =
+ static_cast<const PpbBuffer*>(key_message->message())->buffer_dev();
pp::ContentDecryptor_Private::KeyMessage(
key_system_,
- std::string(key_message.session_id, key_message.session_id_size),
+ key_message->session_id_string(),
message_buffer,
- std::string(key_message.default_url, key_message.default_url_size));
-
- // TODO(xhwang): Fix this. This is not always safe as the memory is allocated
- // in another shared object.
- delete [] key_message.session_id;
- key_message.session_id = NULL;
- delete [] key_message.message;
- key_message.message = NULL;
- delete [] key_message.default_url;
- key_message.default_url = NULL;
+ key_message->default_url_string());
}
// TODO(xhwang): Support MediaKeyError (see spec: http://goo.gl/rbdnR) in CDM
@@ -285,13 +437,11 @@ void CdmWrapper::KeyError(int32_t result, const std::string& session_id) {
void CdmWrapper::DeliverBlock(int32_t result,
const cdm::Status& status,
- cdm::OutputBuffer& output_buffer,
+ const LinkedOutputBuffer& output_buffer,
const PP_DecryptTrackingInfo& tracking_info) {
- pp::Buffer_Dev decrypted_buffer(MakeBufferResource(output_buffer.data,
- output_buffer.data_size));
PP_DecryptedBlockInfo decrypted_block_info;
decrypted_block_info.tracking_info.request_id = tracking_info.request_id;
- decrypted_block_info.tracking_info.timestamp = output_buffer.timestamp;
+ decrypted_block_info.tracking_info.timestamp = output_buffer->timestamp();
switch (status) {
case cdm::kSuccess:
@@ -304,21 +454,17 @@ void CdmWrapper::DeliverBlock(int32_t result,
decrypted_block_info.result = PP_DECRYPTRESULT_DECRYPT_ERROR;
}
- pp::ContentDecryptor_Private::DeliverBlock(decrypted_buffer,
- decrypted_block_info);
-
- // TODO(xhwang): Fix this. This is not always safe as the memory is allocated
- // in another shared object.
- delete [] output_buffer.data;
- output_buffer.data = NULL;
+ pp::ContentDecryptor_Private::DeliverBlock(
+ static_cast<PpbBuffer*>(output_buffer->buffer())->buffer_dev(),
+ decrypted_block_info);
}
// This object is the global object representing this plugin library as long
// as it is loaded.
-class MyModule : public pp::Module {
+class CdmWrapperModule : public pp::Module {
public:
- MyModule() : pp::Module() {}
- virtual ~MyModule() {}
+ CdmWrapperModule() : pp::Module() {}
+ virtual ~CdmWrapperModule() {}
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new CdmWrapper(instance, this);
@@ -331,7 +477,7 @@ namespace pp {
// Factory function for your specialization of the Module object.
Module* CreateModule() {
- return new webkit_media::MyModule();
+ return new webkit_media::CdmWrapperModule();
}
} // namespace pp
« no previous file with comments | « no previous file | webkit/media/crypto/ppapi/clear_key_cdm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698