From 0b3f41ec8d2420aef8328e00cfbeb8bdbd183dd1 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Thu, 16 Feb 2017 12:20:30 -0800 Subject: [PATCH] Support multiple codecs per crypto instance The initial drm hidl hal implementation assumed one codec per crypto instance, but in fact there can be multiple codecs per crypto instance. This change extends the drm hal to allow multiple memory heaps per crypto plugin. It fixes the issue of mapping memory frequently during playback. bug:35275191 Test: manual verification with Play Movies on angler and in binderized mode on marlin Change-Id: I0ec36856248623d2ad8acb8ce9873e9274883a40 --- drm/1.0/ICryptoPlugin.hal | 10 +++++++++- drm/1.0/default/CryptoPlugin.cpp | 25 ++++++++++++++++++------- drm/1.0/default/CryptoPlugin.h | 6 +++--- drm/1.0/types.hal | 12 +++++++++--- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/drm/1.0/ICryptoPlugin.hal b/drm/1.0/ICryptoPlugin.hal index d66151e125..ca8fa502ac 100644 --- a/drm/1.0/ICryptoPlugin.hal +++ b/drm/1.0/ICryptoPlugin.hal @@ -62,8 +62,16 @@ interface ICryptoPlugin { * After the shared buffer base is established, the decrypt() method * receives SharedBuffer instances which specify the buffer address range * for decrypt source and destination addresses. + * + * There can be multiple shared buffers per crypto plugin. The buffers + * are distinguished by the bufferId. + * + * @param base the base IMemory of the memory buffer identified by + * bufferId + * @param bufferId identifies the specific shared buffer for which + * the base is being set. */ - setSharedBufferBase(memory base); + setSharedBufferBase(memory base, uint32_t bufferId); /** * Decrypt an array of subsamples from the source memory buffer to the diff --git a/drm/1.0/default/CryptoPlugin.cpp b/drm/1.0/default/CryptoPlugin.cpp index fb61ede14f..4a4171b66d 100644 --- a/drm/1.0/default/CryptoPlugin.cpp +++ b/drm/1.0/default/CryptoPlugin.cpp @@ -49,8 +49,9 @@ namespace implementation { return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId))); } - Return CryptoPlugin::setSharedBufferBase(const hidl_memory& base) { - mSharedBufferBase = mapMemory(base); + Return CryptoPlugin::setSharedBufferBase(const hidl_memory& base, + uint32_t bufferId) { + mSharedBufferMap[bufferId] = mapMemory(base); return Void(); } @@ -62,11 +63,19 @@ namespace implementation { const DestinationBuffer& destination, decrypt_cb _hidl_cb) { - if (mSharedBufferBase == NULL) { - _hidl_cb(Status::BAD_VALUE, 0, "decrypt buffer base not set"); + if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) { + _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set"); return Void(); } + if (destination.type == BufferType::SHARED_MEMORY) { + const SharedBuffer& dest = destination.nonsecureMemory; + if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) { + _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination decrypt buffer base not set"); + return Void(); + } + } + android::CryptoPlugin::Mode legacyMode; switch(mode) { case Mode::UNENCRYPTED: @@ -97,20 +106,22 @@ namespace implementation { } AString detailMessage; + sp sourceBase = mSharedBufferMap[source.bufferId]; - if (source.offset + offset + source.size > mSharedBufferBase->getSize()) { + if (source.offset + offset + source.size > sourceBase->getSize()) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } uint8_t *base = static_cast - (static_cast(mSharedBufferBase->getPointer())); + (static_cast(sourceBase->getPointer())); void *srcPtr = static_cast(base + source.offset + offset); void *destPtr = NULL; if (destination.type == BufferType::SHARED_MEMORY) { const SharedBuffer& destBuffer = destination.nonsecureMemory; - if (destBuffer.offset + destBuffer.size > mSharedBufferBase->getSize()) { + sp destBase = mSharedBufferMap[destBuffer.bufferId]; + if (destBuffer.offset + destBuffer.size > destBase->getSize()) { _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); return Void(); } diff --git a/drm/1.0/default/CryptoPlugin.h b/drm/1.0/default/CryptoPlugin.h index f805f09f2f..11cc2aae47 100644 --- a/drm/1.0/default/CryptoPlugin.h +++ b/drm/1.0/default/CryptoPlugin.h @@ -57,8 +57,8 @@ struct CryptoPlugin : public ICryptoPlugin { Return setMediaDrmSession(const hidl_vec& sessionId) override; - Return setSharedBufferBase(const ::android::hardware::hidl_memory& base) - override; + Return setSharedBufferBase(const ::android::hardware::hidl_memory& base, + uint32_t bufferId) override; Return decrypt(bool secure, const hidl_array& keyId, const hidl_array& iv, Mode mode, const Pattern& pattern, @@ -68,7 +68,7 @@ struct CryptoPlugin : public ICryptoPlugin { private: android::CryptoPlugin *mLegacyPlugin; - sp mSharedBufferBase; + std::map > mSharedBufferMap; CryptoPlugin() = delete; CryptoPlugin(const CryptoPlugin &) = delete; diff --git a/drm/1.0/types.hal b/drm/1.0/types.hal index 33bbf9adfc..52730444a8 100644 --- a/drm/1.0/types.hal +++ b/drm/1.0/types.hal @@ -293,11 +293,17 @@ enum BufferType : uint32_t { }; /** - * A SharedBuffer describes a decrypt buffer which is defined by an offset and - * a size. The offset is relative to the shared memory base which is established - * using setSharedMemoryBase(). + * SharedBuffer describes a decrypt buffer which is defined by a bufferId, an + * offset and a size. The offset is relative to the shared memory base for the + * memory region identified by bufferId, which is established by + * setSharedMemoryBase(). */ struct SharedBuffer { + /** + * The unique buffer identifier + */ + uint32_t bufferId; + /** * The offset from the shared memory base */