summaryrefslogtreecommitdiffstats
path: root/chromium/media/cdm/ppapi/cdm_wrapper.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/media/cdm/ppapi/cdm_wrapper.h')
-rw-r--r--chromium/media/cdm/ppapi/cdm_wrapper.h431
1 files changed, 162 insertions, 269 deletions
diff --git a/chromium/media/cdm/ppapi/cdm_wrapper.h b/chromium/media/cdm/ppapi/cdm_wrapper.h
index d827336a8c6..665b6b68dad 100644
--- a/chromium/media/cdm/ppapi/cdm_wrapper.h
+++ b/chromium/media/cdm/ppapi/cdm_wrapper.h
@@ -35,16 +35,6 @@ namespace media {
// (just a shim layer in most cases), everything is done in this header file.
class CdmWrapper {
public:
- // CDM_1 and CDM_2 methods AddKey() and CancelKeyRequest() may require
- // callbacks to fire. Use this enum to indicate the additional calls required.
- // TODO(jrummell): Remove return value once CDM_1 and CDM_2 are no longer
- // supported.
- enum Result {
- NO_ACTION,
- CALL_KEY_ADDED,
- CALL_KEY_ERROR
- };
-
static CdmWrapper* Create(const char* key_system,
uint32_t key_system_size,
GetCdmHostFunc get_cdm_host_func,
@@ -52,15 +42,23 @@ class CdmWrapper {
virtual ~CdmWrapper() {};
- virtual void CreateSession(uint32_t session_id,
- const char* type,
- uint32_t type_size,
+ virtual void CreateSession(uint32_t promise_id,
+ const char* init_data_type,
+ uint32_t init_data_type_size,
const uint8_t* init_data,
- uint32_t init_data_size) = 0;
- virtual Result UpdateSession(uint32_t session_id,
- const uint8_t* response,
- uint32_t response_size) = 0;
- virtual Result ReleaseSession(uint32_t session_id) = 0;
+ uint32_t init_data_size,
+ cdm::SessionType session_type) = 0;
+ virtual void LoadSession(uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) = 0;
+ virtual void UpdateSession(uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size,
+ const uint8_t* response,
+ uint32_t response_size) = 0;
+ virtual void ReleaseSession(uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) = 0;
virtual void TimerExpired(void* context) = 0;
virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer,
cdm::DecryptedBlock* decrypted_buffer) = 0;
@@ -82,42 +80,23 @@ class CdmWrapper {
uint32_t link_mask,
uint32_t output_protection_mask) = 0;
- // ContentDecryptionModule_1 and ContentDecryptionModule_2 interface methods
- // AddKey() and CancelKeyRequest() (older versions of UpdateSession() and
- // ReleaseSession(), respectively) pass in the web_session_id rather than the
- // session_id. As well, Host_1 and Host_2 callbacks SendKeyMessage() and
- // SendKeyError() include the web_session_id, but the actual callbacks need
- // session_id.
- //
- // The following functions maintain the session_id <-> web_session_id mapping.
- // These can be removed once _1 and _2 interfaces are no longer supported.
-
- // Determine the corresponding session_id for |web_session_id|.
- virtual uint32_t LookupSessionId(const std::string& web_session_id) = 0;
-
- // Determine the corresponding session_id for |session_id|.
- virtual const std::string LookupWebSessionId(uint32_t session_id) = 0;
-
- // Map between session_id and web_session_id.
- // TODO(jrummell): The following can be removed once CDM_1 and CDM_2 are
- // no longer supported.
- typedef std::map<uint32_t, std::string> SessionMap;
- SessionMap session_map_;
-
- static const uint32_t kInvalidSessionId = 0;
-
- // As the response from PrefixedGenerateKeyRequest() may be synchronous or
- // asynchronous, keep track of the current request during the call to handle
- // synchronous responses or errors. If no response received, add this request
- // to a queue and assume that the subsequent responses come back in the order
- // issued.
- // TODO(jrummell): Remove once all supported CDM host interfaces support
- // session_id.
- uint32_t current_key_request_session_id_;
- std::queue<uint32_t> pending_key_request_session_ids_;
+ // Helper function for the cdm::Host_4 methods. Calls to CreateSession(),
+ // LoadSession(), UpdateSession(), and ReleaseSession() pass in promise ids,
+ // but the CDM interface needs session ids. For create and load, we need to
+ // create a new session_id to pass to the CDM. For update and release, we need
+ // to look up |web_session_id| and convert it into the existing |session_id|.
+ // Since the callbacks don't come through this interface, cdm_adapter needs to
+ // create the mapping (and delete it on release).
+ // TODO(jrummell): Remove these once Host_4 interface is removed.
+ virtual uint32_t LookupPromiseId(uint32_t session_id) = 0;
+ virtual void AssignWebSessionId(uint32_t session_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) = 0;
+ virtual std::string LookupWebSessionId(uint32_t session_id) = 0;
+ virtual void DropWebSessionId(std::string web_session_id) = 0;
protected:
- CdmWrapper() : current_key_request_session_id_(kInvalidSessionId) {}
+ CdmWrapper() {}
private:
DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
@@ -147,24 +126,42 @@ class CdmWrapperImpl : public CdmWrapper {
cdm_->Destroy();
}
- virtual void CreateSession(uint32_t session_id,
- const char* type,
- uint32_t type_size,
+ virtual void CreateSession(uint32_t promise_id,
+ const char* init_data_type,
+ uint32_t init_data_type_size,
const uint8_t* init_data,
- uint32_t init_data_size) OVERRIDE {
- cdm_->CreateSession(session_id, type, type_size, init_data, init_data_size);
+ uint32_t init_data_size,
+ cdm::SessionType session_type) OVERRIDE {
+ cdm_->CreateSession(promise_id,
+ init_data_type,
+ init_data_type_size,
+ init_data,
+ init_data_size,
+ session_type);
+ }
+
+ virtual void LoadSession(uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) OVERRIDE {
+ cdm_->LoadSession(promise_id, web_session_id, web_session_id_size);
}
- virtual Result UpdateSession(uint32_t session_id,
- const uint8_t* response,
- uint32_t response_size) OVERRIDE {
- cdm_->UpdateSession(session_id, response, response_size);
- return NO_ACTION;
+ virtual void UpdateSession(uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size,
+ const uint8_t* response,
+ uint32_t response_size) OVERRIDE {
+ cdm_->UpdateSession(promise_id,
+ web_session_id,
+ web_session_id_size,
+ response,
+ response_size);
}
- virtual Result ReleaseSession(uint32_t session_id) OVERRIDE {
- cdm_->ReleaseSession(session_id);
- return NO_ACTION;
+ virtual void ReleaseSession(uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) OVERRIDE {
+ cdm_->ReleaseSession(promise_id, web_session_id, web_session_id_size);
}
virtual void TimerExpired(void* context) OVERRIDE {
@@ -217,223 +214,125 @@ class CdmWrapperImpl : public CdmWrapper {
cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask);
}
- uint32_t LookupSessionId(const std::string& web_session_id) {
- for (SessionMap::iterator it = session_map_.begin();
- it != session_map_.end();
- ++it) {
- if (it->second == web_session_id)
- return it->first;
- }
-
- // There is no entry in the map; assume it came from the current
- // PrefixedGenerateKeyRequest() call (if possible). If no current request,
- // assume it came from the oldest PrefixedGenerateKeyRequest() call.
- uint32_t session_id = current_key_request_session_id_;
- if (current_key_request_session_id_) {
- // Only 1 response is allowed for the current
- // PrefixedGenerateKeyRequest().
- current_key_request_session_id_ = kInvalidSessionId;
- } else {
- PP_DCHECK(!pending_key_request_session_ids_.empty());
- session_id = pending_key_request_session_ids_.front();
- pending_key_request_session_ids_.pop();
- }
-
- // If this is a valid |session_id|, add it to the list. Otherwise, avoid
- // adding empty string as a mapping to prevent future calls with an empty
- // string from using the wrong session_id.
- if (!web_session_id.empty()) {
- PP_DCHECK(session_map_.find(session_id) == session_map_.end());
- session_map_[session_id] = web_session_id;
- }
-
- return session_id;
+ uint32_t CreateSessionId() {
+ return next_session_id_++;
}
- const std::string LookupWebSessionId(uint32_t session_id) {
- // Session may not exist if error happens during CreateSession().
- SessionMap::iterator it = session_map_.find(session_id);
- return (it != session_map_.end()) ? it->second : std::string();
+ void RegisterPromise(uint32_t session_id, uint32_t promise_id) {
+ PP_DCHECK(promise_to_session_id_map_.find(session_id) ==
+ promise_to_session_id_map_.end());
+ promise_to_session_id_map_.insert(std::make_pair(session_id, promise_id));
}
- private:
- CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) {
- PP_DCHECK(cdm_);
+ virtual uint32_t LookupPromiseId(uint32_t session_id) {
+ std::map<uint32_t, uint32_t>::iterator it =
+ promise_to_session_id_map_.find(session_id);
+ if (it == promise_to_session_id_map_.end())
+ return 0;
+ uint32_t promise_id = it->second;
+ promise_to_session_id_map_.erase(it);
+ return promise_id;
}
- CdmInterface* cdm_;
-
- DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl);
-};
-
-// For ContentDecryptionModule_1 and ContentDecryptionModule_2,
-// CreateSession(), UpdateSession(), and ReleaseSession() call methods
-// are incompatible with ContentDecryptionModule_3. Use the following
-// templated functions to handle this.
-
-template <class CdmInterface>
-void PrefixedGenerateKeyRequest(CdmWrapper* wrapper,
- CdmInterface* cdm,
- uint32_t session_id,
- const char* type,
- uint32_t type_size,
- const uint8_t* init_data,
- uint32_t init_data_size) {
- // As it is possible for CDMs to reply synchronously during the call to
- // GenerateKeyRequest(), keep track of |session_id|.
- wrapper->current_key_request_session_id_ = session_id;
-
- cdm::Status status =
- cdm->GenerateKeyRequest(type, type_size, init_data, init_data_size);
- PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
- if (status != cdm::kSuccess) {
- // If GenerateKeyRequest() failed, no subsequent asynchronous replies
- // will be sent. Verify that a response was sent synchronously.
- PP_DCHECK(wrapper->current_key_request_session_id_ ==
- CdmWrapper::kInvalidSessionId);
- wrapper->current_key_request_session_id_ = CdmWrapper::kInvalidSessionId;
- return;
+ virtual void AssignWebSessionId(uint32_t session_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) {
+ web_session_to_session_id_map_.insert(std::make_pair(
+ std::string(web_session_id, web_session_id_size), session_id));
}
- if (wrapper->current_key_request_session_id_) {
- // If this request is still pending (SendKeyMessage() or SendKeyError()
- // not called synchronously), add |session_id| to the end of the queue.
- // Without CDM support, it is impossible to match SendKeyMessage()
- // (or SendKeyError()) responses to the |session_id|. Doing the best
- // we can by keeping track of this in a queue, and assuming the responses
- // come back in order.
- wrapper->pending_key_request_session_ids_.push(session_id);
- wrapper->current_key_request_session_id_ = CdmWrapper::kInvalidSessionId;
+ uint32_t LookupSessionId(std::string web_session_id) {
+ return web_session_to_session_id_map_.find(web_session_id)->second;
}
-}
-template <class CdmInterface>
-CdmWrapper::Result PrefixedAddKey(CdmWrapper* wrapper,
- CdmInterface* cdm,
- uint32_t session_id,
- const uint8_t* response,
- uint32_t response_size) {
- const std::string web_session_id = wrapper->LookupWebSessionId(session_id);
- if (web_session_id.empty()) {
- // Possible if UpdateSession() called before CreateSession().
- return CdmWrapper::CALL_KEY_ERROR;
+ virtual std::string LookupWebSessionId(uint32_t session_id) {
+ std::map<std::string, uint32_t>::iterator it;
+ for (it = web_session_to_session_id_map_.begin();
+ it != web_session_to_session_id_map_.end();
+ ++it) {
+ if (it->second == session_id)
+ return it->first;
+ }
+ PP_NOTREACHED();
+ return std::string();
}
- // CDM_1 and CDM_2 accept initdata, which is no longer needed.
- // In it's place pass in NULL.
- cdm::Status status = cdm->AddKey(web_session_id.data(), web_session_id.size(),
- response, response_size,
- NULL, 0);
- PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
- if (status != cdm::kSuccess) {
- // Some CDMs using Host_1/2 don't call keyerror, so send one.
- return CdmWrapper::CALL_KEY_ERROR;
+ virtual void DropWebSessionId(std::string web_session_id) {
+ web_session_to_session_id_map_.erase(web_session_id);
}
- return CdmWrapper::CALL_KEY_ADDED;
-}
-
-template <class CdmInterface>
-CdmWrapper::Result PrefixedCancelKeyRequest(CdmWrapper* wrapper,
- CdmInterface* cdm,
- uint32_t session_id) {
- const std::string web_session_id = wrapper->LookupWebSessionId(session_id);
- if (web_session_id.empty()) {
- // Possible if ReleaseSession() called before CreateSession().
- return CdmWrapper::CALL_KEY_ERROR;
+ private:
+ CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm), next_session_id_(100) {
+ PP_DCHECK(cdm_);
}
- wrapper->session_map_.erase(session_id);
- cdm::Status status =
- cdm->CancelKeyRequest(web_session_id.data(), web_session_id.size());
+ CdmInterface* cdm_;
- PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
- if (status != cdm::kSuccess) {
- // Some CDMs using Host_1/2 don't call keyerror, so send one.
- return CdmWrapper::CALL_KEY_ERROR;
- }
+ std::map<uint32_t, uint32_t> promise_to_session_id_map_;
+ uint32_t next_session_id_;
+ std::map<std::string, uint32_t> web_session_to_session_id_map_;
- return CdmWrapper::NO_ACTION;
-}
+ DISALLOW_COPY_AND_ASSIGN(CdmWrapperImpl);
+};
-// Specializations for ContentDecryptionModule_1.
+// Overrides for the cdm::Host_4 methods. Calls to CreateSession(),
+// LoadSession(), UpdateSession(), and ReleaseSession() pass in promise ids,
+// but the CDM interface needs session ids. For create and load, we need to
+// create a new session_id to pass to the CDM. For update and release, we need
+// to look up |web_session_id| and convert it into the existing |session_id|.
+// Since the callbacks don't come through this interface, cdm_adapter needs to
+// create the mapping (and delete it on release).
+// TODO(jrummell): Remove these once Host_4 interface is removed.
template <>
-void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::CreateSession(
- uint32_t session_id,
- const char* type,
- uint32_t type_size,
+void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::CreateSession(
+ uint32_t promise_id,
+ const char* init_data_type,
+ uint32_t init_data_type_size,
const uint8_t* init_data,
- uint32_t init_data_size) {
- PrefixedGenerateKeyRequest(
- this, cdm_, session_id, type, type_size, init_data, init_data_size);
+ uint32_t init_data_size,
+ cdm::SessionType session_type) {
+ uint32_t session_id = CreateSessionId();
+ RegisterPromise(session_id, promise_id);
+ cdm_->CreateSession(session_id,
+ init_data_type,
+ init_data_type_size,
+ init_data,
+ init_data_size);
}
template <>
-CdmWrapper::Result CdmWrapperImpl<
- cdm::ContentDecryptionModule_1>::UpdateSession(uint32_t session_id,
- const uint8_t* response,
- uint32_t response_size) {
- return PrefixedAddKey(this, cdm_, session_id, response, response_size);
+void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::LoadSession(
+ uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) {
+ uint32_t session_id = CreateSessionId();
+ RegisterPromise(session_id, promise_id);
+ cdm_->LoadSession(session_id, web_session_id, web_session_id_size);
}
template <>
-CdmWrapper::Result CdmWrapperImpl<
- cdm::ContentDecryptionModule_1>::ReleaseSession(uint32_t session_id) {
- return PrefixedCancelKeyRequest(this, cdm_, session_id);
-}
-
-template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
- OnPlatformChallengeResponse(
- const cdm::PlatformChallengeResponse& response) {
- PP_NOTREACHED();
-}
-
-template <> void CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
- OnQueryOutputProtectionStatus(uint32_t link_mask,
- uint32_t output_protection_mask) {
- PP_NOTREACHED();
-}
-
-template <> cdm::Status CdmWrapperImpl<cdm::ContentDecryptionModule_1>::
- DecryptAndDecodeSamples(const cdm::InputBuffer& encrypted_buffer,
- cdm::AudioFrames* audio_frames) {
- AudioFramesImpl audio_frames_1;
- cdm::Status status =
- cdm_->DecryptAndDecodeSamples(encrypted_buffer, &audio_frames_1);
- if (status != cdm::kSuccess)
- return status;
-
- audio_frames->SetFrameBuffer(audio_frames_1.PassFrameBuffer());
- audio_frames->SetFormat(cdm::kAudioFormatS16);
- return cdm::kSuccess;
+void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::UpdateSession(
+ uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size,
+ const uint8_t* response,
+ uint32_t response_size) {
+ std::string web_session_str(web_session_id, web_session_id_size);
+ uint32_t session_id = LookupSessionId(web_session_str);
+ RegisterPromise(session_id, promise_id);
+ cdm_->UpdateSession(session_id, response, response_size);
}
-// Specializations for ContentDecryptionModule_2.
-
template <>
-void CdmWrapperImpl<cdm::ContentDecryptionModule_2>::CreateSession(
- uint32_t session_id,
- const char* type,
- uint32_t type_size,
- const uint8_t* init_data,
- uint32_t init_data_size) {
- PrefixedGenerateKeyRequest(
- this, cdm_, session_id, type, type_size, init_data, init_data_size);
-}
-
-template <>
-CdmWrapper::Result CdmWrapperImpl<
- cdm::ContentDecryptionModule_2>::UpdateSession(uint32_t session_id,
- const uint8_t* response,
- uint32_t response_size) {
- return PrefixedAddKey(this, cdm_, session_id, response, response_size);
-}
-
-template <>
-CdmWrapper::Result CdmWrapperImpl<
- cdm::ContentDecryptionModule_2>::ReleaseSession(uint32_t session_id) {
- return PrefixedCancelKeyRequest(this, cdm_, session_id);
+void CdmWrapperImpl<cdm::ContentDecryptionModule_4>::ReleaseSession(
+ uint32_t promise_id,
+ const char* web_session_id,
+ uint32_t web_session_id_size) {
+ std::string web_session_str(web_session_id, web_session_id_size);
+ uint32_t session_id = LookupSessionId(web_session_str);
+ RegisterPromise(session_id, promise_id);
+ cdm_->ReleaseSession(session_id);
}
CdmWrapper* CdmWrapper::Create(const char* key_system,
@@ -441,23 +340,21 @@ CdmWrapper* CdmWrapper::Create(const char* key_system,
GetCdmHostFunc get_cdm_host_func,
void* user_data) {
COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
- cdm::ContentDecryptionModule_3::kVersion,
+ cdm::ContentDecryptionModule_5::kVersion,
update_code_below);
- // Ensure IsSupportedCdmInterfaceVersion matches this implementation.
+ // Ensure IsSupportedCdmInterfaceVersion() matches this implementation.
// Always update this DCHECK when updating this function.
// If this check fails, update this function and DCHECK or update
- // IsSupportedCdmInterfaceVersion.
+ // IsSupportedCdmInterfaceVersion().
PP_DCHECK(
- !IsSupportedCdmInterfaceVersion(
- cdm::ContentDecryptionModule::kVersion + 1) &&
+ !IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule::kVersion +
+ 1) &&
IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule::kVersion) &&
IsSupportedCdmInterfaceVersion(
- cdm::ContentDecryptionModule_2::kVersion) &&
- IsSupportedCdmInterfaceVersion(
- cdm::ContentDecryptionModule_1::kVersion) &&
- !IsSupportedCdmInterfaceVersion(
- cdm::ContentDecryptionModule_1::kVersion - 1));
+ cdm::ContentDecryptionModule_4::kVersion) &&
+ !IsSupportedCdmInterfaceVersion(cdm::ContentDecryptionModule_4::kVersion -
+ 1));
// Try to create the CDM using the latest CDM interface version.
CdmWrapper* cdm_wrapper =
@@ -466,13 +363,9 @@ CdmWrapper* CdmWrapper::Create(const char* key_system,
if (cdm_wrapper)
return cdm_wrapper;
- // Try to see if the CDM supports older version(s) of the CDM interface.
- cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_2>::Create(
- key_system, key_system_size, get_cdm_host_func, user_data);
- if (cdm_wrapper)
- return cdm_wrapper;
-
- cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_1>::Create(
+ // If |cdm_wrapper| is NULL, try to create the CDM using older supported
+ // versions of the CDM interface.
+ cdm_wrapper = CdmWrapperImpl<cdm::ContentDecryptionModule_4>::Create(
key_system, key_system_size, get_cdm_host_func, user_data);
return cdm_wrapper;
}
@@ -482,7 +375,7 @@ CdmWrapper* CdmWrapper::Create(const char* key_system,
// does not have.
// Also update supported_cdm_versions.h.
COMPILE_ASSERT(cdm::ContentDecryptionModule::kVersion ==
- cdm::ContentDecryptionModule_3::kVersion,
+ cdm::ContentDecryptionModule_5::kVersion,
ensure_cdm_wrapper_templates_have_old_version_support);
} // namespace media