Merge "Add an OMX IL API for querying buffer usage flags."
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index cb36bbb..16a9342 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -85,6 +85,9 @@
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0;
 
+    virtual status_t getGraphicBufferUsage(
+            node_id node, OMX_U32 port_index, OMX_U32* usage) = 0;
+
     virtual status_t useBuffer(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer) = 0;
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index 17908b4..d1ecaaf 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -87,6 +87,18 @@
     const sp<android_native_buffer_t>& nativeBuffer;
 };
 
+// A pointer to this struct is passed to OMX_GetParameter when the extension
+// index for the 'OMX.google.android.index.getAndroidNativeBufferUsage'
+// extension is given.  The usage bits returned from this query will be used to
+// allocate the Gralloc buffers that get passed to the useAndroidNativeBuffer
+// command.
+struct GetAndroidNativeBufferUsageParams {
+    OMX_U32 nSize;              // IN
+    OMX_VERSIONTYPE nVersion;   // IN
+    OMX_U32 nPortIndex;         // IN
+    OMX_U32 nUsage;             // OUT
+};
+
 }  // namespace android
 
 extern android::OMXPluginBase *createOMXPlugin();
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index af67175..d6a1757 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -33,6 +33,7 @@
     EMPTY_BUFFER,
     GET_EXTENSION_INDEX,
     OBSERVER_ON_MSG,
+    GET_GRAPHIC_BUFFER_USAGE,
 };
 
 class BpOMX : public BpInterface<IOMX> {
@@ -194,6 +195,19 @@
         return err;
     }
 
+    virtual status_t getGraphicBufferUsage(
+            node_id node, OMX_U32 port_index, OMX_U32* usage) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
+        data.writeIntPtr((intptr_t)node);
+        data.writeInt32(port_index);
+        remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
+
+        status_t err = reply.readInt32();
+        *usage = reply.readInt32();
+        return err;
+    }
+
     virtual status_t useBuffer(
             node_id node, OMX_U32 port_index, const sp<IMemory> &params,
             buffer_id *buffer) {
@@ -508,6 +522,21 @@
             return NO_ERROR;
         }
 
+        case GET_GRAPHIC_BUFFER_USAGE:
+        {
+            CHECK_INTERFACE(IOMX, data, reply);
+
+            node_id node = (void*)data.readIntPtr();
+            OMX_U32 port_index = data.readInt32();
+
+            OMX_U32 usage = 0;
+            status_t err = getGraphicBufferUsage(node, port_index, &usage);
+            reply->writeInt32(err);
+            reply->writeInt32(usage);
+
+            return NO_ERROR;
+        }
+
         case USE_BUFFER:
         {
             CHECK_INTERFACE(IOMX, data, reply);
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 5fed98a..ec3e5fa 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -62,6 +62,9 @@
     virtual status_t enableGraphicBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable);
 
+    virtual status_t getGraphicBufferUsage(
+            node_id node, OMX_U32 port_index, OMX_U32* usage);
+
     virtual status_t storeMetaDataInBuffers(
             node_id node, OMX_U32 port_index, OMX_BOOL enable);
 
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 86c102c..ca2578f 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -50,6 +50,9 @@
     status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size);
 
     status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable);
+
+    status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
+
     status_t storeMetaDataInBuffers(OMX_U32 portIndex, OMX_BOOL enable);
 
     status_t useBuffer(
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 3638f41..4b1c3a7 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -297,6 +297,11 @@
     return findInstance(node)->enableGraphicBuffers(port_index, enable);
 }
 
+status_t OMX::getGraphicBufferUsage(
+        node_id node, OMX_U32 port_index, OMX_U32* usage) {
+    return findInstance(node)->getGraphicBufferUsage(port_index, usage);
+}
+
 status_t OMX::storeMetaDataInBuffers(
         node_id node, OMX_U32 port_index, OMX_BOOL enable) {
     return findInstance(node)->storeMetaDataInBuffers(port_index, enable);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index c7c1409..6cbd599 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -302,6 +302,45 @@
     return OK;
 }
 
+status_t OMXNodeInstance::getGraphicBufferUsage(
+        OMX_U32 portIndex, OMX_U32* usage) {
+    Mutex::Autolock autoLock(mLock);
+
+    OMX_INDEXTYPE index;
+    OMX_ERRORTYPE err = OMX_GetExtensionIndex(
+            mHandle,
+            const_cast<OMX_STRING>(
+                    "OMX.google.android.index.getAndroidNativeBufferUsage"),
+            &index);
+
+    if (err != OMX_ErrorNone) {
+        LOGE("OMX_GetExtensionIndex failed");
+
+        return StatusFromOMXError(err);
+    }
+
+    OMX_VERSIONTYPE ver;
+    ver.s.nVersionMajor = 1;
+    ver.s.nVersionMinor = 0;
+    ver.s.nRevision = 0;
+    ver.s.nStep = 0;
+    GetAndroidNativeBufferUsageParams params = {
+        sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0,
+    };
+
+    err = OMX_GetParameter(mHandle, index, &params);
+
+    if (err != OMX_ErrorNone) {
+        LOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)",
+                err, err);
+        return UNKNOWN_ERROR;
+    }
+
+    *usage = params.nUsage;
+
+    return OK;
+}
+
 status_t OMXNodeInstance::storeMetaDataInBuffers(
         OMX_U32 portIndex,
         OMX_BOOL enable) {