Created
December 6, 2016 19:21
-
-
Save invisiblek/6ac5e56cebe7db75fbfd183c9a814600 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h | |
index 7c50638..090ca51 100644 | |
--- a/include/media/stagefright/MetaData.h | |
+++ b/include/media/stagefright/MetaData.h | |
@@ -283,6 +283,14 @@ public: | |
TYPE_RECT = 'rect', | |
}; | |
+ static const size_t kSharedMemThreshold = 10 * 1024; | |
+ | |
+ enum ParcelAllocationType { | |
+ NULL_ALLOCATION, | |
+ SHARED_ALLOCATION, | |
+ INLINE_ALLOCATION | |
+ }; | |
+ | |
void clear(); | |
bool remove(uint32_t key); | |
diff --git a/media/libstagefright/foundation/MetaData.cpp b/media/libstagefright/foundation/MetaData.cpp | |
index d9d614c..8cc9d22 100644 | |
--- a/media/libstagefright/foundation/MetaData.cpp | |
+++ b/media/libstagefright/foundation/MetaData.cpp | |
@@ -22,6 +22,10 @@ | |
#include <stdlib.h> | |
#include <string.h> | |
+#include <binder/MemoryBase.h> | |
+#include <binder/MemoryHeapBase.h> | |
+#include <binder/IPCThreadState.h> | |
+ | |
#include <media/stagefright/foundation/ADebug.h> | |
#include <media/stagefright/foundation/AString.h> | |
#include <media/stagefright/foundation/hexdump.h> | |
@@ -392,7 +396,7 @@ void MetaData::dumpToLog() const { | |
} | |
status_t MetaData::writeToParcel(Parcel &parcel) { | |
- status_t ret; | |
+ status_t ret, status = OK; | |
size_t numItems = mItems.size(); | |
ret = parcel.writeUint32(uint32_t(numItems)); | |
if (ret) { | |
@@ -426,16 +430,50 @@ status_t MetaData::writeToParcel(Parcel &parcel) { | |
memcpy(blob.data(), data, size); | |
blob.release(); | |
} else { | |
- ret = parcel.writeByteArray(size, (uint8_t*)data); | |
- if (ret) { | |
- return ret; | |
+ if (size < SIZE_MAX && size >= kSharedMemThreshold) { | |
+ sp<MemoryHeapBase> heap = | |
+ new MemoryHeapBase(size, 0, "Metadata::writeToParcel"); | |
+ if (heap == NULL) { | |
+ ALOGE("cannot create HeapBase for shared allocation"); | |
+ status = UNKNOWN_ERROR; | |
+ break; | |
+ } | |
+ sp<IMemory> mem = new MemoryBase(heap, 0, size); | |
+ if (mem == NULL || mem->pointer() == NULL) { | |
+ ALOGE("cannot create MemoryBase for shared allocation"); | |
+ status = UNKNOWN_ERROR; | |
+ break; | |
+ } | |
+ ret = parcel.writeInt32(SHARED_ALLOCATION); | |
+ if (ret) { | |
+ return ret; | |
+ } | |
+ ret = parcel.writeUint32(size); | |
+ if (ret) { | |
+ return ret; | |
+ } | |
+ memcpy(mem->pointer(), data, size); | |
+ ret = parcel.writeStrongBinder(IInterface::asBinder(mem)); | |
+ if (ret) { | |
+ return ret; | |
+ } | |
+ } else { | |
+ ret = parcel.writeInt32(INLINE_ALLOCATION); | |
+ if (ret) { | |
+ return ret; | |
+ } | |
+ ret = parcel.writeByteArray(size, (uint8_t*)data); | |
+ if (ret) { | |
+ return ret; | |
+ } | |
} | |
} | |
} | |
- return ret; | |
+ return status; | |
} | |
status_t MetaData::updateFromParcel(const Parcel &parcel) { | |
+ status_t status = OK; | |
uint32_t numItems; | |
if (parcel.readUint32(&numItems) == OK) { | |
@@ -443,8 +481,10 @@ status_t MetaData::updateFromParcel(const Parcel &parcel) { | |
int32_t key; | |
uint32_t type; | |
uint32_t size; | |
+ int32_t allocationType; | |
status_t ret = parcel.readInt32(&key); | |
ret |= parcel.readUint32(&type); | |
+ ret |= parcel.readInt32(&allocationType); | |
ret |= parcel.readUint32(&size); | |
if (ret != OK) { | |
break; | |
@@ -460,12 +500,27 @@ status_t MetaData::updateFromParcel(const Parcel &parcel) { | |
setData(key, type, blob.data(), size); | |
blob.release(); | |
} else { | |
- // copy data directly from Parcel storage, then advance position | |
- setData(key, type, parcel.readInplace(size), size); | |
+ if (allocationType == SHARED_ALLOCATION) { | |
+ sp<IBinder> binder = parcel.readStrongBinder(); | |
+ sp<IMemory> mem = interface_cast<IMemory>(binder); | |
+ if (mem == NULL || mem->pointer() == NULL) { | |
+ ALOGE("received NULL IMemory for shared allocation"); | |
+ status = UNKNOWN_ERROR; | |
+ break; | |
+ } | |
+ setData(key, type, mem->pointer(), size); | |
+ } else if (allocationType == INLINE_ALLOCATION) { | |
+ // copy data directly from Parcel storage, then advance position | |
+ setData(key, type, parcel.readInplace(size), size); | |
+ } else { | |
+ ALOGE("unknown allocation"); | |
+ status = UNKNOWN_ERROR; | |
+ break; | |
+ } | |
} | |
- } | |
+ } | |
- return OK; | |
+ return status; | |
} | |
ALOGW("no metadata in parcel"); | |
return UNKNOWN_ERROR; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment