Merge changes I58b03acd,I7d7eb086 into nyc-dev
am: 0d0a8b48d2
* commit '0d0a8b48d267a1980cfd9507b51d173756835f34':
stagefright: untangle metadata-mode handling
stagefright: add a way to update native handle in OMX buffers
Change-Id: I857573724b0a4f7b38832777b12caa8666ac210b
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index e5fbba0..9e15a81 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -39,7 +39,8 @@
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
- $(TOP)/frameworks/native/include/media/openmax
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/native/include/media/hardware
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_CLANG := true
@@ -63,7 +64,8 @@
LOCAL_C_INCLUDES:= \
frameworks/av/media/libstagefright \
- $(TOP)/frameworks/native/include/media/openmax
+ $(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/native/include/media/hardware
LOCAL_CFLAGS += -Wno-multichar -Werror -Wall
LOCAL_CLANG := true
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 19c7955..673c56a 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(
@@ -272,17 +276,18 @@
OMX_U32 mLevel;
};
-} // namespace android
-
-inline static const char *asString(android::MetadataBufferType i, const char *def = "??") {
+inline static const char *asString(MetadataBufferType i, const char *def = "??") {
using namespace android;
switch (i) {
case kMetadataBufferTypeCameraSource: return "CameraSource";
case kMetadataBufferTypeGrallocSource: return "GrallocSource";
case kMetadataBufferTypeANWBuffer: return "ANWBuffer";
+ case kMetadataBufferTypeNativeHandleSource: return "NativeHandleSource";
case kMetadataBufferTypeInvalid: return "Invalid";
default: return def;
}
}
+} // namespace android
+
#endif // ANDROID_IOMX_H_
diff --git a/include/media/stagefright/CameraSource.h b/include/media/stagefright/CameraSource.h
index 399f363..c2e75a6 100644
--- a/include/media/stagefright/CameraSource.h
+++ b/include/media/stagefright/CameraSource.h
@@ -28,6 +28,7 @@
#include <utils/List.h>
#include <utils/RefBase.h>
#include <utils/String16.h>
+#include <MetadataBufferType.h>
namespace android {
@@ -118,11 +119,11 @@
* Tell whether this camera source stores meta data or real YUV
* frame data in video buffers.
*
- * @return true if meta data is stored in the video
- * buffers; false if real YUV data is stored in
+ * @return a valid type if meta data is stored in the video
+ * buffers; kMetadataBufferTypeInvalid if real YUV data is stored in
* the video buffers.
*/
- bool isMetaDataStoredInVideoBuffers() const;
+ MetadataBufferType metaDataStoredInVideoBuffers() const;
virtual void signalBufferReturned(MediaBuffer* buffer);
diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h
index 035e8ae..cc62786 100644
--- a/include/media/stagefright/MediaCodecSource.h
+++ b/include/media/stagefright/MediaCodecSource.h
@@ -37,7 +37,6 @@
public MediaBufferObserver {
enum FlagBits {
FLAG_USE_SURFACE_INPUT = 1,
- FLAG_USE_METADATA_INPUT = 2,
FLAG_PREFER_SOFTWARE_CODEC = 4, // used for testing only
};
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index 2177c00..ca3a3bf 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -25,6 +25,8 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MediaBuffer.h>
+#include <MetadataBufferType.h>
+
#include "foundation/ABase.h"
namespace android {
@@ -109,9 +111,9 @@
void dump(String8& result, const char* prefix, char* buffer,
size_t SIZE) const;
- // isMetaDataStoredInVideoBuffers tells the encoder whether we will
- // pass metadata through the buffers. Currently, it is force set to true
- bool isMetaDataStoredInVideoBuffers() const;
+ // metaDataStoredInVideoBuffers tells the encoder what kind of metadata
+ // is passed through the buffers. Currently, it is set to ANWBuffer
+ MetadataBufferType metaDataStoredInVideoBuffers() const;
sp<IGraphicBufferProducer> getProducer() const { return mProducer; }
@@ -234,6 +236,9 @@
Condition mMediaBuffersAvailableCondition;
+ // Allocate and return a new MediaBuffer and pass the ANW buffer as metadata into it.
+ void passMetadataBuffer_l(MediaBuffer **buffer, ANativeWindowBuffer *bufferHandle) const;
+
// Avoid copying and equating and default constructor
DISALLOW_EVIL_CONSTRUCTORS(SurfaceMediaSource);
};
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index daffb48..797a5f7 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) {
@@ -416,7 +436,9 @@
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
data.writeInt32((int32_t)node);
data.writeInt32(port_index);
- data.writeInt32((uint32_t)enable);
+ data.writeInt32((int32_t)enable);
+ data.writeInt32(type == NULL ? kMetadataBufferTypeANWBuffer : *type);
+
remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
// read type even storeMetaDataInBuffers failed
@@ -908,6 +930,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);
@@ -1001,7 +1042,7 @@
OMX_U32 port_index = data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
- MetadataBufferType type = kMetadataBufferTypeInvalid;
+ MetadataBufferType type = (MetadataBufferType)data.readInt32();
status_t err = storeMetaDataInBuffers(node, port_index, enable, &type);
reply->writeInt32(type);
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index f6a6f83..31a6992 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -53,6 +53,7 @@
$(TOP)/frameworks/av/include/media \
$(TOP)/frameworks/av/include/camera \
$(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/native/include/media/hardware \
$(TOP)/external/tremolo/Tremolo \
libcore/include \
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 3f7367f..6114af8 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1474,8 +1474,8 @@
CHECK(mFrameRate != -1);
- mIsMetaDataStoredInVideoBuffers =
- (*cameraSource)->isMetaDataStoredInVideoBuffers();
+ mMetaDataStoredInVideoBuffers =
+ (*cameraSource)->metaDataStoredInVideoBuffers();
return OK;
}
@@ -1565,11 +1565,11 @@
format->setFloat("operating-rate", mCaptureFps);
}
- uint32_t flags = 0;
- if (mIsMetaDataStoredInVideoBuffers) {
- flags |= MediaCodecSource::FLAG_USE_METADATA_INPUT;
+ if (mMetaDataStoredInVideoBuffers != kMetadataBufferTypeInvalid) {
+ format->setInt32("android._input-metadata-buffer-type", mMetaDataStoredInVideoBuffers);
}
+ uint32_t flags = 0;
if (cameraSource == NULL) {
flags |= MediaCodecSource::FLAG_USE_SURFACE_INPUT;
} else {
@@ -1866,7 +1866,7 @@
mCaptureFps = 0.0f;
mTimeBetweenCaptureUs = -1;
mCameraSourceTimeLapse = NULL;
- mIsMetaDataStoredInVideoBuffers = false;
+ mMetaDataStoredInVideoBuffers = kMetadataBufferTypeInvalid;
mEncoderProfiles = MediaProfiles::getInstance();
mRotationDegrees = 0;
mLatitudex10000 = -3600000;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index a73197f..d7f43bc 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -24,6 +24,8 @@
#include <system/audio.h>
+#include <MetadataBufferType.h>
+
namespace android {
class Camera;
@@ -121,7 +123,7 @@
String8 mParams;
- bool mIsMetaDataStoredInVideoBuffers;
+ MetadataBufferType mMetaDataStoredInVideoBuffers;
MediaProfiles *mEncoderProfiles;
int64_t mPauseStartTimeUs;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 3841876..27c1a64 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -794,10 +794,10 @@
MetadataBufferType type =
portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
size_t bufSize = def.nBufferSize;
- if (type == kMetadataBufferTypeGrallocSource) {
- bufSize = sizeof(VideoGrallocMetadata);
- } else if (type == kMetadataBufferTypeANWBuffer) {
+ if (type == kMetadataBufferTypeANWBuffer) {
bufSize = sizeof(VideoNativeMetadata);
+ } else if (type == kMetadataBufferTypeNativeHandleSource) {
+ bufSize = sizeof(VideoNativeHandleMetadata);
}
// If using gralloc or native source input metadata buffers, allocate largest
@@ -805,7 +805,7 @@
// may require gralloc source. For camera source, allocate at least enough
// size for native metadata buffers.
size_t allottedSize = bufSize;
- if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) {
+ if (portIndex == kPortIndexInput && type == kMetadataBufferTypeANWBuffer) {
bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
} else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
bufSize = max(bufSize, sizeof(VideoNativeMetadata));
@@ -1726,19 +1726,20 @@
int32_t storeMeta;
if (encoder
- && msg->findInt32("store-metadata-in-buffers", &storeMeta)
- && storeMeta != 0) {
- err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
+ && msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
+ && storeMeta != kMetadataBufferTypeInvalid) {
+ mInputMetadataType = (MetadataBufferType)storeMeta;
+ err = mOMX->storeMetaDataInBuffers(
+ mNode, kPortIndexInput, OMX_TRUE, &mInputMetadataType);
if (err != OK) {
ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
mComponentName.c_str(), err);
return err;
- }
- // For this specific case we could be using camera source even if storeMetaDataInBuffers
- // returns Gralloc source. Pretend that we are; this will force us to use nBufferSize.
- if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
- mInputMetadataType = kMetadataBufferTypeCameraSource;
+ } else if (storeMeta == kMetadataBufferTypeANWBuffer
+ && mInputMetadataType == kMetadataBufferTypeGrallocSource) {
+ // IOMX translates ANWBuffers to gralloc source already.
+ mInputMetadataType = (MetadataBufferType)storeMeta;
}
uint32_t usageBits;
@@ -1784,9 +1785,10 @@
mIsVideo = video;
if (encoder && video) {
OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
- && msg->findInt32("store-metadata-in-buffers-output", &storeMeta)
+ && msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
&& storeMeta != 0);
+ mOutputMetadataType = kMetadataBufferTypeNativeHandleSource;
err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, enable, &mOutputMetadataType);
if (err != OK) {
ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
@@ -1915,6 +1917,7 @@
}
// Always try to enable dynamic output buffers on native surface
+ mOutputMetadataType = kMetadataBufferTypeANWBuffer;
err = mOMX->storeMetaDataInBuffers(
mNode, kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
if (err != OK) {
@@ -5967,18 +5970,15 @@
if (mCodec->usingMetadataOnEncoderOutput()) {
native_handle_t *handle = NULL;
- VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)info->mData->data();
- VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)info->mData->data();
- if (info->mData->size() >= sizeof(grallocMeta)
- && grallocMeta.eType == kMetadataBufferTypeGrallocSource) {
- handle = (native_handle_t *)(uintptr_t)grallocMeta.pHandle;
- } else if (info->mData->size() >= sizeof(nativeMeta)
- && nativeMeta.eType == kMetadataBufferTypeANWBuffer) {
+ VideoNativeHandleMetadata &nativeMeta =
+ *(VideoNativeHandleMetadata *)info->mData->data();
+ if (info->mData->size() >= sizeof(nativeMeta)
+ && nativeMeta.eType == kMetadataBufferTypeNativeHandleSource) {
#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
- // ANativeWindowBuffer is only valid on 32-bit/mediaserver process
+ // handle is only valid on 32-bit/mediaserver process
handle = NULL;
#else
- handle = (native_handle_t *)nativeMeta.pBuffer->handle;
+ handle = (native_handle_t *)nativeMeta.pHandle;
#endif
}
info->mData->meta()->setPointer("handle", handle);
@@ -6665,8 +6665,14 @@
sp<IGraphicBufferProducer> bufferProducer;
if (err == OK) {
+ mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
err = mCodec->mOMX->createInputSurface(
- mCodec->mNode, kPortIndexInput, dataSpace, &bufferProducer, &mCodec->mInputMetadataType);
+ mCodec->mNode, kPortIndexInput, dataSpace, &bufferProducer,
+ &mCodec->mInputMetadataType);
+ // framework uses ANW buffers internally instead of gralloc handles
+ if (mCodec->mInputMetadataType == kMetadataBufferTypeGrallocSource) {
+ mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
+ }
}
if (err == OK) {
@@ -6705,9 +6711,14 @@
notify->setMessage("output-format", mCodec->mOutputFormat);
if (err == OK) {
+ mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
err = mCodec->mOMX->setInputSurface(
mCodec->mNode, kPortIndexInput, surface->getBufferConsumer(),
&mCodec->mInputMetadataType);
+ // framework uses ANW buffers internally instead of gralloc handles
+ if (mCodec->mInputMetadataType == kMetadataBufferTypeGrallocSource) {
+ mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
+ }
}
if (err == OK) {
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index e213581..5fc9237 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -1244,13 +1244,19 @@
mFrameAvailableCondition.signal();
}
-bool CameraSource::isMetaDataStoredInVideoBuffers() const {
- ALOGV("isMetaDataStoredInVideoBuffers");
+MetadataBufferType CameraSource::metaDataStoredInVideoBuffers() const {
+ ALOGV("metaDataStoredInVideoBuffers");
// Output buffers will contain metadata if camera sends us buffer in metadata mode or via
// buffer queue.
- return (mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA ||
- mVideoBufferMode == hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE);
+ switch (mVideoBufferMode) {
+ case hardware::ICamera::VIDEO_BUFFER_MODE_DATA_CALLBACK_METADATA:
+ return kMetadataBufferTypeNativeHandleSource;
+ case hardware::ICamera::VIDEO_BUFFER_MODE_BUFFER_QUEUE:
+ return kMetadataBufferTypeANWBuffer;
+ default:
+ return kMetadataBufferTypeInvalid;
+ }
}
CameraSource::ProxyListener::ProxyListener(const sp<CameraSource>& source) {
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index f77d762..d7cf1e9 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -449,10 +449,6 @@
mCodecLooper->setName("codec_looper");
mCodecLooper->start();
- if (mFlags & FLAG_USE_METADATA_INPUT) {
- mOutputFormat->setInt32("store-metadata-in-buffers", 1);
- }
-
if (mFlags & FLAG_USE_SURFACE_INPUT) {
mOutputFormat->setInt32("create-input-buffers-suspended", 1);
}
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/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index e4bf67a..15ff569 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -23,6 +23,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <OMX_IVCommon.h>
+#include <media/hardware/HardwareAPI.h>
#include <media/hardware/MetadataBufferType.h>
#include <ui/GraphicBuffer.h>
@@ -126,9 +127,9 @@
return OK;
}
-bool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const {
+MetadataBufferType SurfaceMediaSource::metaDataStoredInVideoBuffers() const {
ALOGV("isMetaDataStoredInVideoBuffers");
- return true;
+ return kMetadataBufferTypeANWBuffer;
}
int32_t SurfaceMediaSource::getFrameRate( ) const {
@@ -250,29 +251,19 @@
}
// Pass the data to the MediaBuffer. Pass in only the metadata
-// The metadata passed consists of two parts:
-// 1. First, there is an integer indicating that it is a GRAlloc
-// source (kMetadataBufferTypeGrallocSource)
-// 2. This is followed by the buffer_handle_t that is a handle to the
-// GRalloc buffer. The encoder needs to interpret this GRalloc handle
-// and encode the frames.
-// --------------------------------------------------------------
-// | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
-// --------------------------------------------------------------
// Note: Call only when you have the lock
-static void passMetadataBuffer(MediaBuffer **buffer,
- buffer_handle_t bufferHandle) {
- *buffer = new MediaBuffer(4 + sizeof(buffer_handle_t));
- char *data = (char *)(*buffer)->data();
+void SurfaceMediaSource::passMetadataBuffer_l(MediaBuffer **buffer,
+ ANativeWindowBuffer *bufferHandle) const {
+ *buffer = new MediaBuffer(sizeof(VideoNativeMetadata));
+ VideoNativeMetadata *data = (VideoNativeMetadata *)(*buffer)->data();
if (data == NULL) {
ALOGE("Cannot allocate memory for metadata buffer!");
return;
}
- OMX_U32 type = kMetadataBufferTypeGrallocSource;
- memcpy(data, &type, 4);
- memcpy(data + 4, &bufferHandle, sizeof(buffer_handle_t));
-
- ALOGV("handle = %p, , offset = %zu, length = %zu",
+ data->eType = metaDataStoredInVideoBuffers();
+ data->pBuffer = bufferHandle;
+ data->nFenceFd = -1;
+ ALOGV("handle = %p, offset = %zu, length = %zu",
bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
}
@@ -361,7 +352,7 @@
mNumFramesEncoded++;
// Pass the data to the MediaBuffer. Pass in only the metadata
- passMetadataBuffer(buffer, mSlots[mCurrentSlot].mGraphicBuffer->handle);
+ passMetadataBuffer_l(buffer, mSlots[mCurrentSlot].mGraphicBuffer->getNativeBuffer());
(*buffer)->setObserver(this);
(*buffer)->add_ref();
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 4cc857e..7121ac4 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 e23ceed..70c5cb1 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;
@@ -523,6 +529,9 @@
OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) {
if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) {
android_errorWriteLog(0x534e4554, "26324358");
+ if (type != NULL) {
+ *type = kMetadataBufferTypeInvalid;
+ }
return BAD_VALUE;
}
@@ -533,26 +542,32 @@
OMX_STRING nativeBufferName = const_cast<OMX_STRING>(
"OMX.google.android.index.storeANWBufferInMetadata");
MetadataBufferType negotiatedType;
+ MetadataBufferType requestedType = type != NULL ? *type : kMetadataBufferTypeANWBuffer;
StoreMetaDataInBuffersParams params;
InitOMXParams(¶ms);
params.nPortIndex = portIndex;
params.bStoreMetaData = enable;
- OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, nativeBufferName, &index);
+ OMX_ERRORTYPE err =
+ requestedType == kMetadataBufferTypeANWBuffer
+ ? OMX_GetExtensionIndex(mHandle, nativeBufferName, &index)
+ : OMX_ErrorUnsupportedIndex;
OMX_ERRORTYPE xerr = err;
if (err == OMX_ErrorNone) {
err = OMX_SetParameter(mHandle, index, ¶ms);
if (err == OMX_ErrorNone) {
name = nativeBufferName; // set name for debugging
- negotiatedType = kMetadataBufferTypeANWBuffer;
+ negotiatedType = requestedType;
}
}
if (err != OMX_ErrorNone) {
err = OMX_GetExtensionIndex(mHandle, name, &index);
xerr = err;
if (err == OMX_ErrorNone) {
- negotiatedType = kMetadataBufferTypeGrallocSource;
+ negotiatedType =
+ requestedType == kMetadataBufferTypeANWBuffer
+ ? kMetadataBufferTypeGrallocSource : requestedType;
err = OMX_SetParameter(mHandle, index, ¶ms);
}
}
@@ -574,8 +589,9 @@
}
mMetadataType[portIndex] = negotiatedType;
}
- CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u negotiated %s:%d",
- portString(portIndex), portIndex, asString(negotiatedType), negotiatedType);
+ CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u %srequested %s:%d negotiated %s:%d",
+ portString(portIndex), portIndex, enable ? "" : "UN",
+ asString(requestedType), requestedType, asString(negotiatedType), negotiatedType);
if (type != NULL) {
*type = negotiatedType;
@@ -871,6 +887,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;
@@ -884,6 +937,9 @@
}
// Input buffers will hold meta-data (ANativeWindowBuffer references).
+ if (type != NULL) {
+ *type = kMetadataBufferTypeANWBuffer;
+ }
err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, type);
if (err != OK) {
return err;
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
index 111e6c5..d1c9d36 100644
--- a/media/libstagefright/tests/Android.mk
+++ b/media/libstagefright/tests/Android.mk
@@ -30,6 +30,7 @@
frameworks/av/media/libstagefright \
frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/native/include/media/hardware \
LOCAL_CFLAGS += -Werror -Wall
LOCAL_CLANG := true
diff --git a/media/libstagefright/wifi-display/Android.mk b/media/libstagefright/wifi-display/Android.mk
index 5bd6e5c..ae4ac90 100644
--- a/media/libstagefright/wifi-display/Android.mk
+++ b/media/libstagefright/wifi-display/Android.mk
@@ -17,6 +17,7 @@
LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/av/media/libstagefright \
$(TOP)/frameworks/native/include/media/openmax \
+ $(TOP)/frameworks/native/include/media/hardware \
$(TOP)/frameworks/av/media/libstagefright/mpeg2ts \
LOCAL_SHARED_LIBRARIES:= \
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 3ecb52b..3587cb9 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -948,8 +948,9 @@
if (isVideo) {
format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
- format->setInt32("store-metadata-in-buffers", true);
- format->setInt32("store-metadata-in-buffers-output", (mHDCP != NULL)
+ format->setInt32(
+ "android._input-metadata-buffer-type", kMetadataBufferTypeANWBuffer);
+ format->setInt32("android._store-metadata-in-buffers-output", (mHDCP != NULL)
&& (mHDCP->getCaps() & HDCPModule::HDCP_CAPS_ENCRYPT_NATIVE));
format->setInt32(
"color-format", OMX_COLOR_FormatAndroidOpaque);