diff options
-rw-r--r-- | include/media/IOMX.h | 8 | ||||
-rw-r--r-- | include/media/stagefright/HardwareAPI.h | 46 | ||||
-rw-r--r-- | media/libmedia/IOMX.cpp | 73 | ||||
-rw-r--r-- | media/libstagefright/include/OMX.h | 7 | ||||
-rw-r--r-- | media/libstagefright/include/OMXNodeInstance.h | 7 | ||||
-rw-r--r-- | media/libstagefright/omx/OMX.cpp | 13 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 88 |
7 files changed, 238 insertions, 4 deletions
diff --git a/include/media/IOMX.h b/include/media/IOMX.h index 2f61cbe..1f8ce71 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -19,6 +19,7 @@ #define ANDROID_IOMX_H_ #include <binder/IInterface.h> +#include <ui/GraphicBuffer.h> #include <utils/List.h> #include <utils/String8.h> @@ -78,10 +79,17 @@ public: node_id node, OMX_INDEXTYPE index, const void *params, size_t size) = 0; + virtual status_t enableGraphicBuffers( + node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; + virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) = 0; + virtual status_t useGraphicBuffer( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) = 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 diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h index 221c679..7595c56 100644 --- a/include/media/stagefright/HardwareAPI.h +++ b/include/media/stagefright/HardwareAPI.h @@ -25,6 +25,51 @@ #include <OMX_Component.h> +namespace android { + +// A pointer to this struct is passed to the OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.enableAndroidNativeBuffers' extension +// is given. +// +// When Android native buffer use is disabled for a port (the default state), +// the OMX node should operate as normal, and expect UseBuffer calls to set its +// buffers. This is the mode that will be used when CPU access to the buffer is +// required. +// +// When Android native buffer use has been enabled, the OMX node must support +// only color formats in the range [OMX_COLOR_FormatAndroidPrivateStart, +// OMX_COLOR_FormatAndroidPrivateEnd). The node should then expect to receive +// UseAndroidNativeBuffer calls (via OMX_SetParameter) rather than UseBuffer +// calls. +struct EnableAndroidNativeBuffersParams { + OMX_U32 portIndex; + OMX_BOOL enable; +}; + +// Color formats in the range [OMX_COLOR_FormatAndroidPrivateStart, +// OMX_COLOR_FormatAndroidPrivateEnd) will be converted to a gralloc pixel +// format when used to allocate Android native buffers via gralloc. The +// conversion is done by subtracting OMX_COLOR_FormatAndroidPrivateStart from +// the color format reported by the codec. +enum { + OMX_COLOR_FormatAndroidPrivateStart = 0xA0000000, + OMX_COLOR_FormatAndroidPrivateEnd = 0xB0000000, +}; + +// A pointer to this struct is passed to OMX_SetParameter when the extension +// index for the 'OMX.google.android.index.useAndroidNativeBuffer' extension is +// given. This call will only be performed if a prior call was made with the +// 'OMX.google.android.index.enableAndroidNativeBuffers' extension index, +// enabling use of Android native buffers. +struct UseAndroidNativeBufferParams { + OMX_BUFFERHEADERTYPE **bufferHeader; + OMX_U32 portIndex; + OMX_PTR appPrivate; + const sp<android_native_buffer_t>& nativeBuffer; +}; + +} // namespace android + extern android::VideoRenderer *createRenderer( const android::sp<android::ISurface> &surface, const char *componentName, @@ -35,4 +80,3 @@ extern android::VideoRenderer *createRenderer( extern android::OMXPluginBase *createOMXPlugin(); #endif // HARDWARE_API_H_ - diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index f3804b8..40801a2 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -21,7 +21,9 @@ enum { SET_PARAMETER, GET_CONFIG, SET_CONFIG, + ENABLE_GRAPHIC_BUFFERS, USE_BUFFER, + USE_GRAPHIC_BUFFER, ALLOC_BUFFER, ALLOC_BUFFER_WITH_BACKUP, FREE_BUFFER, @@ -216,6 +218,19 @@ public: return reply.readInt32(); } + virtual status_t enableGraphicBuffers( + node_id node, OMX_U32 port_index, OMX_BOOL enable) { + Parcel data, reply; + data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); + data.writeIntPtr((intptr_t)node); + data.writeInt32(port_index); + data.writeInt32((uint32_t)enable); + remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply); + + status_t err = reply.readInt32(); + return err; + } + virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) { @@ -238,6 +253,29 @@ public: return err; } + + virtual status_t useGraphicBuffer( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { + Parcel data, reply; + data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); + data.writeIntPtr((intptr_t)node); + data.writeInt32(port_index); + data.write(*graphicBuffer); + remote()->transact(USE_GRAPHIC_BUFFER, data, &reply); + + status_t err = reply.readInt32(); + if (err != OK) { + *buffer = 0; + + return err; + } + + *buffer = (void*)reply.readIntPtr(); + + return err; + } + virtual status_t allocateBuffer( node_id node, OMX_U32 port_index, size_t size, buffer_id *buffer, void **buffer_data) { @@ -541,6 +579,20 @@ status_t BnOMX::onTransact( return NO_ERROR; } + case ENABLE_GRAPHIC_BUFFERS: + { + CHECK_INTERFACE(IOMX, data, reply); + + node_id node = (void*)data.readIntPtr(); + OMX_U32 port_index = data.readInt32(); + OMX_BOOL enable = (OMX_BOOL)data.readInt32(); + + status_t err = enableGraphicBuffers(node, port_index, enable); + reply->writeInt32(err); + + return NO_ERROR; + } + case USE_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); @@ -561,6 +613,27 @@ status_t BnOMX::onTransact( return NO_ERROR; } + case USE_GRAPHIC_BUFFER: + { + CHECK_INTERFACE(IOMX, data, reply); + + node_id node = (void*)data.readIntPtr(); + OMX_U32 port_index = data.readInt32(); + sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(); + data.read(*graphicBuffer); + + buffer_id buffer; + status_t err = useGraphicBuffer( + node, port_index, graphicBuffer, &buffer); + reply->writeInt32(err); + + if (err == OK) { + reply->writeIntPtr((intptr_t)buffer); + } + + return NO_ERROR; + } + case ALLOC_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h index c99da59..83b75ad 100644 --- a/media/libstagefright/include/OMX.h +++ b/media/libstagefright/include/OMX.h @@ -59,10 +59,17 @@ public: node_id node, OMX_INDEXTYPE index, const void *params, size_t size); + virtual status_t enableGraphicBuffers( + node_id node, OMX_U32 port_index, OMX_BOOL enable); + virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer); + virtual status_t useGraphicBuffer( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer); + virtual status_t allocateBuffer( node_id node, OMX_U32 port_index, size_t size, buffer_id *buffer, void **buffer_data); diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index b5b31ac..8c7c562 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -49,10 +49,16 @@ struct OMXNodeInstance { status_t getConfig(OMX_INDEXTYPE index, void *params, size_t size); status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size); + status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable); + status_t useBuffer( OMX_U32 portIndex, const sp<IMemory> ¶ms, OMX::buffer_id *buffer); + status_t useGraphicBuffer( + OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer, + OMX::buffer_id *buffer); + status_t allocateBuffer( OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer, void **buffer_data); @@ -125,4 +131,3 @@ private: } // namespace android #endif // OMX_NODE_INSTANCE_H_ - diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 88b9605..37243ad 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -287,6 +287,11 @@ status_t OMX::setConfig( index, params, size); } +status_t OMX::enableGraphicBuffers( + node_id node, OMX_U32 port_index, OMX_BOOL enable) { + return findInstance(node)->enableGraphicBuffers(port_index, enable); +} + status_t OMX::useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) { @@ -294,6 +299,13 @@ status_t OMX::useBuffer( port_index, params, buffer); } +status_t OMX::useGraphicBuffer( + node_id node, OMX_U32 port_index, + const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) { + return findInstance(node)->useGraphicBuffer( + port_index, graphicBuffer, buffer); +} + status_t OMX::allocateBuffer( node_id node, OMX_U32 port_index, size_t size, buffer_id *buffer, void **buffer_data) { @@ -530,4 +542,3 @@ void OMXRenderer::render(IOMX::buffer_id buffer) { } } // namespace android - diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index 5db516e..1104113 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -24,6 +24,7 @@ #include <OMX_Component.h> #include <binder/IMemory.h> +#include <media/stagefright/HardwareAPI.h> #include <media/stagefright/MediaDebug.h> #include <media/stagefright/MediaErrors.h> @@ -40,6 +41,11 @@ struct BufferMeta { mIsBackup(false) { } + BufferMeta(const sp<GraphicBuffer> &graphicBuffer) + : mGraphicBuffer(graphicBuffer), + mIsBackup(false) { + } + void CopyFromOMX(const OMX_BUFFERHEADERTYPE *header) { if (!mIsBackup) { return; @@ -61,6 +67,7 @@ struct BufferMeta { } private: + sp<GraphicBuffer> mGraphicBuffer; sp<IMemory> mMem; size_t mSize; bool mIsBackup; @@ -240,6 +247,38 @@ status_t OMXNodeInstance::setConfig( return StatusFromOMXError(err); } +status_t OMXNodeInstance::enableGraphicBuffers( + OMX_U32 portIndex, OMX_BOOL enable) { + Mutex::Autolock autoLock(mLock); + + OMX_INDEXTYPE index; + OMX_ERRORTYPE err = OMX_GetExtensionIndex( + mHandle, + const_cast<OMX_STRING>("OMX.google.android.index.enableAndroidNativeBuffers"), + &index); + + if (err != OMX_ErrorNone) { + LOGE("OMX_GetExtensionIndex failed"); + + return StatusFromOMXError(err); + } + + EnableAndroidNativeBuffersParams params = { + portIndex, enable, + }; + + err = OMX_SetParameter(mHandle, index, ¶ms); + + if (err != OMX_ErrorNone) { + LOGE("OMX_EnableAndroidNativeBuffers failed with error %d (0x%08x)", + err, err); + + return UNKNOWN_ERROR; + } + + return OK; +} + status_t OMXNodeInstance::useBuffer( OMX_U32 portIndex, const sp<IMemory> ¶ms, OMX::buffer_id *buffer) { @@ -273,6 +312,54 @@ status_t OMXNodeInstance::useBuffer( return OK; } +status_t OMXNodeInstance::useGraphicBuffer( + OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, + OMX::buffer_id *buffer) { + Mutex::Autolock autoLock(mLock); + + OMX_INDEXTYPE index; + OMX_ERRORTYPE err = OMX_GetExtensionIndex( + mHandle, + const_cast<OMX_STRING>("OMX.google.android.index.useAndroidNativeBuffer"), + &index); + + if (err != OMX_ErrorNone) { + LOGE("OMX_GetExtensionIndex failed"); + + return StatusFromOMXError(err); + } + + BufferMeta *bufferMeta = new BufferMeta(graphicBuffer); + + OMX_BUFFERHEADERTYPE *header; + + UseAndroidNativeBufferParams params = { + &header, portIndex, bufferMeta, graphicBuffer, + }; + + err = OMX_SetParameter(mHandle, index, ¶ms); + + if (err != OMX_ErrorNone) { + LOGE("OMX_UseAndroidNativeBuffer failed with error %d (0x%08x)", err, + err); + + delete bufferMeta; + bufferMeta = NULL; + + *buffer = 0; + + return UNKNOWN_ERROR; + } + + CHECK_EQ(header->pAppPrivate, bufferMeta); + + *buffer = header; + + addActiveBuffer(portIndex, *buffer); + + return OK; +} + status_t OMXNodeInstance::allocateBuffer( OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer, void **buffer_data) { @@ -498,4 +585,3 @@ void OMXNodeInstance::freeActiveBuffers() { } } // namespace android - |