IOMX: consolidate buffer passing on IOMX
- Use OMXBuffer to parcel different buffer types.
- Only leave one useBuffer, emptyBuffer and fillBuffer.
- Remove the update metadata calls.
bug: 31399200
Change-Id: I307e59415c3c5be61772210431bd8225ce6b75a3
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index b902cf5..839945c 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -19,7 +19,7 @@
#define ANDROID_IOMX_H_
#include <binder/IInterface.h>
-#include <ui/GraphicBuffer.h>
+#include <gui/IGraphicBufferProducer.h>
#include <utils/List.h>
#include <utils/String8.h>
@@ -39,6 +39,7 @@
class IOMXNode;
class IOMXObserver;
class NativeHandle;
+class OMXBuffer;
struct omx_message;
class IOMX : public IInterface {
@@ -108,23 +109,6 @@
virtual status_t getGraphicBufferUsage(
OMX_U32 port_index, OMX_U32* usage) = 0;
- // Use |params| as an OMX buffer, but limit the size of the OMX buffer to |allottedSize|.
- virtual status_t useBuffer(
- OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer, OMX_U32 allottedSize) = 0;
-
- virtual status_t useGraphicBuffer(
- OMX_U32 port_index,
- const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) = 0;
-
- virtual status_t updateGraphicBufferInMeta(
- OMX_U32 port_index,
- const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) = 0;
-
- virtual status_t updateNativeHandleInMeta(
- OMX_U32 port_index,
- const sp<NativeHandle> &nativeHandle, buffer_id buffer) = 0;
-
virtual status_t setInputSurface(
const sp<IOMXBufferSource> &bufferSource) = 0;
@@ -137,34 +121,37 @@
OMX_U32 port_index, size_t size, buffer_id *buffer,
void **buffer_data, sp<NativeHandle> *native_handle) = 0;
+ // Instructs the component to use the buffer passed in via |omxBuf| on the
+ // specified port. Returns in |*buffer| the buffer id that the component
+ // assigns to this buffer. |omxBuf| must be one of:
+ // 1) OMXBuffer::sPreset for meta-mode,
+ // 2) type kBufferTypeANWBuffer for non-meta-graphic buffer mode,
+ // 3) type kBufferTypeSharedMem for bytebuffer mode.
+ virtual status_t useBuffer(
+ OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) = 0;
+
+ // Frees the buffer on the specified port with buffer id |buffer|.
virtual status_t freeBuffer(
OMX_U32 port_index, buffer_id buffer) = 0;
- // Calls OMX_FillBuffer on buffer, and passes |fenceFd| to component if it supports
- // fences. Otherwise, it waits on |fenceFd| before calling OMX_FillBuffer.
- // Takes ownership of |fenceFd| even if this call fails.
- virtual status_t fillBuffer(buffer_id buffer, int fenceFd = -1) = 0;
+ // Calls OMX_FillBuffer on buffer. Passes |fenceFd| to component if it
+ // supports fences. Otherwise, it waits on |fenceFd| before calling
+ // OMX_FillBuffer. Takes ownership of |fenceFd| even if this call fails.
+ // If the port is in metadata mode, the buffer will be updated to point
+ // to the new buffer passed in via |omxBuf| before OMX_FillBuffer is called.
+ // Otherwise info in the |omxBuf| is not used.
+ virtual status_t fillBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1) = 0;
- // Calls OMX_EmptyBuffer on buffer (after updating buffer header with |range_offset|,
- // |range_length|, |flags| and |timestamp|). Passes |fenceFd| to component if it
- // supports fences. Otherwise, it waits on |fenceFd| before calling OMX_EmptyBuffer.
- // Takes ownership of |fenceFd| even if this call fails.
+ // Calls OMX_EmptyBuffer on buffer. Passes |fenceFd| to component if it
+ // supports fences. Otherwise, it waits on |fenceFd| before calling
+ // OMX_EmptyBuffer. Takes ownership of |fenceFd| even if this call fails.
+ // If the port is in metadata mode, the buffer will be updated to point
+ // to the new buffer passed in via |omxBuf| before OMX_EmptyBuffer is called.
virtual status_t emptyBuffer(
- buffer_id buffer,
- OMX_U32 range_offset, OMX_U32 range_length,
+ buffer_id buffer, const OMXBuffer &omxBuf,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1) = 0;
- // Calls OMX_EmptyBuffer on buffer (after updating buffer header with metadata of
- // |graphicBuffer|, |flags| and |timestamp|). Passes |fenceFd| to component if it
- // supports fences. Otherwise, it waits on |fenceFd| before calling OMX_EmptyBuffer.
- // Takes ownership of |fenceFd| even if this call fails. If |origTimestamp| >= 0,
- // timestamp on the filled buffer corresponding to this frame will be modified to
- // |origTimestamp| after it's filled.
- virtual status_t emptyGraphicBuffer(
- buffer_id buffer,
- const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
- OMX_TICKS timestamp, int fenceFd) = 0;
-
virtual status_t getExtensionIndex(
const char *parameter_name,
OMX_INDEXTYPE *index) = 0;
diff --git a/include/media/OMXBuffer.h b/include/media/OMXBuffer.h
new file mode 100644
index 0000000..0322b73
--- /dev/null
+++ b/include/media/OMXBuffer.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _OMXBUFFER_H_
+#define _OMXBUFFER_H_
+
+#include <cutils/native_handle.h>
+#include <media/IOMX.h>
+#include <system/window.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class GraphicBuffer;
+class IMemory;
+class MediaCodecBuffer;
+class NativeHandle;
+class OMXNodeInstance;
+
+class OMXBuffer {
+public:
+ // sPreset is used in places where we are referring to a pre-registered
+ // buffer on a port. It has type kBufferTypePreset and mRangeLength of 0.
+ static OMXBuffer sPreset;
+
+ // Default constructor, constructs a buffer of type kBufferTypeInvalid.
+ OMXBuffer();
+
+ // Constructs a buffer of type kBufferTypePreset with mRangeLength set to
+ // |codecBuffer|'s size (or 0 if |codecBuffer| is NULL).
+ OMXBuffer(const sp<MediaCodecBuffer> &codecBuffer);
+
+ // Constructs a buffer of type kBufferTypeSharedMem.
+ OMXBuffer(const sp<IMemory> &mem, size_t allottedSize = 0);
+
+ // Constructs a buffer of type kBufferTypeANWBuffer.
+ OMXBuffer(const sp<GraphicBuffer> &gbuf);
+
+ // Constructs a buffer of type kBufferTypeNativeHandle.
+ OMXBuffer(const sp<NativeHandle> &handle);
+
+ // Parcelling/Un-parcelling.
+ status_t writeToParcel(Parcel *parcel) const;
+ status_t readFromParcel(const Parcel *parcel);
+
+ ~OMXBuffer();
+
+private:
+ friend class OMXNodeInstance;
+
+ enum BufferType {
+ kBufferTypeInvalid = 0,
+ kBufferTypePreset,
+ kBufferTypeSharedMem,
+ kBufferTypeANWBuffer,
+ kBufferTypeNativeHandle,
+ };
+
+ BufferType mBufferType;
+
+ // kBufferTypePreset
+ // If the port is operating in byte buffer mode, mRangeLength is the valid
+ // range length. Otherwise the range info should also be ignored.
+ OMX_U32 mRangeLength;
+
+ // kBufferTypeSharedMem
+ sp<IMemory> mMem;
+ OMX_U32 mAllottedSize;
+
+ // kBufferTypeANWBuffer
+ sp<GraphicBuffer> mGraphicBuffer;
+
+ // kBufferTypeNativeHandle
+ sp<NativeHandle> mNativeHandle;
+
+ OMXBuffer(const OMXBuffer &);
+ OMXBuffer &operator=(const OMXBuffer &);
+};
+
+} // namespace android
+
+#endif // _OMXBUFFER_H_
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 64a542d..13ceeb6 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -330,6 +330,8 @@
uint32_t portIndex, IOMX::buffer_id bufferID,
ssize_t *index = NULL);
+ status_t fillBuffer(BufferInfo *info);
+
status_t setComponentRole(bool isEncoder, const char *mime);
status_t configureCodec(const char *mime, const sp<AMessage> &msg);
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index ca96098..56b2979 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -65,6 +65,7 @@
MediaProfiles.cpp \
MediaResource.cpp \
MediaResourcePolicy.cpp \
+ OMXBuffer.cpp \
IEffect.cpp \
IEffectClient.cpp \
AudioEffect.cpp \
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 4bd1ab8..1a6d6b8 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -26,8 +26,8 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/openmax/OMX_IndexExt.h>
#include <utils/NativeHandle.h>
+#include <media/OMXBuffer.h>
-#include <gui/IGraphicBufferProducer.h>
#include <android/IGraphicBufferSource.h>
#include <android/IOMXBufferSource.h>
@@ -45,7 +45,6 @@
SET_CONFIG,
ENABLE_NATIVE_BUFFERS,
USE_BUFFER,
- USE_GRAPHIC_BUFFER,
CREATE_INPUT_SURFACE,
SET_INPUT_SURFACE,
STORE_META_DATA_IN_BUFFERS,
@@ -54,13 +53,10 @@
FREE_BUFFER,
FILL_BUFFER,
EMPTY_BUFFER,
- EMPTY_GRAPHIC_BUFFER,
GET_EXTENSION_INDEX,
OBSERVER_ON_MSG,
GET_GRAPHIC_BUFFER_USAGE,
- UPDATE_GRAPHIC_BUFFER_IN_META,
CONFIGURE_VIDEO_TUNNEL_MODE,
- UPDATE_NATIVE_HANDLE_IN_META,
DISPATCH_MESSAGE,
SET_QUIRKS,
};
@@ -255,16 +251,19 @@
}
virtual status_t useBuffer(
- OMX_U32 port_index, const sp<IMemory> ¶ms,
- buffer_id *buffer, OMX_U32 allottedSize) {
+ OMX_U32 port_index, const OMXBuffer &omxBuf, buffer_id *buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
data.writeInt32(port_index);
- data.writeStrongBinder(IInterface::asBinder(params));
- data.writeInt32(allottedSize);
+
+ status_t err = omxBuf.writeToParcel(&data);
+ if (err != OK) {
+ return err;
+ }
+
remote()->transact(USE_BUFFER, data, &reply);
- status_t err = reply.readInt32();
+ err = reply.readInt32();
if (err != OK) {
*buffer = 0;
@@ -276,59 +275,6 @@
return err;
}
-
- virtual status_t useGraphicBuffer(
- OMX_U32 port_index,
- const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
- Parcel data, reply;
- data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
- 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 = (buffer_id)reply.readInt32();
-
- return err;
- }
-
- virtual status_t updateGraphicBufferInMeta(
- OMX_U32 port_index,
- const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
- Parcel data, reply;
- data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
- data.writeInt32(port_index);
- data.write(*graphicBuffer);
- data.writeInt32((int32_t)buffer);
- remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
-
- status_t err = reply.readInt32();
- return err;
- }
-
- virtual status_t updateNativeHandleInMeta(
- OMX_U32 port_index,
- const sp<NativeHandle> &nativeHandle, buffer_id buffer) {
- Parcel data, reply;
- data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
- 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 setInputSurface(
const sp<IOMXBufferSource> &bufferSource) {
Parcel data, reply;
@@ -439,10 +385,15 @@
return reply.readInt32();
}
- virtual status_t fillBuffer(buffer_id buffer, int fenceFd) {
+ virtual status_t fillBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd) {
Parcel data, reply;
data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
data.writeInt32((int32_t)buffer);
+ status_t err = omxBuf.writeToParcel(&data);
+ if (err != OK) {
+ return err;
+ }
data.writeInt32(fenceFd >= 0);
if (fenceFd >= 0) {
data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
@@ -453,14 +404,15 @@
}
virtual status_t emptyBuffer(
- buffer_id buffer,
- OMX_U32 range_offset, OMX_U32 range_length,
+ buffer_id buffer, const OMXBuffer &omxBuf,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
Parcel data, reply;
data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
data.writeInt32((int32_t)buffer);
- data.writeInt32(range_offset);
- data.writeInt32(range_length);
+ status_t err = omxBuf.writeToParcel(&data);
+ if (err != OK) {
+ return err;
+ }
data.writeInt32(flags);
data.writeInt64(timestamp);
data.writeInt32(fenceFd >= 0);
@@ -472,25 +424,6 @@
return reply.readInt32();
}
- virtual status_t emptyGraphicBuffer(
- buffer_id buffer,
- const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
- OMX_TICKS timestamp, int fenceFd) {
- Parcel data, reply;
- data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
- data.writeInt32((int32_t)buffer);
- data.write(*graphicBuffer);
- data.writeInt32(flags);
- data.writeInt64(timestamp);
- data.writeInt32(fenceFd >= 0);
- if (fenceFd >= 0) {
- data.writeFileDescriptor(fenceFd, true /* takeOwnership */);
- }
- remote()->transact(EMPTY_GRAPHIC_BUFFER, data, &reply);
-
- return reply.readInt32();
- }
-
virtual status_t getExtensionIndex(
const char *parameter_name,
OMX_INDEXTYPE *index) {
@@ -770,18 +703,15 @@
CHECK_OMX_INTERFACE(IOMXNode, data, reply);
OMX_U32 port_index = data.readInt32();
- sp<IMemory> params =
- interface_cast<IMemory>(data.readStrongBinder());
- OMX_U32 allottedSize = data.readInt32();
- if (params == NULL) {
- ALOGE("b/26392700");
- reply->writeInt32(INVALID_OPERATION);
- return NO_ERROR;
+ OMXBuffer omxBuf;
+ status_t err = omxBuf.readFromParcel(&data);
+ if (err != OK) {
+ return err;
}
buffer_id buffer;
- status_t err = useBuffer(port_index, params, &buffer, allottedSize);
+ err = useBuffer(port_index, omxBuf, &buffer);
reply->writeInt32(err);
if (err == OK) {
@@ -791,60 +721,6 @@
return NO_ERROR;
}
- case USE_GRAPHIC_BUFFER:
- {
- CHECK_OMX_INTERFACE(IOMXNode, data, reply);
-
- OMX_U32 port_index = data.readInt32();
- sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
- data.read(*graphicBuffer);
-
- buffer_id buffer;
- status_t err = useGraphicBuffer(
- port_index, graphicBuffer, &buffer);
- reply->writeInt32(err);
-
- if (err == OK) {
- reply->writeInt32((int32_t)buffer);
- }
-
- return NO_ERROR;
- }
-
- case UPDATE_GRAPHIC_BUFFER_IN_META:
- {
- CHECK_OMX_INTERFACE(IOMXNode, data, reply);
-
- OMX_U32 port_index = data.readInt32();
- sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
- data.read(*graphicBuffer);
- buffer_id buffer = (buffer_id)data.readInt32();
-
- status_t err = updateGraphicBufferInMeta(
- port_index, graphicBuffer, buffer);
- reply->writeInt32(err);
-
- return NO_ERROR;
- }
-
- case UPDATE_NATIVE_HANDLE_IN_META:
- {
- CHECK_OMX_INTERFACE(IOMXNode, data, reply);
-
- 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(
- port_index, NativeHandle::create(handle, true /* ownshandle */), buffer);
- reply->writeInt32(err);
-
- return NO_ERROR;
- }
-
case SET_INPUT_SURFACE:
{
CHECK_OMX_INTERFACE(IOMXNode, data, reply);
@@ -956,9 +832,17 @@
CHECK_OMX_INTERFACE(IOMXNode, data, reply);
buffer_id buffer = (buffer_id)data.readInt32();
+
+ OMXBuffer omxBuf;
+ status_t err = omxBuf.readFromParcel(&data);
+ if (err != OK) {
+ return err;
+ }
+
bool haveFence = data.readInt32();
int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
- reply->writeInt32(fillBuffer(buffer, fenceFd));
+
+ reply->writeInt32(fillBuffer(buffer, omxBuf, fenceFd));
return NO_ERROR;
}
@@ -968,31 +852,17 @@
CHECK_OMX_INTERFACE(IOMXNode, data, reply);
buffer_id buffer = (buffer_id)data.readInt32();
- OMX_U32 range_offset = data.readInt32();
- OMX_U32 range_length = data.readInt32();
+ OMXBuffer omxBuf;
+ status_t err = omxBuf.readFromParcel(&data);
+ if (err != OK) {
+ return err;
+ }
OMX_U32 flags = data.readInt32();
OMX_TICKS timestamp = data.readInt64();
bool haveFence = data.readInt32();
int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
reply->writeInt32(emptyBuffer(
- buffer, range_offset, range_length, flags, timestamp, fenceFd));
-
- return NO_ERROR;
- }
-
- case EMPTY_GRAPHIC_BUFFER:
- {
- CHECK_OMX_INTERFACE(IOMXNode, data, reply);
-
- buffer_id buffer = (buffer_id)data.readInt32();
- sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
- data.read(*graphicBuffer);
- OMX_U32 flags = data.readInt32();
- OMX_TICKS timestamp = data.readInt64();
- bool haveFence = data.readInt32();
- int fenceFd = haveFence ? ::dup(data.readFileDescriptor()) : -1;
- reply->writeInt32(emptyGraphicBuffer(
- buffer, graphicBuffer, flags, timestamp, fenceFd));
+ buffer, omxBuf, flags, timestamp, fenceFd));
return NO_ERROR;
}
diff --git a/media/libmedia/OMXBuffer.cpp b/media/libmedia/OMXBuffer.cpp
new file mode 100644
index 0000000..0931872
--- /dev/null
+++ b/media/libmedia/OMXBuffer.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "OMXBuffer"
+
+#include <media/MediaCodecBuffer.h>
+#include <media/OMXBuffer.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <ui/GraphicBuffer.h>
+#include <utils/NativeHandle.h>
+
+namespace android {
+
+//static
+OMXBuffer OMXBuffer::sPreset(static_cast<sp<MediaCodecBuffer> >(NULL));
+
+OMXBuffer::OMXBuffer()
+ : mBufferType(kBufferTypeInvalid) {
+}
+
+OMXBuffer::OMXBuffer(const sp<MediaCodecBuffer>& codecBuffer)
+ : mBufferType(kBufferTypePreset),
+ mRangeLength(codecBuffer != NULL ? codecBuffer->size() : 0) {
+}
+
+OMXBuffer::OMXBuffer(const sp<IMemory> &mem, size_t allottedSize)
+ : mBufferType(kBufferTypeSharedMem),
+ mMem(mem),
+ mAllottedSize(allottedSize ? : mem->size()) {
+}
+
+OMXBuffer::OMXBuffer(const sp<GraphicBuffer> &gbuf)
+ : mBufferType(kBufferTypeANWBuffer),
+ mGraphicBuffer(gbuf) {
+}
+
+OMXBuffer::OMXBuffer(const sp<NativeHandle> &handle)
+ : mBufferType(kBufferTypeNativeHandle),
+ mNativeHandle(handle) {
+}
+
+OMXBuffer::~OMXBuffer() {
+}
+
+status_t OMXBuffer::writeToParcel(Parcel *parcel) const {
+ parcel->writeInt32(mBufferType);
+
+ switch(mBufferType) {
+ case kBufferTypePreset:
+ {
+ return parcel->writeUint32(mRangeLength);
+ }
+
+ case kBufferTypeSharedMem:
+ {
+ status_t err = parcel->writeStrongBinder(IInterface::asBinder(mMem));
+ if (err != NO_ERROR) {
+ return err;
+ }
+ return parcel->writeUint32(mAllottedSize);
+ }
+
+ case kBufferTypeANWBuffer:
+ {
+ return parcel->write(*mGraphicBuffer);
+ }
+
+ case kBufferTypeNativeHandle:
+ {
+ return parcel->writeNativeHandle(mNativeHandle->handle());
+ }
+
+ default:
+ return BAD_VALUE;
+ }
+ return BAD_VALUE;
+}
+
+status_t OMXBuffer::readFromParcel(const Parcel *parcel) {
+ BufferType bufferType = (BufferType) parcel->readInt32();
+
+ switch(bufferType) {
+ case kBufferTypePreset:
+ {
+ mRangeLength = parcel->readUint32();
+ break;
+ }
+
+ case kBufferTypeSharedMem:
+ {
+ sp<IMemory> params = interface_cast<IMemory>(parcel->readStrongBinder());
+
+ mMem = params;
+ mAllottedSize = parcel->readUint32();
+ break;
+ }
+
+ case kBufferTypeANWBuffer:
+ {
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+
+ status_t err = parcel->read(*buffer);
+
+ if (err != OK) {
+ return err;
+ }
+
+ mGraphicBuffer = buffer;
+ break;
+ }
+
+ case kBufferTypeNativeHandle:
+ {
+ sp<NativeHandle> handle = NativeHandle::create(
+ parcel->readNativeHandle(), true /* ownsHandle */);
+
+ mNativeHandle = handle;
+ break;
+ }
+
+ default:
+ return BAD_VALUE;
+ }
+
+ mBufferType = bufferType;
+ return OK;
+}
+
+} // namespace android
+
+
+
+
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 52c0feb..094f5cc 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -44,6 +44,7 @@
#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/SurfaceUtils.h>
#include <media/hardware/HardwareAPI.h>
+#include <media/OMXBuffer.h>
#include <OMX_AudioExt.h>
#include <OMX_VideoExt.h>
@@ -796,7 +797,7 @@
status_t err;
if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
- if (storingMetadataInDecodedBuffers()) {
+ if (storingMetadataInDecodedBuffers() && !mLegacyAdaptiveExperiment) {
err = allocateOutputMetadataBuffers();
} else {
err = allocateOutputBuffersFromNativeWindow();
@@ -893,8 +894,8 @@
: new SecureBuffer(format, native_handle, bufSize);
info.mCodecData = info.mData;
} else {
- err = mOMXNode->useBuffer(
- portIndex, mem, &info.mBufferID, allottedSize);
+ err = mOMXNode->useBuffer(portIndex,
+ OMXBuffer(mem, allottedSize), &info.mBufferID);
}
if (mem != NULL) {
@@ -1085,6 +1086,11 @@
}
status_t ACodec::allocateOutputBuffersFromNativeWindow() {
+ // This method only handles the non-metadata mode, or legacy metadata mode
+ // (where the headers for each buffer id will be fixed). Non-legacy metadata
+ // mode shouldn't go through this path.
+ CHECK(!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment);
+
OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
status_t err = configureOutputBuffersFromNativeWindow(
&bufferCount, &bufferSize, &minUndequeuedBuffers, true /* preregister */);
@@ -1092,10 +1098,8 @@
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
- if (!storingMetadataInDecodedBuffers()) {
- static_cast<Surface*>(mNativeWindow.get())
- ->getIGraphicBufferProducer()->allowAllocation(true);
- }
+ static_cast<Surface*>(mNativeWindow.get())
+ ->getIGraphicBufferProducer()->allowAllocation(true);
ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
"output port",
@@ -1118,11 +1122,19 @@
info.mIsReadFence = false;
info.mRenderInfo = NULL;
info.mGraphicBuffer = graphicBuffer;
+
+ // TODO: We shouln't need to create MediaCodecBuffer. In metadata mode
+ // OMX doesn't use the shared memory buffer, but some code still
+ // access info.mData. Create an ABuffer as a placeholder.
+ if (storingMetadataInDecodedBuffers()) {
+ info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
+ info.mCodecData = info.mData;
+ }
+
mBuffers[kPortIndexOutput].push(info);
IOMX::buffer_id bufferId;
- err = mOMXNode->useGraphicBuffer(
- kPortIndexOutput, graphicBuffer, &bufferId);
+ err = mOMXNode->useBuffer(kPortIndexOutput, graphicBuffer, &bufferId);
if (err != 0) {
ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
"%d", i, err);
@@ -1139,9 +1151,9 @@
OMX_U32 cancelStart;
OMX_U32 cancelEnd;
- if (err != 0) {
+ if (err != 0 || storingMetadataInDecodedBuffers()) {
// If an error occurred while dequeuing we need to cancel any buffers
- // that were dequeued.
+ // that were dequeued. Also cancel all if we're in legacy metadata mode.
cancelStart = 0;
cancelEnd = mBuffers[kPortIndexOutput].size();
} else {
@@ -1160,19 +1172,23 @@
}
}
- if (!storingMetadataInDecodedBuffers()) {
- static_cast<Surface*>(mNativeWindow.get())
- ->getIGraphicBufferProducer()->allowAllocation(false);
+ static_cast<Surface*>(mNativeWindow.get())
+ ->getIGraphicBufferProducer()->allowAllocation(false);
+
+ if (storingMetadataInDecodedBuffers()) {
+ mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
}
return err;
}
status_t ACodec::allocateOutputMetadataBuffers() {
+ CHECK(storingMetadataInDecodedBuffers() && !mLegacyAdaptiveExperiment);
+
OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
status_t err = configureOutputBuffersFromNativeWindow(
&bufferCount, &bufferSize, &minUndequeuedBuffers,
- mLegacyAdaptiveExperiment /* preregister */);
+ false /* preregister */);
if (err != 0)
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
@@ -1185,7 +1201,6 @@
size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
- // Dequeue buffers and send them to OMX
for (OMX_U32 i = 0; i < bufferCount; i++) {
BufferInfo info;
info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
@@ -1206,57 +1221,13 @@
info.mCodecData = info.mData;
info.mCodecRef = mem;
- err = mOMXNode->useBuffer(
- kPortIndexOutput, mem, &info.mBufferID, mem->size());
+ err = mOMXNode->useBuffer(kPortIndexOutput, mem, &info.mBufferID);
mBuffers[kPortIndexOutput].push(info);
ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
mComponentName.c_str(), info.mBufferID, mem->pointer());
}
- if (mLegacyAdaptiveExperiment) {
- // preallocate and preregister buffers
- static_cast<Surface *>(mNativeWindow.get())
- ->getIGraphicBufferProducer()->allowAllocation(true);
-
- ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
- "output port",
- mComponentName.c_str(), bufferCount, bufferSize);
-
- // Dequeue buffers then cancel them all
- for (OMX_U32 i = 0; i < bufferCount; i++) {
- BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
-
- ANativeWindowBuffer *buf;
- int fenceFd;
- err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
- if (err != 0) {
- ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
- break;
- }
-
- sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
- mOMXNode->updateGraphicBufferInMeta(
- kPortIndexOutput, graphicBuffer, info->mBufferID);
- info->mStatus = BufferInfo::OWNED_BY_US;
- info->setWriteFence(fenceFd, "allocateOutputMetadataBuffers for legacy");
- info->mGraphicBuffer = graphicBuffer;
- }
-
- for (OMX_U32 i = 0; i < mBuffers[kPortIndexOutput].size(); i++) {
- BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
- if (info->mStatus == BufferInfo::OWNED_BY_US) {
- status_t error = cancelBufferToNativeWindow(info);
- if (err == OK) {
- err = error;
- }
- }
- }
-
- static_cast<Surface*>(mNativeWindow.get())
- ->getIGraphicBufferProducer()->allowAllocation(false);
- }
-
mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
return err;
}
@@ -1276,13 +1247,7 @@
--mMetadataBuffersToSubmit;
info->checkWriteFence("submitOutputMetadataBuffer");
- status_t err = mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
- info->mFenceFd = -1;
- if (err == OK) {
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- }
-
- return err;
+ return fillBuffer(info);
}
status_t ACodec::waitForFence(int fd, const char *dbg ) {
@@ -1467,6 +1432,12 @@
// while loop above does not complete
CHECK(storingMetadataInDecodedBuffers());
+ if (storingMetadataInDecodedBuffers() && mLegacyAdaptiveExperiment) {
+ // If we're here while running legacy experiment, we dequeued some
+ // unrecognized buffers, and the experiment can't continue.
+ ALOGE("Legacy experiment failed, drop back to metadata mode");
+ mLegacyAdaptiveExperiment = false;
+ }
// discard buffer in LRU info and replace with new buffer
oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
oldest->mStatus = BufferInfo::OWNED_BY_US;
@@ -1474,9 +1445,6 @@
mRenderTracker.untrackFrame(oldest->mRenderInfo);
oldest->mRenderInfo = NULL;
- mOMXNode->updateGraphicBufferInMeta(
- kPortIndexOutput, oldest->mGraphicBuffer, oldest->mBufferID);
-
if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
VideoGrallocMetadata *grallocMeta =
reinterpret_cast<VideoGrallocMetadata *>(oldest->mCodecData->base());
@@ -1599,6 +1567,23 @@
return NULL;
}
+status_t ACodec::fillBuffer(BufferInfo *info) {
+ status_t err;
+ if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
+ err = mOMXNode->fillBuffer(
+ info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
+ } else {
+ err = mOMXNode->fillBuffer(
+ info->mBufferID, info->mGraphicBuffer, info->mFenceFd);
+ }
+
+ info->mFenceFd = -1;
+ if (err == OK) {
+ info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
+ }
+ return err;
+}
+
status_t ACodec::setComponentRole(
bool isEncoder, const char *mime) {
const char *role = GetComponentRole(isEncoder, mime);
@@ -5683,6 +5668,8 @@
return;
}
size = info->mCodecData->size();
+ } else {
+ info->mCodecData->setRange(0, size);
}
if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
@@ -5725,25 +5712,29 @@
status_t err2 = OK;
switch (metaType) {
case kMetadataBufferTypeInvalid:
+ {
+ err2 = mCodec->mOMXNode->emptyBuffer(
+ bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
+ }
break;
#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
case kMetadataBufferTypeNativeHandleSource:
if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
VideoNativeHandleMetadata *vnhmd =
(VideoNativeHandleMetadata*)info->mCodecData->base();
- err2 = mCodec->mOMXNode->updateNativeHandleInMeta(
- mCodec->kPortIndexInput,
- NativeHandle::create(vnhmd->pHandle, false /* ownsHandle */),
- bufferID);
+ sp<NativeHandle> handle = NativeHandle::create(
+ vnhmd->pHandle, false /* ownsHandle */);
+ err2 = mCodec->mOMXNode->emptyBuffer(
+ bufferID, handle, flags, timeUs, info->mFenceFd);
}
break;
case kMetadataBufferTypeANWBuffer:
if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
- err2 = mCodec->mOMXNode->updateGraphicBufferInMeta(
- mCodec->kPortIndexInput,
- new GraphicBuffer(vnmd->pBuffer, false /* keepOwnership */),
- bufferID);
+ sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
+ vnmd->pBuffer, false /* keepOwnership */);
+ err2 = mCodec->mOMXNode->emptyBuffer(
+ bufferID, graphicBuffer, flags, timeUs, info->mFenceFd);
}
break;
#endif
@@ -5755,15 +5746,6 @@
break;
}
- if (err2 == OK) {
- err2 = mCodec->mOMXNode->emptyBuffer(
- bufferID,
- 0,
- size,
- flags,
- timeUs,
- info->mFenceFd);
- }
info->mFenceFd = -1;
if (err2 != OK) {
mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
@@ -5796,12 +5778,7 @@
info->checkReadFence("onInputBufferFilled");
status_t err2 = mCodec->mOMXNode->emptyBuffer(
- bufferID,
- 0,
- 0,
- OMX_BUFFERFLAG_EOS,
- 0,
- info->mFenceFd);
+ bufferID, OMXBuffer::sPreset, OMX_BUFFERFLAG_EOS, 0, info->mFenceFd);
info->mFenceFd = -1;
if (err2 != OK) {
mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err2));
@@ -5925,14 +5902,11 @@
ALOGV("[%s] calling fillBuffer %u",
mCodec->mComponentName.c_str(), info->mBufferID);
- err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
- info->mFenceFd = -1;
+ err = mCodec->fillBuffer(info);
if (err != OK) {
mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
return true;
}
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
break;
}
@@ -6155,12 +6129,8 @@
ALOGV("[%s] calling fillBuffer %u",
mCodec->mComponentName.c_str(), info->mBufferID);
info->checkWriteFence("onOutputBufferDrained::RESUBMIT_BUFFERS");
- status_t err = mCodec->mOMXNode->fillBuffer(
- info->mBufferID, info->mFenceFd);
- info->mFenceFd = -1;
- if (err == OK) {
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- } else {
+ status_t err = mCodec->fillBuffer(info);
+ if (err != OK) {
mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
}
}
@@ -6960,14 +6930,11 @@
ALOGV("[%s] calling fillBuffer %u", mCodec->mComponentName.c_str(), info->mBufferID);
info->checkWriteFence("submitRegularOutputBuffers");
- status_t err = mCodec->mOMXNode->fillBuffer(info->mBufferID, info->mFenceFd);
- info->mFenceFd = -1;
+ status_t err = mCodec->fillBuffer(info);
if (err != OK) {
failed = true;
break;
}
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
}
if (failed) {
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index bda29fa..85ee4ee 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -28,6 +28,7 @@
class IOMXBufferSource;
class IOMXObserver;
struct OMXMaster;
+class OMXBuffer;
struct OMXNodeInstance : public BnOMXNode {
OMXNodeInstance(
@@ -64,22 +65,6 @@
OMX_U32 portIndex, OMX_BOOL tunneled,
OMX_U32 audioHwSync, native_handle_t **sidebandHandle);
- status_t useBuffer(
- OMX_U32 portIndex, const sp<IMemory> ¶ms,
- OMX::buffer_id *buffer, OMX_U32 allottedSize);
-
- status_t useGraphicBuffer(
- OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
- OMX::buffer_id *buffer);
-
- status_t updateGraphicBufferInMeta(
- 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 setInputSurface(
const sp<IOMXBufferSource> &bufferSource);
@@ -87,19 +72,18 @@
OMX_U32 portIndex, size_t size, OMX::buffer_id *buffer,
void **buffer_data, sp<NativeHandle> *native_handle);
- status_t freeBuffer(OMX_U32 portIndex, OMX::buffer_id buffer);
+ status_t useBuffer(
+ OMX_U32 portIndex, const OMXBuffer &omxBuf, buffer_id *buffer);
- status_t fillBuffer(OMX::buffer_id buffer, int fenceFd);
+ status_t freeBuffer(
+ OMX_U32 portIndex, buffer_id buffer);
+
+ status_t fillBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuf, int fenceFd = -1);
status_t emptyBuffer(
- OMX::buffer_id buffer,
- OMX_U32 rangeOffset, OMX_U32 rangeLength,
- OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
-
- status_t emptyGraphicBuffer(
- OMX::buffer_id buffer,
- const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags,
- OMX_TICKS timestamp, int fenceFd);
+ buffer_id buffer, const OMXBuffer &omxBuf,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd = -1);
status_t getExtensionIndex(
const char *parameterName, OMX_INDEXTYPE *index);
@@ -196,9 +180,43 @@
bool isProhibitedIndex_l(OMX_INDEXTYPE index);
+ status_t useBuffer(
+ OMX_U32 portIndex, const sp<IMemory> ¶ms,
+ OMX::buffer_id *buffer, OMX_U32 allottedSize);
+
+ status_t useBuffer_l(
+ OMX_U32 portIndex, const sp<IMemory> ¶ms,
+ OMX::buffer_id *buffer, OMX_U32 allottedSize);
+
+ status_t useGraphicBuffer(
+ OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
+ OMX::buffer_id *buffer);
+
+ status_t useGraphicBufferWithMetadata_l(
+ OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
+ OMX::buffer_id *buffer);
+
status_t useGraphicBuffer2_l(
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
OMX::buffer_id *buffer);
+
+ status_t emptyBuffer(
+ OMX::buffer_id buffer,
+ OMX_U32 rangeOffset, OMX_U32 rangeLength,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
+
+ status_t emptyGraphicBuffer(
+ OMX::buffer_id buffer, const sp<GraphicBuffer> &graphicBuffer,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
+
+ status_t emptyNativeHandleBuffer(
+ OMX::buffer_id buffer, const sp<NativeHandle> &nativeHandle,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
+
+ status_t emptyBuffer_l(
+ OMX_BUFFERHEADERTYPE *header,
+ OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr, int fenceFd);
+
static OMX_ERRORTYPE OnEvent(
OMX_IN OMX_HANDLETYPE hComponent,
OMX_IN OMX_PTR pAppData,
@@ -229,10 +247,6 @@
int retrieveFenceFromMeta_l(
OMX_BUFFERHEADERTYPE *header, OMX_U32 portIndex);
- status_t emptyBuffer_l(
- OMX_BUFFERHEADERTYPE *header,
- OMX_U32 flags, OMX_TICKS timestamp, intptr_t debugAddr, int fenceFd);
-
// Updates the graphic buffer handle in the metadata buffer for |buffer| and |header| to
// |graphicBuffer|'s handle. If |updateCodecBuffer| is true, the update will happen in
// the actual codec buffer (use this if not using emptyBuffer (with no _l) later to
@@ -242,6 +256,10 @@
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header);
+ status_t updateNativeHandleInMeta_l(
+ OMX_U32 portIndex, const sp<NativeHandle> &nativeHandle,
+ OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header);
+
sp<IOMXBufferSource> getBufferSource();
void setBufferSource(const sp<IOMXBufferSource> &bufferSource);
// Called when omx_message::FILL_BUFFER_DONE is received. (Currently the
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 4575d28..7ffd3f6 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -34,6 +34,7 @@
#include "omx/OMXUtils.h"
#include <OMX_Component.h>
#include <OMX_IndexExt.h>
+#include "OMXBuffer.h"
#include <inttypes.h>
#include "FrameDropper.h"
@@ -578,7 +579,7 @@
const sp<GraphicBuffer> &buffer = codecBuffer.mGraphicBuffer;
int fenceID = item.mFence->isValid() ? item.mFence->dup() : -1;
- status_t err = mOMXNode->emptyGraphicBuffer(
+ status_t err = mOMXNode->emptyBuffer(
bufferID, buffer, OMX_BUFFERFLAG_ENDOFFRAME, codecTimeUs, fenceID);
if (err != OK) {
@@ -611,8 +612,8 @@
CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
IOMX::buffer_id bufferID = codecBuffer.mBufferID;
- status_t err = mOMXNode->emptyGraphicBuffer(
- bufferID, NULL /* buffer */,
+ status_t err = mOMXNode->emptyBuffer(
+ bufferID, (sp<GraphicBuffer>)NULL,
OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS,
0 /* timestamp */, -1 /* fenceFd */);
if (err != OK) {
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 41f3e4a..fdc9d7f 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -40,6 +40,7 @@
#include <media/stagefright/MediaErrors.h>
#include <utils/misc.h>
#include <utils/NativeHandle.h>
+#include <media/OMXBuffer.h>
static const OMX_U32 kPortIndexInput = 0;
static const OMX_U32 kPortIndexOutput = 1;
@@ -901,6 +902,21 @@
}
status_t OMXNodeInstance::useBuffer(
+ OMX_U32 portIndex,
+ const OMXBuffer &omxBuffer, OMX::buffer_id *buffer) {
+ // TODO: the allotted size is probably no longer needed.
+ if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeSharedMem) {
+ return useBuffer(portIndex, omxBuffer.mMem, buffer, omxBuffer.mAllottedSize);
+ }
+
+ if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
+ return useGraphicBuffer(portIndex, omxBuffer.mGraphicBuffer, buffer);
+ }
+
+ return BAD_VALUE;
+}
+
+status_t OMXNodeInstance::useBuffer(
OMX_U32 portIndex, const sp<IMemory> ¶ms,
OMX::buffer_id *buffer, OMX_U32 allottedSize) {
if (params == NULL || buffer == NULL) {
@@ -913,6 +929,12 @@
return BAD_VALUE;
}
+ return useBuffer_l(portIndex, params, buffer, allottedSize);
+}
+
+status_t OMXNodeInstance::useBuffer_l(
+ OMX_U32 portIndex, const sp<IMemory> ¶ms,
+ OMX::buffer_id *buffer, OMX_U32 allottedSize) {
BufferMeta *buffer_meta;
OMX_BUFFERHEADERTYPE *header;
OMX_ERRORTYPE err = OMX_ErrorNone;
@@ -937,16 +959,18 @@
if (err != OMX_ErrorNone) {
CLOG_ERROR(allocateBuffer, err,
- SIMPLE_BUFFER(portIndex, (size_t)allottedSize, params->pointer()));
+ SIMPLE_BUFFER(portIndex, (size_t)allottedSize,
+ params != NULL ? params->pointer() : NULL));
}
} else {
- OMX_U8 *data = static_cast<OMX_U8 *>(params->pointer());
+ OMX_U8 *data = NULL;
// metadata buffers are not connected cross process
// use a backup buffer instead of the actual buffer
if (isMetadata) {
+ // TODO: this logic is very fishy, should it be removed?
// if we are not connecting the buffers, the sizes must match
- if (allottedSize != params->size()) {
+ if (params != NULL && allottedSize != params->size()) {
CLOG_ERROR(useBuffer, BAD_VALUE, SIMPLE_BUFFER(portIndex, (size_t)allottedSize, data));
return BAD_VALUE;
}
@@ -960,6 +984,10 @@
buffer_meta = new BufferMeta(
params, portIndex, false /* copy */, data);
} else {
+ // NULL params is allowed only in metadata mode.
+ CHECK(params != NULL);
+ data = static_cast<OMX_U8 *>(params->pointer());
+
buffer_meta = new BufferMeta(
params, portIndex, false /* copy */, NULL);
}
@@ -1064,6 +1092,13 @@
}
Mutex::Autolock autoLock(mLock);
+ // First, see if we're in metadata mode. We could be running an experiment to simulate
+ // legacy behavior (preallocated buffers) on devices that supports meta.
+ if (mMetadataType[portIndex] != kMetadataBufferTypeInvalid) {
+ return useGraphicBufferWithMetadata_l(
+ portIndex, graphicBuffer, buffer);
+ }
+
// See if the newer version of the extension is present.
OMX_INDEXTYPE index;
if (OMX_GetExtensionIndex(
@@ -1119,6 +1154,33 @@
return OK;
}
+status_t OMXNodeInstance::useGraphicBufferWithMetadata_l(
+ OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
+ OMX::buffer_id *buffer) {
+ if (portIndex != kPortIndexOutput) {
+ return BAD_VALUE;
+ }
+
+ OMX_U32 allottedSize = 0;
+ if (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource) {
+ allottedSize = sizeof(VideoGrallocMetadata);
+ } else if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer) {
+ allottedSize = sizeof(VideoNativeMetadata);
+ } else {
+ return BAD_VALUE;
+ }
+
+ status_t err = useBuffer_l(portIndex, NULL, buffer, allottedSize);
+ if (err != OK) {
+ return err;
+ }
+
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(*buffer, portIndex);
+
+ return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, *buffer, header);
+
+}
+
status_t OMXNodeInstance::updateGraphicBufferInMeta_l(
OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) {
@@ -1159,20 +1221,9 @@
return OK;
}
-status_t OMXNodeInstance::updateGraphicBufferInMeta(
- OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
- OMX::buffer_id buffer) {
- Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, portIndex);
-
- 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, portIndex);
+status_t OMXNodeInstance::updateNativeHandleInMeta_l(
+ OMX_U32 portIndex, const sp<NativeHandle>& nativeHandle,
+ OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) {
// No need to check |nativeHandle| since NULL is valid for it as below.
if (header == NULL) {
ALOGE("b/25884056");
@@ -1340,7 +1391,8 @@
return StatusFromOMXError(err);
}
-status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer, int fenceFd) {
+status_t OMXNodeInstance::fillBuffer(
+ OMX::buffer_id buffer, const OMXBuffer &omxBuffer, int fenceFd) {
Mutex::Autolock autoLock(mLock);
OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexOutput);
@@ -1348,6 +1400,20 @@
ALOGE("b/25884056");
return BAD_VALUE;
}
+
+ if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
+ status_t err = updateGraphicBufferInMeta_l(
+ kPortIndexOutput, omxBuffer.mGraphicBuffer, buffer, header);
+
+ if (err != OK) {
+ CLOG_ERROR(fillBuffer, err, FULL_BUFFER(
+ (intptr_t)header->pBuffer, header, fenceFd));
+ return err;
+ }
+ } else if (omxBuffer.mBufferType != OMXBuffer::kBufferTypePreset) {
+ return BAD_VALUE;
+ }
+
header->nFilledLen = 0;
header->nOffset = 0;
header->nFlags = 0;
@@ -1375,6 +1441,27 @@
}
status_t OMXNodeInstance::emptyBuffer(
+ buffer_id buffer, const OMXBuffer &omxBuffer,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
+ if (omxBuffer.mBufferType == OMXBuffer::kBufferTypePreset) {
+ return emptyBuffer(
+ buffer, 0, omxBuffer.mRangeLength, flags, timestamp, fenceFd);
+ }
+
+ if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
+ return emptyGraphicBuffer(
+ buffer, omxBuffer.mGraphicBuffer, flags, timestamp, fenceFd);
+ }
+
+ if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeNativeHandle) {
+ return emptyNativeHandleBuffer(
+ buffer, omxBuffer.mNativeHandle, flags, timestamp, fenceFd);
+ }
+
+ return BAD_VALUE;
+}
+
+status_t OMXNodeInstance::emptyBuffer(
OMX::buffer_id buffer,
OMX_U32 rangeOffset, OMX_U32 rangeLength,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
@@ -1601,6 +1688,31 @@
return timestamp;
}
+status_t OMXNodeInstance::emptyNativeHandleBuffer(
+ OMX::buffer_id buffer, const sp<NativeHandle> &nativeHandle,
+ OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
+ Mutex::Autolock autoLock(mLock);
+
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
+ if (header == NULL) {
+ ALOGE("b/25884056");
+ return BAD_VALUE;
+ }
+
+ status_t err = updateNativeHandleInMeta_l(
+ kPortIndexInput, nativeHandle, buffer, header);
+ if (err != OK) {
+ CLOG_ERROR(emptyNativeHandleBuffer, err, FULL_BUFFER(
+ (intptr_t)header->pBuffer, header, fenceFd));
+ return err;
+ }
+
+ header->nOffset = 0;
+ header->nFilledLen = (nativeHandle == NULL) ? 0 : sizeof(VideoNativeMetadata);
+
+ return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer, fenceFd);
+}
+
void OMXNodeInstance::codecBufferFilled(omx_message &msg) {
Mutex::Autolock autoLock(mBufferIDLock);
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index ea99e53..935d7bf 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -38,6 +38,7 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/SimpleDecodingSource.h>
+#include <media/OMXBuffer.h>
#define DEFAULT_TIMEOUT 500000
@@ -210,8 +211,7 @@
buffer.mFlags = 0;
CHECK(buffer.mMemory != NULL);
- err = mOMXNode->useBuffer(
- portIndex, buffer.mMemory, &buffer.mID, buffer.mMemory->size());
+ err = mOMXNode->useBuffer(portIndex, buffer.mMemory, &buffer.mID);
EXPECT_SUCCESS(err, "useBuffer");
buffers->push(buffer);
@@ -338,7 +338,7 @@
"executing state.");
for (size_t i = 0; i < outputBuffers.size(); ++i) {
- err = mOMXNode->fillBuffer(outputBuffers[i].mID);
+ err = mOMXNode->fillBuffer(outputBuffers[i].mID, OMXBuffer::sPreset);
EXPECT_SUCCESS(err, "fillBuffer");
outputBuffers.editItemAt(i).mFlags |= kBufferBusy;
@@ -363,7 +363,7 @@
}
for (size_t i = 0; i < outputBuffers.size(); ++i) {
- err = mOMXNode->fillBuffer(outputBuffers[i].mID);
+ err = mOMXNode->fillBuffer(outputBuffers[i].mID, OMXBuffer::sPreset);
EXPECT_SUCCESS(err, "fillBuffer");
outputBuffers.editItemAt(i).mFlags |= kBufferBusy;