Merge changes from topic 'heapbase'
* changes:
DRM: more fixes for heap base mapping
Revert "Revert "Fix decoder instantiation during playback""
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 1466222..25c16da 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -105,7 +105,8 @@
CryptoHal::CryptoHal()
: mFactories(makeCryptoFactories()),
mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
- mNextBufferId(0) {
+ mNextBufferId(0),
+ mHeapSeqNum(0) {
}
CryptoHal::~CryptoHal() {
@@ -225,26 +226,37 @@
* size. Once the heap base is established, shared memory buffers
* are sent by providing an offset into the heap and a buffer size.
*/
-void CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
+int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
+ if (heap == NULL) {
+ ALOGE("setHeapBase(): heap is NULL");
+ return -1;
+ }
native_handle_t* nativeHandle = native_handle_create(1, 0);
if (!nativeHandle) {
- ALOGE("setSharedBufferBase(), failed to create native handle");
- return;
+ ALOGE("setHeapBase(), failed to create native handle");
+ return -1;
}
- if (heap == NULL) {
- ALOGE("setSharedBufferBase(): heap is NULL");
- return;
- }
+
+ Mutex::Autolock autoLock(mLock);
+
+ int32_t seqNum = mHeapSeqNum++;
int fd = heap->getHeapID();
nativeHandle->data[0] = fd;
auto hidlHandle = hidl_handle(nativeHandle);
auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
- mHeapBases.add(heap->getBase(), mNextBufferId);
+ mHeapBases.add(seqNum, mNextBufferId);
Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
+ return seqNum;
}
-status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer) {
+void CryptoHal::clearHeapBase(int32_t seqNum) {
+ Mutex::Autolock autoLock(mLock);
+
+ mHeapBases.removeItem(seqNum);
+}
+
+status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) {
ssize_t offset;
size_t size;
@@ -257,11 +269,10 @@
return UNEXPECTED_NULL;
}
- if (mHeapBases.indexOfKey(heap->getBase()) < 0) {
- setHeapBase(heap);
- }
+ // memory must be in the declared heap
+ CHECK(mHeapBases.indexOfKey(seqNum) >= 0);
- buffer->bufferId = mHeapBases.valueFor(heap->getBase());
+ buffer->bufferId = mHeapBases.valueFor(seqNum);
buffer->offset = offset >= 0 ? offset : 0;
buffer->size = size;
return OK;
@@ -269,7 +280,7 @@
ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const sp<IMemory> &source, size_t offset,
+ const ICrypto::SourceBuffer &source, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) {
Mutex::Autolock autoLock(mLock);
@@ -309,11 +320,12 @@
}
auto hSubSamples = hidl_vec<SubSample>(stdSubSamples);
+ int32_t heapSeqNum = source.mHeapSeqNum;
bool secure;
::DestinationBuffer hDestination;
if (destination.mType == kDestinationTypeSharedMemory) {
hDestination.type = BufferType::SHARED_MEMORY;
- status_t status = toSharedBuffer(destination.mSharedMemory,
+ status_t status = toSharedBuffer(destination.mSharedMemory, heapSeqNum,
&hDestination.nonsecureMemory);
if (status != OK) {
return status;
@@ -326,7 +338,7 @@
}
::SharedBuffer hSource;
- status_t status = toSharedBuffer(source, &hSource);
+ status_t status = toSharedBuffer(source.mSharedMemory, heapSeqNum, &hSource);
if (status != OK) {
return status;
}
diff --git a/drm/libmediadrm/ICrypto.cpp b/drm/libmediadrm/ICrypto.cpp
index 92c9548..8506d95 100644
--- a/drm/libmediadrm/ICrypto.cpp
+++ b/drm/libmediadrm/ICrypto.cpp
@@ -36,6 +36,8 @@
DECRYPT,
NOTIFY_RESOLUTION,
SET_MEDIADRM_SESSION,
+ SET_HEAP,
+ UNSET_HEAP,
};
struct BpCrypto : public BpInterface<ICrypto> {
@@ -96,7 +98,7 @@
virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const sp<IMemory> &source, size_t offset,
+ const SourceBuffer &source, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
const DestinationBuffer &destination, AString *errorDetailMsg) {
Parcel data, reply;
@@ -125,7 +127,8 @@
}
data.writeInt32(totalSize);
- data.writeStrongBinder(IInterface::asBinder(source));
+ data.writeStrongBinder(IInterface::asBinder(source.mSharedMemory));
+ data.writeInt32(source.mHeapSeqNum);
data.writeInt32(offset);
data.writeInt32(numSubSamples);
@@ -177,6 +180,30 @@
return reply.readInt32();
}
+ virtual int32_t setHeap(const sp<IMemoryHeap> &heap) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ data.writeStrongBinder(IInterface::asBinder(heap));
+ status_t err = remote()->transact(SET_HEAP, data, &reply);
+ if (err != NO_ERROR) {
+ return -1;
+ }
+ int32_t seqNum;
+ if (reply.readInt32(&seqNum) != NO_ERROR) {
+ return -1;
+ }
+ return seqNum;
+ }
+
+ virtual void unsetHeap(int32_t seqNum) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
+ data.writeInt32(seqNum);
+ remote()->transact(UNSET_HEAP, data, &reply);
+ return;
+ }
+
+
private:
void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
uint32_t size = reply.readInt32();
@@ -295,12 +322,17 @@
data.read(iv, sizeof(iv));
size_t totalSize = data.readInt32();
- sp<IMemory> source =
+
+ SourceBuffer source;
+
+ source.mSharedMemory =
interface_cast<IMemory>(data.readStrongBinder());
- if (source == NULL) {
+ if (source.mSharedMemory == NULL) {
reply->writeInt32(BAD_VALUE);
return OK;
}
+ source.mHeapSeqNum = data.readInt32();
+
int32_t offset = data.readInt32();
int32_t numSubSamples = data.readInt32();
@@ -353,9 +385,9 @@
if (overflow || sumSubsampleSizes != totalSize) {
result = -EINVAL;
- } else if (totalSize > source->size()) {
+ } else if (totalSize > source.mSharedMemory->size()) {
result = -EINVAL;
- } else if ((size_t)offset > source->size() - totalSize) {
+ } else if ((size_t)offset > source.mSharedMemory->size() - totalSize) {
result = -EINVAL;
} else {
result = decrypt(key, iv, mode, pattern, source, offset,
@@ -404,6 +436,23 @@
return OK;
}
+ case SET_HEAP:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+ sp<IMemoryHeap> heap =
+ interface_cast<IMemoryHeap>(data.readStrongBinder());
+ reply->writeInt32(setHeap(heap));
+ return OK;
+ }
+
+ case UNSET_HEAP:
+ {
+ CHECK_INTERFACE(ICrypto, data, reply);
+ int32_t seqNum = data.readInt32();
+ unsetHeap(seqNum);
+ return OK;
+ }
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/include/Crypto.h b/media/libmedia/include/Crypto.h
index ce08f98..b68413d 100644
--- a/media/libmedia/include/Crypto.h
+++ b/media/libmedia/include/Crypto.h
@@ -55,6 +55,9 @@
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
const DestinationBuffer &destination, AString *errorDetailMsg);
+ virtual void setHeap(const sp<IMemoryHeap>&) {}
+ virtual void unsetHeap(const sp<IMemoryHeap>&) {}
+
private:
mutable Mutex mLock;
diff --git a/media/libmedia/include/CryptoHal.h b/media/libmedia/include/CryptoHal.h
index 28ade20..a5d8b43 100644
--- a/media/libmedia/include/CryptoHal.h
+++ b/media/libmedia/include/CryptoHal.h
@@ -55,11 +55,16 @@
virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const sp<IMemory> &source, size_t offset,
+ const ICrypto::SourceBuffer &source, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
const ICrypto::DestinationBuffer &destination,
AString *errorDetailMsg);
+ virtual int32_t setHeap(const sp<IMemoryHeap>& heap) {
+ return setHeapBase(heap);
+ }
+ virtual void unsetHeap(int32_t seqNum) { clearHeapBase(seqNum); }
+
private:
mutable Mutex mLock;
@@ -74,16 +79,18 @@
*/
status_t mInitCheck;
- KeyedVector<void *, uint32_t> mHeapBases;
+ KeyedVector<int32_t, uint32_t> mHeapBases;
uint32_t mNextBufferId;
+ int32_t mHeapSeqNum;
Vector<sp<ICryptoFactory>> makeCryptoFactories();
sp<ICryptoPlugin> makeCryptoPlugin(const sp<ICryptoFactory>& factory,
const uint8_t uuid[16], const void *initData, size_t size);
- void setHeapBase(const sp<IMemoryHeap>& heap);
+ int32_t setHeapBase(const sp<IMemoryHeap>& heap);
+ void clearHeapBase(int32_t seqNum);
- status_t toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer);
+ status_t toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer);
DISALLOW_EVIL_CONSTRUCTORS(CryptoHal);
};
diff --git a/media/libmedia/include/ICrypto.h b/media/libmedia/include/ICrypto.h
index 8990f4b..6d896b8 100644
--- a/media/libmedia/include/ICrypto.h
+++ b/media/libmedia/include/ICrypto.h
@@ -27,6 +27,7 @@
struct AString;
class IMemory;
+class IMemoryHeap;
struct ICrypto : public IInterface {
DECLARE_META_INTERFACE(Crypto);
@@ -47,6 +48,11 @@
virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;
+ struct SourceBuffer {
+ sp<IMemory> mSharedMemory;
+ int32_t mHeapSeqNum;
+ };
+
enum DestinationType {
kDestinationTypeSharedMemory, // non-secure
kDestinationTypeNativeHandle // secure
@@ -60,10 +66,19 @@
virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16],
CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
- const sp<IMemory> &source, size_t offset,
+ const SourceBuffer &source, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
const DestinationBuffer &destination, AString *errorDetailMsg) = 0;
+ /**
+ * Declare the heap that the shared memory source buffers passed
+ * to decrypt will be allocated from. Returns a sequence number
+ * that subsequent decrypt calls can use to refer to the heap,
+ * with -1 indicating failure.
+ */
+ virtual int32_t setHeap(const sp<IMemoryHeap>& heap) = 0;
+ virtual void unsetHeap(int32_t seqNum) = 0;
+
private:
DISALLOW_EVIL_CONSTRUCTORS(ICrypto);
};
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index ecbbd03..40ac986 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -39,6 +39,12 @@
using BufferInfo = ACodecBufferChannel::BufferInfo;
using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator;
+ACodecBufferChannel::~ACodecBufferChannel() {
+ if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) {
+ mCrypto->unsetHeap(mHeapSeqNum);
+ }
+}
+
static BufferInfoIterator findClientBuffer(
const std::shared_ptr<const std::vector<const BufferInfo>> &array,
const sp<MediaCodecBuffer> &buffer) {
@@ -71,7 +77,8 @@
ACodecBufferChannel::ACodecBufferChannel(
const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained)
: mInputBufferFilled(inputBufferFilled),
- mOutputBufferDrained(outputBufferDrained) {
+ mOutputBufferDrained(outputBufferDrained),
+ mHeapSeqNum(-1) {
}
status_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
@@ -122,11 +129,15 @@
destination.mSharedMemory = mDecryptDestination;
}
+ ICrypto::SourceBuffer source;
+ source.mSharedMemory = it->mSharedEncryptedBuffer;
+ source.mHeapSeqNum = mHeapSeqNum;
+
ssize_t result = -1;
if (mCrypto != NULL) {
result = mCrypto->decrypt(key, iv, mode, pattern,
- it->mSharedEncryptedBuffer, it->mClientBuffer->offset(),
- subSamples, numSubSamples, destination, errorDetailMsg);
+ source, it->mClientBuffer->offset(),
+ subSamples, numSubSamples, destination, errorDetailMsg);
} else {
DescrambleInfo descrambleInfo;
descrambleInfo.dstType = destination.mType ==
@@ -254,6 +265,25 @@
}
}
+sp<MemoryDealer> ACodecBufferChannel::makeMemoryDealer(size_t heapSize) {
+ sp<MemoryDealer> dealer;
+ if (mDealer != nullptr && mCrypto != nullptr && mHeapSeqNum >= 0) {
+ mCrypto->unsetHeap(mHeapSeqNum);
+ }
+ dealer = new MemoryDealer(heapSize, "ACodecBufferChannel");
+ if (mCrypto != nullptr) {
+ int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap());
+ if (seqNum >= 0) {
+ mHeapSeqNum = seqNum;
+ ALOGD("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
+ } else {
+ mHeapSeqNum = -1;
+ ALOGD("setHeap failed, setting mHeapSeqNum=-1");
+ }
+ }
+ return dealer;
+}
+
void ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) {
if (hasCryptoOrDescrambler()) {
size_t totalSize = std::accumulate(
@@ -268,8 +298,10 @@
(size_t max, const BufferAndId& elem) {
return std::max(max, align(elem.mBuffer->capacity(), alignment));
});
- mDealer = new MemoryDealer(totalSize + maxSize, "ACodecBufferChannel");
- mDecryptDestination = mDealer->allocate(maxSize);
+ size_t destinationBufferSize = maxSize;
+ size_t heapSize = totalSize + destinationBufferSize;
+ mDealer = makeMemoryDealer(heapSize);
+ mDecryptDestination = mDealer->allocate(destinationBufferSize);
}
std::vector<const BufferInfo> inputBuffers;
for (const BufferAndId &elem : array) {
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index 02468c1..0da2e81 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -60,7 +60,7 @@
ACodecBufferChannel(
const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained);
- virtual ~ACodecBufferChannel() = default;
+ virtual ~ACodecBufferChannel();
// BufferChannelBase interface
virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
@@ -116,6 +116,7 @@
sp<MemoryDealer> mDealer;
sp<IMemory> mDecryptDestination;
+ int32_t mHeapSeqNum;
// These should only be accessed via std::atomic_* functions.
//
@@ -127,6 +128,8 @@
std::shared_ptr<const std::vector<const BufferInfo>> mInputBuffers;
std::shared_ptr<const std::vector<const BufferInfo>> mOutputBuffers;
+ sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
+
bool hasCryptoOrDescrambler() {
return mCrypto != NULL || mDescrambler != NULL;
}