stagefright: add a way to update native handle in OMX buffers
Bug: 22775369
Change-Id: I7d7eb0868fef896d1cb0a45bec759a00f0783673
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 19c7955..8caf72d 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -118,6 +118,10 @@
node_id node, OMX_U32 port_index,
const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) = 0;
+ virtual status_t updateNativeHandleInMeta(
+ node_id node, OMX_U32 port_index,
+ const sp<NativeHandle> &nativeHandle, buffer_id buffer) = 0;
+
// This will set *type to resulting metadata buffer type on OMX error (not on binder error) as
// well as on success.
virtual status_t createInputSurface(
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 61fba35..9b3ef30 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -25,6 +25,7 @@
#include <media/IOMX.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/openmax/OMX_IndexExt.h>
+#include <utils/NativeHandle.h>
namespace android {
@@ -60,6 +61,7 @@
SET_INTERNAL_OPTION,
UPDATE_GRAPHIC_BUFFER_IN_META,
CONFIGURE_VIDEO_TUNNEL_MODE,
+ UPDATE_NATIVE_HANDLE_IN_META,
};
class BpOMX : public BpInterface<IOMX> {
@@ -313,6 +315,24 @@
return err;
}
+ virtual status_t updateNativeHandleInMeta(
+ node_id node, OMX_U32 port_index,
+ const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+ data.writeInt32((int32_t)node);
+ data.writeInt32(port_index);
+ data.writeInt32(nativeHandle != NULL);
+ if (nativeHandle != NULL) {
+ data.writeNativeHandle(nativeHandle->handle());
+ }
+ data.writeInt32((int32_t)buffer);
+ remote()->transact(UPDATE_NATIVE_HANDLE_IN_META, data, &reply);
+
+ status_t err = reply.readInt32();
+ return err;
+ }
+
virtual status_t createInputSurface(
node_id node, OMX_U32 port_index, android_dataspace dataSpace,
sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
@@ -908,6 +928,25 @@
return NO_ERROR;
}
+ case UPDATE_NATIVE_HANDLE_IN_META:
+ {
+ CHECK_OMX_INTERFACE(IOMX, data, reply);
+
+ node_id node = (node_id)data.readInt32();
+ OMX_U32 port_index = data.readInt32();
+ native_handle *handle = NULL;
+ if (data.readInt32()) {
+ handle = data.readNativeHandle();
+ }
+ buffer_id buffer = (buffer_id)data.readInt32();
+
+ status_t err = updateNativeHandleInMeta(
+ node, port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
+ reply->writeInt32(err);
+
+ return NO_ERROR;
+ }
+
case CREATE_INPUT_SURFACE:
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index a523d0e..e19c9f6 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -111,6 +111,10 @@
node_id node, OMX_U32 port_index,
const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer);
+ virtual status_t updateNativeHandleInMeta(
+ node_id node, OMX_U32 port_index,
+ const sp<NativeHandle> &nativeHandle, buffer_id buffer);
+
virtual status_t createInputSurface(
node_id node, OMX_U32 port_index, android_dataspace dataSpace,
sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type);
@@ -387,6 +391,13 @@
node, port_index, graphicBuffer, buffer);
}
+status_t MuxOMX::updateNativeHandleInMeta(
+ node_id node, OMX_U32 port_index,
+ const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
+ return getOMX(node)->updateNativeHandleInMeta(
+ node, port_index, nativeHandle, buffer);
+}
+
status_t MuxOMX::createInputSurface(
node_id node, OMX_U32 port_index, android_dataspace dataSpace,
sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 9726741..53bf5d6 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -93,6 +93,10 @@
node_id node, OMX_U32 port_index,
const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer);
+ virtual status_t updateNativeHandleInMeta(
+ node_id node, OMX_U32 port_index,
+ const sp<NativeHandle> &nativeHandle, buffer_id buffer);
+
virtual status_t createInputSurface(
node_id node, OMX_U32 port_index, android_dataspace dataSpace,
sp<IGraphicBufferProducer> *bufferProducer,
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 25c3773..736718c 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -79,6 +79,10 @@
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
OMX::buffer_id buffer);
+ status_t updateNativeHandleInMeta(
+ OMX_U32 portIndex, const sp<NativeHandle> &nativeHandle,
+ OMX::buffer_id buffer);
+
status_t createInputSurface(
OMX_U32 portIndex, android_dataspace dataSpace,
sp<IGraphicBufferProducer> *bufferProducer,
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 4d89ba1..711e32e 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -488,6 +488,19 @@
port_index, graphicBuffer, buffer);
}
+status_t OMX::updateNativeHandleInMeta(
+ node_id node, OMX_U32 port_index,
+ const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
+ OMXNodeInstance *instance = findInstance(node);
+
+ if (instance == NULL) {
+ return NAME_NOT_FOUND;
+ }
+
+ return instance->updateNativeHandleInMeta(
+ port_index, nativeHandle, buffer);
+}
+
status_t OMX::createInputSurface(
node_id node, OMX_U32 port_index, android_dataspace dataSpace,
sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 6b7a871..862a614 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -38,6 +38,7 @@
#include <media/stagefright/MediaErrors.h>
#include <utils/misc.h>
+#include <utils/NativeHandle.h>
static const OMX_U32 kPortIndexInput = 0;
static const OMX_U32 kPortIndexOutput = 1;
@@ -152,8 +153,13 @@
mGraphicBuffer = graphicBuffer;
}
+ void setNativeHandle(const sp<NativeHandle> &nativeHandle) {
+ mNativeHandle = nativeHandle;
+ }
+
private:
sp<GraphicBuffer> mGraphicBuffer;
+ sp<NativeHandle> mNativeHandle;
sp<IMemory> mMem;
size_t mSize;
bool mIsBackup;
@@ -871,6 +877,43 @@
return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, buffer, header);
}
+status_t OMXNodeInstance::updateNativeHandleInMeta(
+ OMX_U32 portIndex, const sp<NativeHandle>& nativeHandle, OMX::buffer_id buffer) {
+ Mutex::Autolock autoLock(mLock);
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
+ // No need to check |nativeHandle| since NULL is valid for it as below.
+ if (header == NULL) {
+ ALOGE("b/25884056");
+ return BAD_VALUE;
+ }
+
+ if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
+ return BAD_VALUE;
+ }
+
+ BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
+ // update backup buffer for input, codec buffer for output
+ sp<ABuffer> data = bufferMeta->getBuffer(
+ header, portIndex == kPortIndexInput /* backup */, false /* limit */);
+ bufferMeta->setNativeHandle(nativeHandle);
+ if (mMetadataType[portIndex] == kMetadataBufferTypeNativeHandleSource
+ && data->capacity() >= sizeof(VideoNativeHandleMetadata)) {
+ VideoNativeHandleMetadata &metadata = *(VideoNativeHandleMetadata *)(data->data());
+ metadata.eType = mMetadataType[portIndex];
+ metadata.pHandle =
+ nativeHandle == NULL ? NULL : const_cast<native_handle*>(nativeHandle->handle());
+ } else {
+ CLOG_ERROR(updateNativeHandleInMeta, BAD_VALUE, "%s:%u, %#x bad type (%d) or size (%zu)",
+ portString(portIndex), portIndex, buffer, mMetadataType[portIndex], data->capacity());
+ return BAD_VALUE;
+ }
+
+ CLOG_BUFFER(updateNativeHandleInMeta, "%s:%u, %#x := %p",
+ portString(portIndex), portIndex, buffer,
+ nativeHandle == NULL ? NULL : nativeHandle->handle());
+ return OK;
+}
+
status_t OMXNodeInstance::createGraphicBufferSource(
OMX_U32 portIndex, sp<IGraphicBufferConsumer> bufferConsumer, MetadataBufferType *type) {
status_t err;