DO NOT MERGE: IOMX: work against metadata buffer spoofing am: 9a4768f7bf
am: da3cba194b
Change-Id: I018340e57d237e4d36d68e2cd118336242447b9c
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 595e51f..6e4a4ac 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -99,7 +99,7 @@
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) = 0;
+ buffer_id *buffer, OMX_BOOL crossProcess = OMX_FALSE) = 0;
virtual status_t useGraphicBuffer(
node_id node, OMX_U32 port_index,
@@ -125,7 +125,7 @@
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) = 0;
+ buffer_id *buffer, OMX_BOOL crossProcess = OMX_FALSE) = 0;
virtual status_t freeBuffer(
node_id node, OMX_U32 port_index, buffer_id buffer) = 0;
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 07de536..618faf4 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -245,7 +245,7 @@
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) {
+ buffer_id *buffer, OMX_BOOL /* crossProcess */) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
@@ -415,7 +415,7 @@
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) {
+ buffer_id *buffer, OMX_BOOL /* crossProcess */) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
@@ -754,7 +754,8 @@
interface_cast<IMemory>(data.readStrongBinder());
buffer_id buffer;
- status_t err = useBuffer(node, port_index, params, &buffer);
+ status_t err = useBuffer(
+ node, port_index, params, &buffer, OMX_TRUE /* crossProcess */);
reply->writeInt32(err);
if (err == OK) {
@@ -842,7 +843,10 @@
OMX_U32 port_index = data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
- status_t err = storeMetaDataInBuffers(node, port_index, enable);
+ status_t err =
+ // only control output metadata via Binder
+ port_index != 1 /* kOutputPortIndex */ ? BAD_VALUE :
+ storeMetaDataInBuffers(node, port_index, enable);
reply->writeInt32(err);
return NO_ERROR;
@@ -924,7 +928,7 @@
buffer_id buffer;
status_t err = allocateBufferWithBackup(
- node, port_index, params, &buffer);
+ node, port_index, params, &buffer, OMX_TRUE /* crossProcess */);
reply->writeInt32(err);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 6d9b412..625472f 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -996,7 +996,8 @@
VideoDecoderOutputMetaData *metaData =
reinterpret_cast<VideoDecoderOutputMetaData *>(
oldest->mData->base());
- CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
+ // metaData is only readable if codec is in the same process
+ //CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
oldest - &mBuffers[kPortIndexOutput][0],
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 230c1f7..fa4a509 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -90,7 +90,7 @@
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer);
+ buffer_id *buffer, OMX_BOOL crossProcess);
virtual status_t useGraphicBuffer(
node_id node, OMX_U32 port_index,
@@ -112,7 +112,7 @@
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer);
+ buffer_id *buffer, OMX_BOOL crossProcess);
virtual status_t freeBuffer(
node_id node, OMX_U32 port_index, buffer_id buffer);
@@ -314,8 +314,9 @@
status_t MuxOMX::useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) {
- return getOMX(node)->useBuffer(node, port_index, params, buffer);
+ buffer_id *buffer, OMX_BOOL /* crossProcess */) {
+ return getOMX(node)->useBuffer(
+ node, port_index, params, buffer, OMX_FALSE /* crossProcess */);
}
status_t MuxOMX::useGraphicBuffer(
@@ -353,9 +354,9 @@
status_t MuxOMX::allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) {
+ buffer_id *buffer, OMX_BOOL /* crossProcess */) {
return getOMX(node)->allocateBufferWithBackup(
- node, port_index, params, buffer);
+ node, port_index, params, buffer, OMX_FALSE /* crossProcess */);
}
status_t MuxOMX::freeBuffer(
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 2da5c6c..829c38b 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -81,7 +81,7 @@
virtual status_t useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer);
+ buffer_id *buffer, OMX_BOOL crossProcess);
virtual status_t useGraphicBuffer(
node_id node, OMX_U32 port_index,
@@ -103,7 +103,7 @@
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer);
+ buffer_id *buffer, OMX_BOOL crossProcess);
virtual status_t freeBuffer(
node_id node, OMX_U32 port_index, buffer_id buffer);
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index ad50faf..616dda1 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -21,6 +21,7 @@
#include "OMX.h"
#include <utils/RefBase.h>
+#include <utils/SortedVector.h>
#include <utils/threads.h>
namespace android {
@@ -68,7 +69,7 @@
status_t useBuffer(
OMX_U32 portIndex, const sp<IMemory> ¶ms,
- OMX::buffer_id *buffer);
+ OMX::buffer_id *buffer, OMX_BOOL crossProcess);
status_t useGraphicBuffer(
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
@@ -89,7 +90,7 @@
status_t allocateBufferWithBackup(
OMX_U32 portIndex, const sp<IMemory> ¶ms,
- OMX::buffer_id *buffer);
+ OMX::buffer_id *buffer, OMX_BOOL crossProcess);
status_t freeBuffer(OMX_U32 portIndex, OMX::buffer_id buffer);
@@ -133,6 +134,9 @@
OMX_HANDLETYPE mHandle;
sp<IOMXObserver> mObserver;
bool mDying;
+ bool mSailed; // configuration is set (no more meta-mode changes)
+ bool mQueriedProhibitedExtensions;
+ SortedVector<OMX_INDEXTYPE> mProhibitedExtensions;
bool mIsSecure;
// Lock only covers mGraphicBufferSource. We can't always use mLock
@@ -153,6 +157,9 @@
KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;
KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID;
+ // metadata mode tracking
+ bool mUsingMetadata[2];
+
// For debug support
char *mName;
int DEBUG;
@@ -177,6 +184,8 @@
OMX::buffer_id findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader);
void invalidateBufferID(OMX::buffer_id buffer);
+ bool isProhibitedIndex_l(OMX_INDEXTYPE index);
+
status_t useGraphicBuffer2_l(
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
OMX::buffer_id *buffer);
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index a943646..01dfc8a 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -361,9 +361,9 @@
status_t OMX::useBuffer(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) {
+ buffer_id *buffer, OMX_BOOL crossProcess) {
return findInstance(node)->useBuffer(
- port_index, params, buffer);
+ port_index, params, buffer, crossProcess);
}
status_t OMX::useGraphicBuffer(
@@ -400,9 +400,9 @@
status_t OMX::allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer) {
+ buffer_id *buffer, OMX_BOOL crossProcess) {
return findInstance(node)->allocateBufferWithBackup(
- port_index, params, buffer);
+ port_index, params, buffer, crossProcess);
}
status_t OMX::freeBuffer(node_id node, OMX_U32 port_index, buffer_id buffer) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 8f320af..58a1a25 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -100,26 +100,34 @@
namespace android {
struct BufferMeta {
- BufferMeta(const sp<IMemory> &mem, OMX_U32 portIndex, bool is_backup = false)
+ BufferMeta(
+ const sp<IMemory> &mem, OMX_U32 portIndex, bool copyToOmx,
+ bool copyFromOmx, OMX_U8 *backup)
: mMem(mem),
- mIsBackup(is_backup),
- mPortIndex(portIndex) {
+ mCopyFromOmx(copyFromOmx),
+ mCopyToOmx(copyToOmx),
+ mPortIndex(portIndex),
+ mBackup(backup) {
}
BufferMeta(size_t size, OMX_U32 portIndex)
: mSize(size),
- mIsBackup(false),
- mPortIndex(portIndex) {
+ mCopyFromOmx(false),
+ mCopyToOmx(false),
+ mPortIndex(portIndex),
+ mBackup(NULL) {
}
BufferMeta(const sp<GraphicBuffer> &graphicBuffer, OMX_U32 portIndex)
: mGraphicBuffer(graphicBuffer),
- mIsBackup(false),
- mPortIndex(portIndex) {
+ mCopyFromOmx(false),
+ mCopyToOmx(false),
+ mPortIndex(portIndex),
+ mBackup(NULL) {
}
void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) {
- if (!mIsBackup) {
+ if (!mCopyFromOmx) {
return;
}
@@ -129,7 +137,7 @@
}
void CopyToOMX(const OMX_BUFFERHEADERTYPE *header) {
- if (!mIsBackup) {
+ if (!mCopyToOmx) {
return;
}
@@ -146,12 +154,18 @@
return mPortIndex;
}
+ ~BufferMeta() {
+ delete[] mBackup;
+ }
+
private:
sp<GraphicBuffer> mGraphicBuffer;
sp<IMemory> mMem;
size_t mSize;
- bool mIsBackup;
+ bool mCopyFromOmx;
+ bool mCopyToOmx;
OMX_U32 mPortIndex;
+ OMX_U8 *mBackup;
BufferMeta(const BufferMeta &);
BufferMeta &operator=(const BufferMeta &);
@@ -178,6 +192,8 @@
mHandle(NULL),
mObserver(observer),
mDying(false),
+ mSailed(false),
+ mQueriedProhibitedExtensions(false),
mBufferIDCount(0)
{
mName = ADebug::GetDebugName(name);
@@ -188,6 +204,8 @@
mNumPortBuffers[1] = 0;
mDebugLevelBumpPendingBuffers[0] = 0;
mDebugLevelBumpPendingBuffers[1] = 0;
+ mUsingMetadata[0] = false;
+ mUsingMetadata[1] = false;
mIsSecure = AString(name).endsWith(".secure");
}
@@ -345,7 +363,12 @@
status_t OMXNodeInstance::sendCommand(
OMX_COMMANDTYPE cmd, OMX_S32 param) {
- const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
+ if (cmd == OMX_CommandStateSet && param != OMX_StateIdle) {
+ // We do not support returning from unloaded state, so there are no configurations past
+ // first StateSet command. However, OMXCodec supports meta configuration past Stateset:Idle.
+ mSailed = true;
+ }
+ const sp<GraphicBufferSource> bufferSource(getGraphicBufferSource());
if (bufferSource != NULL && cmd == OMX_CommandStateSet) {
if (param == OMX_StateIdle) {
// Initiating transition from Executing -> Idle
@@ -378,10 +401,55 @@
return StatusFromOMXError(err);
}
+bool OMXNodeInstance::isProhibitedIndex_l(OMX_INDEXTYPE index) {
+ // these extensions can only be used from OMXNodeInstance, not by clients directly.
+ static const char *restricted_extensions[] = {
+ "OMX.google.android.index.storeMetaDataInBuffers",
+ "OMX.google.android.index.prepareForAdaptivePlayback",
+ "OMX.google.android.index.configureVideoTunnelMode",
+ "OMX.google.android.index.useAndroidNativeBuffer2",
+ "OMX.google.android.index.useAndroidNativeBuffer",
+ "OMX.google.android.index.enableAndroidNativeBuffers",
+ "OMX.google.android.index.getAndroidNativeBufferUsage",
+ };
+
+ if ((index > OMX_IndexComponentStartUnused && index <= OMX_IndexParamStandardComponentRole)
+ || (index > OMX_IndexPortStartUnused && index <= OMX_IndexParamCompBufferSupplier)
+ || (index > OMX_IndexAudioStartUnused && index <= OMX_IndexConfigAudioChannelVolume)
+ || (index > OMX_IndexVideoStartUnused && index <= OMX_IndexConfigVideoNalSize)
+ || (index > OMX_IndexCommonStartUnused
+ && index <= OMX_IndexConfigCommonTransitionEffect)
+ || (index > (OMX_INDEXTYPE)OMX_IndexExtAudioStartUnused
+ && index <= (OMX_INDEXTYPE)OMX_IndexParamAudioAndroidEac3)
+ || (index > (OMX_INDEXTYPE)OMX_IndexExtVideoStartUnused
+ && index <= (OMX_INDEXTYPE)OMX_IndexParamSliceSegments)
+ || (index > (OMX_INDEXTYPE)OMX_IndexExtOtherStartUnused
+ && index <= (OMX_INDEXTYPE)OMX_IndexConfigAutoFramerateConversion)) {
+ return false;
+ }
+
+ if (!mQueriedProhibitedExtensions) {
+ for (size_t i = 0; i < NELEM(restricted_extensions); ++i) {
+ OMX_INDEXTYPE ext;
+ if (OMX_GetExtensionIndex(mHandle, (OMX_STRING)restricted_extensions[i], &ext) == OMX_ErrorNone) {
+ mProhibitedExtensions.add(ext);
+ }
+ }
+ mQueriedProhibitedExtensions = true;
+ }
+
+ return mProhibitedExtensions.indexOf(index) >= 0;
+}
+
status_t OMXNodeInstance::getParameter(
OMX_INDEXTYPE index, void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
+ if (isProhibitedIndex_l(index)) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return BAD_INDEX;
+ }
+
OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
// some errors are expected for getParameter
@@ -397,6 +465,11 @@
OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
CLOG_CONFIG(setParameter, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
+ if (isProhibitedIndex_l(index)) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return BAD_INDEX;
+ }
+
OMX_ERRORTYPE err = OMX_SetParameter(
mHandle, index, const_cast<void *>(params));
CLOG_IF_ERROR(setParameter, err, "%s(%#x)", asString(extIndex), index);
@@ -407,6 +480,11 @@
OMX_INDEXTYPE index, void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
+ if (isProhibitedIndex_l(index)) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return BAD_INDEX;
+ }
+
OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
// some errors are expected for getConfig
@@ -422,6 +500,11 @@
OMX_INDEXEXTTYPE extIndex = (OMX_INDEXEXTTYPE)index;
CLOG_CONFIG(setConfig, "%s(%#x), %zu@%p)", asString(extIndex), index, size, params);
+ if (isProhibitedIndex_l(index)) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return BAD_INDEX;
+ }
+
OMX_ERRORTYPE err = OMX_SetConfig(
mHandle, index, const_cast<void *>(params));
CLOG_IF_ERROR(setConfig, err, "%s(%#x)", asString(extIndex), index);
@@ -507,6 +590,15 @@
OMX_BOOL enable,
OMX_BOOL useGraphicBuffer,
OMX_BOOL *usingGraphicBufferInMetadata) {
+ if (mSailed) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return INVALID_OPERATION;
+ }
+ if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
+ android_errorWriteLog(0x534e4554, "26324358");
+ return BAD_VALUE;
+ }
+
OMX_INDEXTYPE index;
OMX_STRING name = const_cast<OMX_STRING>(
"OMX.google.android.index.storeMetaDataInBuffers");
@@ -541,6 +633,9 @@
// don't log loud error if component does not support metadata mode on the output
if (err != OMX_ErrorNone) {
*usingGraphicBufferInMetadata = OMX_FALSE;
+ if (enable) {
+ mUsingMetadata[portIndex] = false;
+ }
if (err == OMX_ErrorUnsupportedIndex && portIndex == kPortIndexOutput) {
CLOGW("component does not support metadata mode; using fallback");
} else if (xerr != OMX_ErrorNone) {
@@ -549,6 +644,8 @@
CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d GB=%d", name, index,
portString(portIndex), portIndex, enable, useGraphicBuffer);
}
+ } else {
+ mUsingMetadata[portIndex] = enable;
}
return StatusFromOMXError(err);
}
@@ -557,6 +654,10 @@
OMX_U32 portIndex, OMX_BOOL enable, OMX_U32 maxFrameWidth,
OMX_U32 maxFrameHeight) {
Mutex::Autolock autolock(mLock);
+ if (mSailed) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return INVALID_OPERATION;
+ }
CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u",
portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight);
@@ -587,6 +688,10 @@
OMX_U32 portIndex, OMX_BOOL tunneled, OMX_U32 audioHwSync,
native_handle_t **sidebandHandle) {
Mutex::Autolock autolock(mLock);
+ if (mSailed) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return INVALID_OPERATION;
+ }
CLOG_CONFIG(configureVideoTunnelMode, "%s:%u tun=%d sync=%u",
portString(portIndex), portIndex, tunneled, audioHwSync);
@@ -627,16 +732,39 @@
status_t OMXNodeInstance::useBuffer(
OMX_U32 portIndex, const sp<IMemory> ¶ms,
- OMX::buffer_id *buffer) {
+ OMX::buffer_id *buffer, OMX_BOOL crossProcess) {
Mutex::Autolock autoLock(mLock);
+ if (portIndex >= NELEM(mUsingMetadata)) {
+ return BAD_VALUE;
+ }
+ // We do not support metadata mode changes past buffer allocation
+ mSailed = true;
- BufferMeta *buffer_meta = new BufferMeta(params, portIndex);
+ // metadata buffers are not connected cross process
+ BufferMeta *buffer_meta;
+ bool isMeta = mUsingMetadata[portIndex];
+ bool useBackup = crossProcess && isMeta; // use a backup buffer instead of the actual buffer
+ OMX_U8 *data = static_cast<OMX_U8 *>(params->pointer());
+ // allocate backup buffer
+ if (useBackup) {
+ data = new (std::nothrow) OMX_U8[params->size()];
+ if (data == NULL) {
+ return NO_MEMORY;
+ }
+ memset(data, 0, params->size());
+
+ buffer_meta = new BufferMeta(
+ params, portIndex, false /* copyToOmx */, false /* copyFromOmx */, data);
+ } else {
+ buffer_meta = new BufferMeta(
+ params, portIndex, false /* copyFromOmx */, false /* copyToOmx */, NULL);
+ }
OMX_BUFFERHEADERTYPE *header;
OMX_ERRORTYPE err = OMX_UseBuffer(
mHandle, &header, portIndex, buffer_meta,
- params->size(), static_cast<OMX_U8 *>(params->pointer()));
+ params->size(), data);
if (err != OMX_ErrorNone) {
CLOG_ERROR(useBuffer, err, SIMPLE_BUFFER(portIndex, params->size(), params->pointer()));
@@ -802,7 +930,16 @@
Mutex::Autolock autolock(mLock);
status_t err;
- const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource();
+ // only allow graphic source on input port, when there are no allocated buffers yet
+ if (portIndex != kPortIndexInput) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return BAD_VALUE;
+ } else if (mNumPortBuffers[portIndex] > 0) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return INVALID_OPERATION;
+ }
+
+ const sp<GraphicBufferSource> surfaceCheck = getGraphicBufferSource();
if (surfaceCheck != NULL) {
return ALREADY_EXISTS;
}
@@ -866,6 +1003,8 @@
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
void **buffer_data) {
Mutex::Autolock autoLock(mLock);
+ // We do not support metadata mode changes past buffer allocation
+ mSailed = true;
BufferMeta *buffer_meta = new BufferMeta(size, portIndex);
@@ -902,10 +1041,23 @@
status_t OMXNodeInstance::allocateBufferWithBackup(
OMX_U32 portIndex, const sp<IMemory> ¶ms,
- OMX::buffer_id *buffer) {
+ OMX::buffer_id *buffer, OMX_BOOL crossProcess) {
Mutex::Autolock autoLock(mLock);
+ if (portIndex >= NELEM(mUsingMetadata)) {
+ return BAD_VALUE;
+ }
+ // We do not support metadata mode changes past buffer allocation
+ mSailed = true;
- BufferMeta *buffer_meta = new BufferMeta(params, portIndex, true);
+ // metadata buffers are not connected cross process
+ bool isMeta = mUsingMetadata[portIndex];
+ bool copy = !(crossProcess && isMeta);
+
+ BufferMeta *buffer_meta = new BufferMeta(
+ params, portIndex,
+ (portIndex == kPortIndexInput) && copy /* copyToOmx */,
+ (portIndex == kPortIndexOutput) && copy /* copyFromOmx */,
+ NULL /* data */);
OMX_BUFFERHEADERTYPE *header;
@@ -924,6 +1076,7 @@
}
CHECK_EQ(header->pAppPrivate, buffer_meta);
+ memset(header->pBuffer, 0, header->nAllocLen);
*buffer = makeBufferID(header);
@@ -995,13 +1148,17 @@
OMX_U32 flags, OMX_TICKS timestamp) {
Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
- if (header == NULL) {
- return BAD_VALUE;
+ // no emptybuffer if using input surface
+ if (getGraphicBufferSource() != NULL) {
+ android_errorWriteLog(0x534e4554, "29422020");
+ return INVALID_OPERATION;
}
+
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
// rangeLength and rangeOffset must be a subset of the allocated data in the buffer.
// corner case: we permit rangeOffset == end-of-buffer with rangeLength == 0.
- if (rangeOffset > header->nAllocLen
+ if (header == NULL
+ || rangeOffset > header->nAllocLen
|| rangeLength > header->nAllocLen - rangeOffset) {
return BAD_VALUE;
}