stagefright: enable native handles for secure buffers
- rename IOMX::allocateBuffer to allocateSecureBuffer as ACodec
only uses allocateBuffer for secure compressed buffers.
- add argument to return native_handle if component supports it.
- rename IOMX::enableGraphicBuffers to enableNativeBuffers.
- add argument to select graphic vs. native handle mode
- request native handles for secure input buffers, but allow
fallback
Bug: 26782004
Change-Id: Ide9d07f54d2e7e3e6a82dbca011f4db9a5630950
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 27ad694..d6db67a 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -98,8 +98,8 @@
node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0;
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) = 0;
virtual status_t getGraphicBufferUsage(
node_id node, OMX_U32 port_index, OMX_U32* usage) = 0;
@@ -137,13 +137,14 @@
virtual status_t signalEndOfInputStream(node_id node) = 0;
- // This API clearly only makes sense if the caller lives in the
- // same process as the callee, i.e. is the media_server, as the
- // returned "buffer_data" pointer is just that, a pointer into local
- // address space.
- virtual status_t allocateBuffer(
+ // Allocate an opaque buffer as a native handle. If component supports returning native
+ // handles, those are returned in *native_handle. Otherwise, the allocated buffer is
+ // returned in *buffer_data. This clearly only makes sense if the caller lives in the
+ // same process as the callee, i.e. is the media_server, as the returned "buffer_data"
+ // pointer is just that, a pointer into local address space.
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) = 0;
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) = 0;
// Allocate an OMX buffer of size |allotedSize|. Use |params| as the backup buffer, which
// may be larger.
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 349db64..cc5b486 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -26,6 +26,7 @@
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/FrameRenderTracker.h>
#include <media/stagefright/SkipCutBuffer.h>
+#include <utils/NativeHandle.h>
#include <OMX_Audio.h>
#define TRACK_BUFFER_TIMING 0
@@ -72,6 +73,7 @@
size_t countBuffers();
IOMX::buffer_id bufferIDAt(size_t index) const;
sp<ABuffer> bufferAt(size_t index) const;
+ sp<NativeHandle> handleAt(size_t index) const;
sp<RefBase> memRefAt(size_t index) const;
private:
@@ -79,10 +81,13 @@
Vector<IOMX::buffer_id> mBufferIDs;
Vector<sp<ABuffer> > mBuffers;
+ Vector<sp<NativeHandle> > mHandles;
Vector<sp<RefBase> > mMemRefs;
PortDescription();
- void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer, const sp<RefBase> &memRef);
+ void addBuffer(
+ IOMX::buffer_id id, const sp<ABuffer> &buffer,
+ const sp<NativeHandle> &handle, const sp<RefBase> &memRef);
DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
};
@@ -186,6 +191,7 @@
sp<ABuffer> mData;
sp<RefBase> mMemRef;
sp<GraphicBuffer> mGraphicBuffer;
+ sp<NativeHandle> mNativeHandle;
int mFenceFd;
FrameRenderTracker::Info *mRenderInfo;
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
index 01b744b..cbf9839 100644
--- a/include/media/stagefright/CodecBase.h
+++ b/include/media/stagefright/CodecBase.h
@@ -23,6 +23,7 @@
#include <media/MediaCodecInfo.h>
#include <media/stagefright/foundation/AHandler.h>
+#include <utils/NativeHandle.h>
namespace android {
@@ -77,6 +78,7 @@
virtual size_t countBuffers() = 0;
virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0;
virtual sp<ABuffer> bufferAt(size_t index) const = 0;
+ virtual sp<NativeHandle> handleAt(size_t index) { return NULL; };
virtual sp<RefBase> memRefAt(size_t index) const { return NULL; }
protected:
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index ea708e3..2bb1291 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -254,6 +254,7 @@
struct BufferInfo {
uint32_t mBufferID;
sp<ABuffer> mData;
+ sp<NativeHandle> mNativeHandle;
sp<RefBase> mMemRef;
sp<ABuffer> mEncryptedData;
sp<IMemory> mSharedEncryptedBuffer;
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 550b506..9a7dff6 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -37,7 +37,7 @@
GET_CONFIG,
SET_CONFIG,
GET_STATE,
- ENABLE_GRAPHIC_BUFFERS,
+ ENABLE_NATIVE_BUFFERS,
USE_BUFFER,
USE_GRAPHIC_BUFFER,
CREATE_INPUT_SURFACE,
@@ -46,7 +46,7 @@
SIGNAL_END_OF_INPUT_STREAM,
STORE_META_DATA_IN_BUFFERS,
PREPARE_FOR_ADAPTIVE_PLAYBACK,
- ALLOC_BUFFER,
+ ALLOC_SECURE_BUFFER,
ALLOC_BUFFER_WITH_BACKUP,
FREE_BUFFER,
FILL_BUFFER,
@@ -217,14 +217,15 @@
return reply.readInt32();
}
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
data.writeInt32(port_index);
+ data.writeInt32((uint32_t)graphic);
data.writeInt32((uint32_t)enable);
- remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply);
+ remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
status_t err = reply.readInt32();
return err;
@@ -453,26 +454,31 @@
}
- virtual status_t allocateBuffer(
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) {
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.writeInt64(size);
- remote()->transact(ALLOC_BUFFER, data, &reply);
+ remote()->transact(ALLOC_SECURE_BUFFER, data, &reply);
status_t err = reply.readInt32();
if (err != OK) {
*buffer = 0;
-
+ *buffer_data = NULL;
+ *native_handle = NULL;
return err;
}
*buffer = (buffer_id)reply.readInt32();
*buffer_data = (void *)reply.readInt64();
-
+ if (*buffer_data == NULL) {
+ *native_handle = reply.readNativeHandle();
+ } else {
+ *native_handle = NULL;
+ }
return err;
}
@@ -754,15 +760,16 @@
return NO_ERROR;
}
- case ENABLE_GRAPHIC_BUFFERS:
+ case ENABLE_NATIVE_BUFFERS:
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
+ OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
- status_t err = enableGraphicBuffers(node, port_index, enable);
+ status_t err = enableNativeBuffers(node, port_index, graphic, enable);
reply->writeInt32(err);
return NO_ERROR;
@@ -965,7 +972,7 @@
OMX_BOOL tunneled = (OMX_BOOL)data.readInt32();
OMX_U32 audio_hw_sync = data.readInt32();
- native_handle_t *sideband_handle;
+ native_handle_t *sideband_handle = NULL;
status_t err = configureVideoTunnelMode(
node, port_index, tunneled, audio_hw_sync, &sideband_handle);
reply->writeInt32(err);
@@ -974,7 +981,7 @@
return NO_ERROR;
}
- case ALLOC_BUFFER:
+ case ALLOC_SECURE_BUFFER:
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
@@ -989,14 +996,18 @@
size_t size = data.readInt64();
buffer_id buffer;
- void *buffer_data;
- status_t err = allocateBuffer(
- node, port_index, size, &buffer, &buffer_data);
+ void *buffer_data = NULL;
+ native_handle_t *native_handle = NULL;
+ status_t err = allocateSecureBuffer(
+ node, port_index, size, &buffer, &buffer_data, &native_handle);
reply->writeInt32(err);
if (err == OK) {
reply->writeInt32((int32_t)buffer);
reply->writeInt64((uintptr_t)buffer_data);
+ if (buffer_data == NULL) {
+ reply->writeNativeHandle(native_handle);
+ }
}
return NO_ERROR;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 5f13ebc..0dc5d4c 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -828,6 +828,7 @@
info.mStatus = BufferInfo::OWNED_BY_US;
info.mFenceFd = -1;
info.mRenderInfo = NULL;
+ info.mNativeHandle = NULL;
uint32_t requiresAllocateBufferBit =
(portIndex == kPortIndexInput)
@@ -837,12 +838,22 @@
if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
mem.clear();
- void *ptr;
- err = mOMX->allocateBuffer(
+ void *ptr = NULL;
+ native_handle_t *native_handle = NULL;
+ err = mOMX->allocateSecureBuffer(
mNode, portIndex, bufSize, &info.mBufferID,
- &ptr);
+ &ptr, &native_handle);
- info.mData = new ABuffer(ptr, bufSize);
+ // TRICKY: this representation is unorthodox, but ACodec requires
+ // an ABuffer with a proper size to validate range offsets and lengths.
+ // Since mData is never referenced for secure input, it is used to store
+ // either the pointer to the secure buffer, or the opaque handle as on
+ // some devices ptr is actually an opaque handle, not a pointer.
+
+ // TRICKY2: use native handle as the base of the ABuffer if received one,
+ // because Widevine source only receives these base addresses.
+ info.mData = new ABuffer(ptr != NULL ? ptr : (void *)native_handle, bufSize);
+ info.mNativeHandle = NativeHandle::create(native_handle, true /* ownsHandle */);
} else if (mQuirks & requiresAllocateBufferBit) {
err = mOMX->allocateBufferWithBackup(
mNode, portIndex, mem, &info.mBufferID, allottedSize);
@@ -876,7 +887,7 @@
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
const BufferInfo &info = mBuffers[portIndex][i];
- desc->addBuffer(info.mBufferID, info.mData, info.mMemRef);
+ desc->addBuffer(info.mBufferID, info.mData, info.mNativeHandle, info.mMemRef);
}
notify->setObject("portDesc", desc);
@@ -1774,6 +1785,14 @@
mFlags |= kFlagIsGrallocUsageProtected;
mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
}
+
+ if (mFlags & kFlagIsSecure) {
+ // use native_handles for secure input buffers
+ err = mOMX->enableNativeBuffers(
+ mNode, kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
+ ALOGI_IF(err != OK, "falling back to non-native_handles");
+ err = OK; // ignore error for now
+ }
}
if (haveNativeWindow) {
sp<ANativeWindow> nativeWindow =
@@ -1985,7 +2004,8 @@
inputFormat->setInt32("adaptive-playback", false);
}
if (err == OK) {
- err = mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
+ err = mOMX->enableNativeBuffers(
+ mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
}
if (mFlags & kFlagIsGrallocUsageProtected) {
// fallback is not supported for protected playback
@@ -3879,10 +3899,10 @@
status_t ACodec::initNativeWindow() {
if (mNativeWindow != NULL) {
- return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
+ return mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
}
- mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
+ mOMX->enableNativeBuffers(mNode, kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
return OK;
}
@@ -4646,9 +4666,11 @@
}
void ACodec::PortDescription::addBuffer(
- IOMX::buffer_id id, const sp<ABuffer> &buffer, const sp<RefBase> &memRef) {
+ IOMX::buffer_id id, const sp<ABuffer> &buffer,
+ const sp<NativeHandle> &handle, const sp<RefBase> &memRef) {
mBufferIDs.push_back(id);
mBuffers.push_back(buffer);
+ mHandles.push_back(handle);
mMemRefs.push_back(memRef);
}
@@ -4664,6 +4686,10 @@
return mBuffers.itemAt(index);
}
+sp<NativeHandle> ACodec::PortDescription::handleAt(size_t index) const {
+ return mHandles.itemAt(index);
+}
+
sp<RefBase> ACodec::PortDescription::memRefAt(size_t index) const {
return mMemRefs.itemAt(index);
}
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index ce67d78..1be9a3e 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1357,6 +1357,7 @@
info.mBufferID = portDesc->bufferIDAt(i);
info.mOwnedByClient = false;
info.mData = portDesc->bufferAt(i);
+ info.mNativeHandle = portDesc->handleAt(i);
info.mMemRef = portDesc->memRefAt(i);
if (portIndex == kPortIndexInput && mCrypto != NULL) {
@@ -2493,6 +2494,9 @@
AString *errorDetailMsg;
CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
+ // TODO: use different decrypt based on native handle or not
+ // use native handle if we have it; otherwise, use opaque handle
+ void *dst_pointer = (void *)info->mNativeHandle.get() ? : info->mData->base();
ssize_t result = mCrypto->decrypt(
(mFlags & kFlagIsSecure) != 0,
key,
@@ -2503,7 +2507,7 @@
offset,
subSamples,
numSubSamples,
- info->mData->base(),
+ dst_pointer,
errorDetailMsg);
if (result < 0) {
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index e69890d..50f235e 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -82,8 +82,8 @@
node_id node, OMX_U32 portIndex, OMX_BOOL tunneled,
OMX_U32 audioHwSync, native_handle_t **sidebandHandle);
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable);
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
virtual status_t getGraphicBufferUsage(
node_id node, OMX_U32 port_index, OMX_U32* usage);
@@ -114,9 +114,9 @@
virtual status_t signalEndOfInputStream(node_id node);
- virtual status_t allocateBuffer(
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data);
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle);
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
@@ -310,9 +310,9 @@
node, portIndex, enable, audioHwSync, sidebandHandle);
}
-status_t MuxOMX::enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) {
- return getOMX(node)->enableGraphicBuffers(node, port_index, enable);
+status_t MuxOMX::enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
+ return getOMX(node)->enableNativeBuffers(node, port_index, graphic, enable);
}
status_t MuxOMX::getGraphicBufferUsage(
@@ -366,11 +366,11 @@
return getOMX(node)->signalEndOfInputStream(node);
}
-status_t MuxOMX::allocateBuffer(
+status_t MuxOMX::allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) {
- return getOMX(node)->allocateBuffer(
- node, port_index, size, buffer, buffer_data);
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
+ return getOMX(node)->allocateSecureBuffer(
+ node, port_index, size, buffer, buffer_data, native_handle);
}
status_t MuxOMX::allocateBufferWithBackup(
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 9f2e5e7..4c27360 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -62,8 +62,8 @@
virtual status_t getState(
node_id node, OMX_STATETYPE* state);
- virtual status_t enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable);
+ virtual status_t enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable);
virtual status_t getGraphicBufferUsage(
node_id node, OMX_U32 port_index, OMX_U32* usage);
@@ -107,9 +107,9 @@
virtual status_t signalEndOfInputStream(node_id node);
- virtual status_t allocateBuffer(
+ virtual status_t allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data);
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle);
virtual status_t allocateBufferWithBackup(
node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms,
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index e5fb45b..732894c 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -54,7 +54,7 @@
status_t getState(OMX_STATETYPE* state);
- status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
+ status_t enableNativeBuffers(OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable);
status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
@@ -95,9 +95,9 @@
status_t signalEndOfInputStream();
- status_t allocateBuffer(
+ status_t allocateSecureBuffer(
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
- void **buffer_data);
+ void **buffer_data, native_handle_t **native_handle);
status_t allocateBufferWithBackup(
OMX_U32 portIndex, const sp<IMemory> ¶ms,
@@ -165,7 +165,15 @@
uint32_t mBufferIDCount;
KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;
KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID;
+
+ // metadata and secure buffer type tracking
MetadataBufferType mMetadataType[2];
+ enum SecureBufferType {
+ kSecureBufferTypeUnknown,
+ kSecureBufferTypeOpaque,
+ kSecureBufferTypeNativeHandle,
+ };
+ SecureBufferType mSecureBufferType[2];
// For debug support
char *mName;
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index b3625b4..a20028b 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -380,15 +380,15 @@
state);
}
-status_t OMX::enableGraphicBuffers(
- node_id node, OMX_U32 port_index, OMX_BOOL enable) {
+status_t OMX::enableNativeBuffers(
+ node_id node, OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
OMXNodeInstance *instance = findInstance(node);
if (instance == NULL) {
return NAME_NOT_FOUND;
}
- return instance->enableGraphicBuffers(port_index, enable);
+ return instance->enableNativeBuffers(port_index, graphic, enable);
}
status_t OMX::getGraphicBufferUsage(
@@ -521,17 +521,17 @@
return instance->signalEndOfInputStream();
}
-status_t OMX::allocateBuffer(
+status_t OMX::allocateSecureBuffer(
node_id node, OMX_U32 port_index, size_t size,
- buffer_id *buffer, void **buffer_data) {
+ buffer_id *buffer, void **buffer_data, native_handle_t **native_handle) {
OMXNodeInstance *instance = findInstance(node);
if (instance == NULL) {
return NAME_NOT_FOUND;
}
- return instance->allocateBuffer(
- port_index, size, buffer, buffer_data);
+ return instance->allocateSecureBuffer(
+ port_index, size, buffer, buffer_data, native_handle);
}
status_t OMX::allocateBufferWithBackup(
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 9ae238a..3e83f24 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -203,6 +203,8 @@
mDebugLevelBumpPendingBuffers[1] = 0;
mMetadataType[0] = kMetadataBufferTypeInvalid;
mMetadataType[1] = kMetadataBufferTypeInvalid;
+ mSecureBufferType[0] = kSecureBufferTypeUnknown;
+ mSecureBufferType[1] = kSecureBufferTypeUnknown;
mIsSecure = AString(name).endsWith(".secure");
}
@@ -453,12 +455,14 @@
return StatusFromOMXError(err);
}
-status_t OMXNodeInstance::enableGraphicBuffers(
- OMX_U32 portIndex, OMX_BOOL enable) {
+status_t OMXNodeInstance::enableNativeBuffers(
+ OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable) {
Mutex::Autolock autoLock(mLock);
- CLOG_CONFIG(enableGraphicBuffers, "%s:%u, %d", portString(portIndex), portIndex, enable);
+ CLOG_CONFIG(enableNativeBuffers, "%s:%u%s, %d", portString(portIndex), portIndex,
+ graphic ? ", graphic" : "", enable);
OMX_STRING name = const_cast<OMX_STRING>(
- "OMX.google.android.index.enableAndroidNativeBuffers");
+ graphic ? "OMX.google.android.index.enableAndroidNativeBuffers"
+ : "OMX.google.android.index.allocateNativeHandle");
OMX_INDEXTYPE index;
OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);
@@ -476,6 +480,14 @@
err = OMX_SetParameter(mHandle, index, ¶ms);
CLOG_IF_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d", name, index,
portString(portIndex), portIndex, enable);
+ if (!graphic) {
+ if (err == OK) {
+ mSecureBufferType[portIndex] =
+ enable ? kSecureBufferTypeNativeHandle : kSecureBufferTypeOpaque;
+ } else if (mSecureBufferType[portIndex] == kSecureBufferTypeUnknown) {
+ mSecureBufferType[portIndex] = kSecureBufferTypeOpaque;
+ }
+ }
return StatusFromOMXError(err);
}
@@ -996,10 +1008,10 @@
return bufferSource->signalEndOfInputStream();
}
-status_t OMXNodeInstance::allocateBuffer(
+status_t OMXNodeInstance::allocateSecureBuffer(
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
- void **buffer_data) {
- if (buffer == NULL || buffer_data == NULL) {
+ void **buffer_data, native_handle_t **native_handle) {
+ if (buffer == NULL || buffer_data == NULL || native_handle == NULL) {
ALOGE("b/25884056");
return BAD_VALUE;
}
@@ -1026,7 +1038,13 @@
CHECK_EQ(header->pAppPrivate, buffer_meta);
*buffer = makeBufferID(header);
- *buffer_data = header->pBuffer;
+ if (mSecureBufferType[portIndex] == kSecureBufferTypeNativeHandle) {
+ *buffer_data = NULL;
+ *native_handle = (native_handle_t *)header->pBuffer;
+ } else {
+ *buffer_data = header->pBuffer;
+ *native_handle = NULL;
+ }
addActiveBuffer(portIndex, *buffer);
@@ -1034,7 +1052,8 @@
if (bufferSource != NULL && portIndex == kPortIndexInput) {
bufferSource->addCodecBuffer(header);
}
- CLOG_BUFFER(allocateBuffer, NEW_BUFFER_FMT(*buffer, portIndex, "%zu@%p", size, *buffer_data));
+ CLOG_BUFFER(allocateSecureBuffer, NEW_BUFFER_FMT(
+ *buffer, portIndex, "%zu@%p:%p", size, *buffer_data, *native_handle));
return OK;
}