IOMX: add API for setPortMode
- Add setPortMode to centralize port mode configuration
- Remove storeMetaDataInBuffers and enableNativeBuffers. These are
no longer exposed to the client. Metadata mode and native/secure
buffer mode will be enabled by OMX as needed by the port mode.
- Move handling of legacy adpative experiment (legacy metadata mode)
to OMX side. Legacy mode will now appear the same as non-metadata
mode to client.
bug: 31399200
Change-Id: Iaf33bd7c30fab4acbc19e9fb8c19e322f9b4a0a0
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 839945c..ec1d4b6 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -52,6 +52,20 @@
kFenceTimeoutMs = 1000
};
+ enum PortMode {
+ kPortModePresetStart = 0,
+ kPortModePresetByteBuffer,
+ kPortModePresetANWBuffer,
+ kPortModePresetSecureBuffer,
+ kPortModePresetEnd,
+
+ kPortModeDynamicStart = 100,
+ kPortModeDynamicANWBuffer, // uses metadata mode kMetadataBufferTypeANWBuffer
+ // or kMetadataBufferTypeGrallocSource
+ kPortModeDynamicNativeHandle, // uses metadata mode kMetadataBufferTypeNativeHandleSource
+ kPortModeDynamicEnd,
+ };
+
struct ComponentInfo {
String8 mName;
List<String8> mRoles;
@@ -90,10 +104,8 @@
virtual status_t setConfig(
OMX_INDEXTYPE index, const void *params, size_t size) = 0;
- // This will set *type to previous metadata buffer type on OMX error (not on binder error), and
- // new metadata buffer type on success.
- virtual status_t storeMetaDataInBuffers(
- OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type = NULL) = 0;
+ virtual status_t setPortMode(
+ OMX_U32 port_index, IOMX::PortMode mode) = 0;
virtual status_t prepareForAdaptivePlayback(
OMX_U32 portIndex, OMX_BOOL enable,
@@ -103,9 +115,6 @@
OMX_U32 portIndex, OMX_BOOL tunneled,
OMX_U32 audioHwSync, native_handle_t **sidebandHandle) = 0;
- virtual status_t enableNativeBuffers(
- OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) = 0;
-
virtual status_t getGraphicBufferUsage(
OMX_U32 port_index, OMX_U32* usage) = 0;
@@ -241,23 +250,6 @@
uint32_t flags = 0);
};
-struct CodecProfileLevel {
- OMX_U32 mProfile;
- OMX_U32 mLevel;
-};
-
-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/OMXBuffer.h b/include/media/OMXBuffer.h
index 0322b73..89b709c 100644
--- a/include/media/OMXBuffer.h
+++ b/include/media/OMXBuffer.h
@@ -44,7 +44,7 @@
OMXBuffer(const sp<MediaCodecBuffer> &codecBuffer);
// Constructs a buffer of type kBufferTypeSharedMem.
- OMXBuffer(const sp<IMemory> &mem, size_t allottedSize = 0);
+ OMXBuffer(const sp<IMemory> &mem);
// Constructs a buffer of type kBufferTypeANWBuffer.
OMXBuffer(const sp<GraphicBuffer> &gbuf);
@@ -78,7 +78,6 @@
// kBufferTypeSharedMem
sp<IMemory> mMem;
- OMX_U32 mAllottedSize;
// kBufferTypeANWBuffer
sp<GraphicBuffer> mGraphicBuffer;
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 13ceeb6..8fc2809 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -277,9 +277,7 @@
bool mChannelMaskPresent;
int32_t mChannelMask;
unsigned mDequeueCounter;
- MetadataBufferType mInputMetadataType;
- MetadataBufferType mOutputMetadataType;
- bool mLegacyAdaptiveExperiment;
+ IOMX::PortMode mPortMode[2];
int32_t mMetadataBuffersToSubmit;
size_t mNumUndequeuedBuffers;
sp<DataConverter> mConverter[2];
@@ -303,6 +301,7 @@
status_t freeBuffer(OMX_U32 portIndex, size_t i);
status_t handleSetSurface(const sp<Surface> &surface);
+ status_t setPortMode(int32_t portIndex, IOMX::PortMode mode);
status_t setupNativeWindowSizeFormatAndUsage(
ANativeWindow *nativeWindow /* nonnull */, int *finalUsage /* nonnull */,
bool reconnect);
@@ -319,11 +318,11 @@
BufferInfo *dequeueBufferFromNativeWindow();
inline bool storingMetadataInDecodedBuffers() {
- return mOutputMetadataType >= 0 && !mIsEncoder;
+ return (mPortMode[kPortIndexOutput] == IOMX::kPortModeDynamicANWBuffer) && !mIsEncoder;
}
- inline bool usingMetadataOnEncoderOutput() {
- return mOutputMetadataType >= 0 && mIsEncoder;
+ inline bool usingSecureBufferOnEncoderOutput() {
+ return (mPortMode[kPortIndexOutput] == IOMX::kPortModePresetSecureBuffer) && mIsEncoder;
}
BufferInfo *findBufferByID(
@@ -494,8 +493,6 @@
status_t setupErrorCorrectionParameters();
- status_t initNativeWindow();
-
// Returns true iff all buffers on the given port have status
// OWNED_BY_US or OWNED_BY_NATIVE_WINDOW.
bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 1a6d6b8..c1fe87f 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -37,19 +37,18 @@
CONNECT = IBinder::FIRST_CALL_TRANSACTION,
LIST_NODES,
ALLOCATE_NODE,
+ CREATE_INPUT_SURFACE,
FREE_NODE,
SEND_COMMAND,
GET_PARAMETER,
SET_PARAMETER,
GET_CONFIG,
SET_CONFIG,
- ENABLE_NATIVE_BUFFERS,
- USE_BUFFER,
- CREATE_INPUT_SURFACE,
+ SET_PORT_MODE,
SET_INPUT_SURFACE,
- STORE_META_DATA_IN_BUFFERS,
PREPARE_FOR_ADAPTIVE_PLAYBACK,
ALLOC_SECURE_BUFFER,
+ USE_BUFFER,
FREE_BUFFER,
FILL_BUFFER,
EMPTY_BUFFER,
@@ -225,17 +224,15 @@
return reply.readInt32();
}
- virtual status_t enableNativeBuffers(
- OMX_U32 port_index, OMX_BOOL graphic, OMX_BOOL enable) {
+ virtual status_t setPortMode(
+ OMX_U32 port_index, IOMX::PortMode mode) {
Parcel data, reply;
data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
data.writeInt32(port_index);
- data.writeInt32((uint32_t)graphic);
- data.writeInt32((uint32_t)enable);
- remote()->transact(ENABLE_NATIVE_BUFFERS, data, &reply);
+ data.writeInt32(mode);
+ remote()->transact(SET_PORT_MODE, data, &reply);
- status_t err = reply.readInt32();
- return err;
+ return reply.readInt32();
}
virtual status_t getGraphicBufferUsage(
@@ -294,25 +291,6 @@
return err;
}
- virtual status_t storeMetaDataInBuffers(
- OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) {
- Parcel data, reply;
- data.writeInterfaceToken(IOMXNode::getInterfaceDescriptor());
- data.writeInt32(port_index);
- 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
- int negotiatedType = reply.readInt32();
- if (type != NULL) {
- *type = (MetadataBufferType)negotiatedType;
- }
-
- return reply.readInt32();
- }
-
virtual status_t prepareForAdaptivePlayback(
OMX_U32 port_index, OMX_BOOL enable,
OMX_U32 max_width, OMX_U32 max_height) {
@@ -670,16 +648,12 @@
return NO_ERROR;
}
- case ENABLE_NATIVE_BUFFERS:
+ case SET_PORT_MODE:
{
CHECK_OMX_INTERFACE(IOMXNode, data, reply);
-
OMX_U32 port_index = data.readInt32();
- OMX_BOOL graphic = (OMX_BOOL)data.readInt32();
- OMX_BOOL enable = (OMX_BOOL)data.readInt32();
-
- status_t err = enableNativeBuffers(port_index, graphic, enable);
- reply->writeInt32(err);
+ IOMX::PortMode mode = (IOMX::PortMode) data.readInt32();
+ reply->writeInt32(setPortMode(port_index, mode));
return NO_ERROR;
}
@@ -734,22 +708,6 @@
return NO_ERROR;
}
- case STORE_META_DATA_IN_BUFFERS:
- {
- CHECK_OMX_INTERFACE(IOMXNode, data, reply);
-
- OMX_U32 port_index = data.readInt32();
- OMX_BOOL enable = (OMX_BOOL)data.readInt32();
-
- MetadataBufferType type = (MetadataBufferType)data.readInt32();
- status_t err = storeMetaDataInBuffers(port_index, enable, &type);
-
- reply->writeInt32(type);
- reply->writeInt32(err);
-
- return NO_ERROR;
- }
-
case PREPARE_FOR_ADAPTIVE_PLAYBACK:
{
CHECK_OMX_INTERFACE(IOMXNode, data, reply);
diff --git a/media/libmedia/OMXBuffer.cpp b/media/libmedia/OMXBuffer.cpp
index 0931872..2834853 100644
--- a/media/libmedia/OMXBuffer.cpp
+++ b/media/libmedia/OMXBuffer.cpp
@@ -38,10 +38,9 @@
mRangeLength(codecBuffer != NULL ? codecBuffer->size() : 0) {
}
-OMXBuffer::OMXBuffer(const sp<IMemory> &mem, size_t allottedSize)
+OMXBuffer::OMXBuffer(const sp<IMemory> &mem)
: mBufferType(kBufferTypeSharedMem),
- mMem(mem),
- mAllottedSize(allottedSize ? : mem->size()) {
+ mMem(mem) {
}
OMXBuffer::OMXBuffer(const sp<GraphicBuffer> &gbuf)
@@ -68,11 +67,7 @@
case kBufferTypeSharedMem:
{
- status_t err = parcel->writeStrongBinder(IInterface::asBinder(mMem));
- if (err != NO_ERROR) {
- return err;
- }
- return parcel->writeUint32(mAllottedSize);
+ return parcel->writeStrongBinder(IInterface::asBinder(mMem));
}
case kBufferTypeANWBuffer:
@@ -103,10 +98,7 @@
case kBufferTypeSharedMem:
{
- sp<IMemory> params = interface_cast<IMemory>(parcel->readStrongBinder());
-
- mMem = params;
- mAllottedSize = parcel->readUint32();
+ mMem = interface_cast<IMemory>(parcel->readStrongBinder());
break;
}
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 094f5cc..69db709 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -526,9 +526,6 @@
mChannelMaskPresent(false),
mChannelMask(0),
mDequeueCounter(0),
- mInputMetadataType(kMetadataBufferTypeInvalid),
- mOutputMetadataType(kMetadataBufferTypeInvalid),
- mLegacyAdaptiveExperiment(false),
mMetadataBuffersToSubmit(0),
mNumUndequeuedBuffers(0),
mRepeatFrameDelayUs(-1ll),
@@ -556,6 +553,9 @@
mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
mInputEOSResult = OK;
+ mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
+ mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
+
memset(&mLastNativeWindowCrop, 0, sizeof(mLastNativeWindowCrop));
changeState(mUninitializedState);
@@ -691,8 +691,7 @@
int usageBits = 0;
// no need to reconnect as we will not dequeue all buffers
status_t err = setupNativeWindowSizeFormatAndUsage(
- nativeWindow, &usageBits,
- !storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment /* reconnect */);
+ nativeWindow, &usageBits, !storingMetadataInDecodedBuffers());
if (err != OK) {
return err;
}
@@ -742,7 +741,6 @@
const BufferInfo &info = buffers[i];
// skip undequeued buffers for meta data mode
if (storingMetadataInDecodedBuffers()
- && !mLegacyAdaptiveExperiment
&& info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
ALOGV("skipping buffer");
continue;
@@ -759,7 +757,7 @@
}
// cancel undequeued buffers to new surface
- if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
+ if (!storingMetadataInDecodedBuffers()) {
for (size_t i = 0; i < buffers.size(); ++i) {
BufferInfo &info = buffers.editItemAt(i);
if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
@@ -789,6 +787,21 @@
return OK;
}
+status_t ACodec::setPortMode(int32_t portIndex, IOMX::PortMode mode) {
+ status_t err = mOMXNode->setPortMode(portIndex, mode);
+ if (err != OK) {
+ ALOGE("[%s] setPortMode on %s to %s failed w/ err %d",
+ mComponentName.c_str(),
+ portIndex == kPortIndexInput ? "input" : "output",
+ asString(mode),
+ err);
+ return err;
+ }
+
+ mPortMode[portIndex] = mode;
+ return OK;
+}
+
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
@@ -797,7 +810,7 @@
status_t err;
if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
- if (storingMetadataInDecodedBuffers() && !mLegacyAdaptiveExperiment) {
+ if (storingMetadataInDecodedBuffers()) {
err = allocateOutputMetadataBuffers();
} else {
err = allocateOutputBuffersFromNativeWindow();
@@ -811,26 +824,17 @@
OMX_IndexParamPortDefinition, &def, sizeof(def));
if (err == OK) {
- MetadataBufferType type =
- portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
+ const IOMX::PortMode &mode = mPortMode[portIndex];
size_t bufSize = def.nBufferSize;
- if (type == kMetadataBufferTypeANWBuffer) {
+ // Always allocate VideoNativeMetadata if using ANWBuffer.
+ // OMX might use gralloc source internally, but we don't share
+ // metadata buffer with OMX, OMX has its own headers.
+ if (mode == IOMX::kPortModeDynamicANWBuffer) {
bufSize = sizeof(VideoNativeMetadata);
- } else if (type == kMetadataBufferTypeNativeHandleSource) {
+ } else if (mode == IOMX::kPortModeDynamicNativeHandle) {
bufSize = sizeof(VideoNativeHandleMetadata);
}
- // If using gralloc or native source input metadata buffers, allocate largest
- // metadata size as we prefer to generate native source metadata, but component
- // may require gralloc source. For camera source, allocate at least enough
- // size for native metadata buffers.
- size_t allottedSize = bufSize;
- if (portIndex == kPortIndexInput && type == kMetadataBufferTypeANWBuffer) {
- bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
- } else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
- bufSize = max(bufSize, sizeof(VideoNativeMetadata));
- }
-
size_t conversionBufferSize = 0;
sp<DataConverter> converter = mConverter[portIndex];
@@ -845,9 +849,9 @@
size_t alignment = MemoryDealer::getAllocationAlignment();
- ALOGV("[%s] Allocating %u buffers of size %zu/%zu (from %u using %s) on %s port",
+ ALOGV("[%s] Allocating %u buffers of size %zu (from %u using %s) on %s port",
mComponentName.c_str(),
- def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
+ def.nBufferCountActual, bufSize, def.nBufferSize, asString(mode),
portIndex == kPortIndexInput ? "input" : "output");
// verify buffer sizes to avoid overflow in align()
@@ -865,24 +869,21 @@
}
size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
- mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
+ if (mode != IOMX::kPortModePresetSecureBuffer) {
+ mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
+ }
const sp<AMessage> &format =
portIndex == kPortIndexInput ? mInputFormat : mOutputFormat;
for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
- sp<IMemory> mem = mDealer[portIndex]->allocate(bufSize);
- if (mem == NULL || mem->pointer() == NULL) {
- return NO_MEMORY;
- }
+ sp<IMemory> mem;
BufferInfo info;
info.mStatus = BufferInfo::OWNED_BY_US;
info.mFenceFd = -1;
info.mRenderInfo = NULL;
- if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
- mem.clear();
-
+ if (mode == IOMX::kPortModePresetSecureBuffer) {
void *ptr = NULL;
sp<NativeHandle> native_handle;
err = mOMXNode->allocateSecureBuffer(
@@ -894,18 +895,20 @@
: new SecureBuffer(format, native_handle, bufSize);
info.mCodecData = info.mData;
} else {
- err = mOMXNode->useBuffer(portIndex,
- OMXBuffer(mem, allottedSize), &info.mBufferID);
- }
+ mem = mDealer[portIndex]->allocate(bufSize);
+ if (mem == NULL || mem->pointer() == NULL) {
+ return NO_MEMORY;
+ }
- if (mem != NULL) {
- info.mCodecData = new SharedMemoryBuffer(format, mem);
- info.mCodecRef = mem;
+ err = mOMXNode->useBuffer(portIndex, mem, &info.mBufferID);
- if (type == kMetadataBufferTypeANWBuffer) {
+ if (mode == IOMX::kPortModeDynamicANWBuffer) {
((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
}
+ info.mCodecData = new SharedMemoryBuffer(format, mem);
+ info.mCodecRef = mem;
+
// if we require conversion, allocate conversion buffer for client use;
// otherwise, reuse codec buffer
if (mConverter[portIndex] != NULL) {
@@ -1086,10 +1089,9 @@
}
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);
+ // This method only handles the non-metadata mode (or simulating legacy
+ // mode with metadata, which is transparent to ACodec).
+ CHECK(!storingMetadataInDecodedBuffers());
OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
status_t err = configureOutputBuffersFromNativeWindow(
@@ -1126,10 +1128,8 @@
// 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;
- }
+ info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
+ info.mCodecData = info.mData;
mBuffers[kPortIndexOutput].push(info);
@@ -1151,7 +1151,7 @@
OMX_U32 cancelStart;
OMX_U32 cancelEnd;
- if (err != 0 || storingMetadataInDecodedBuffers()) {
+ if (err != OK) {
// If an error occurred while dequeuing we need to cancel any buffers
// that were dequeued. Also cancel all if we're in legacy metadata mode.
cancelStart = 0;
@@ -1175,32 +1175,23 @@
static_cast<Surface*>(mNativeWindow.get())
->getIGraphicBufferProducer()->allowAllocation(false);
- if (storingMetadataInDecodedBuffers()) {
- mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
- }
-
return err;
}
status_t ACodec::allocateOutputMetadataBuffers() {
- CHECK(storingMetadataInDecodedBuffers() && !mLegacyAdaptiveExperiment);
+ CHECK(storingMetadataInDecodedBuffers());
OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
status_t err = configureOutputBuffersFromNativeWindow(
&bufferCount, &bufferSize, &minUndequeuedBuffers,
false /* preregister */);
- if (err != 0)
+ if (err != OK)
return err;
mNumUndequeuedBuffers = minUndequeuedBuffers;
ALOGV("[%s] Allocating %u meta buffers on output port",
mComponentName.c_str(), bufferCount);
- size_t bufSize = mOutputMetadataType == kMetadataBufferTypeANWBuffer ?
- sizeof(struct VideoNativeMetadata) : sizeof(struct VideoGrallocMetadata);
- size_t totalSize = bufferCount * align(bufSize, MemoryDealer::getAllocationAlignment());
- mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "ACodec");
-
for (OMX_U32 i = 0; i < bufferCount; i++) {
BufferInfo info;
info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
@@ -1209,23 +1200,14 @@
info.mGraphicBuffer = NULL;
info.mDequeuedAt = mDequeueCounter;
- sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(bufSize);
- if (mem == NULL || mem->pointer() == NULL) {
- return NO_MEMORY;
- }
- if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
- ((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
- }
- info.mData = new SharedMemoryBuffer(mOutputFormat, mem);
- info.mMemRef = mem;
+ info.mData = new MediaCodecBuffer(mOutputFormat, new ABuffer(bufferSize));
info.mCodecData = info.mData;
- info.mCodecRef = mem;
- err = mOMXNode->useBuffer(kPortIndexOutput, mem, &info.mBufferID);
+ err = mOMXNode->useBuffer(kPortIndexOutput, OMXBuffer::sPreset, &info.mBufferID);
mBuffers[kPortIndexOutput].push(info);
- ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
- mComponentName.c_str(), info.mBufferID, mem->pointer());
+ ALOGV("[%s] allocated meta buffer with ID %u",
+ mComponentName.c_str(), info.mBufferID);
}
mMetadataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
@@ -1401,7 +1383,7 @@
// same is possible in meta mode, in which case, it will be treated
// as a normal buffer, which is not desirable.
// TODO: fix this.
- if (!stale && (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment)) {
+ if (!stale && !storingMetadataInDecodedBuffers()) {
ALOGI("dequeued unrecognized (stale) buffer %p. discarding", buf);
stale = true;
}
@@ -1432,12 +1414,6 @@
// 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;
@@ -1445,23 +1421,10 @@
mRenderTracker.untrackFrame(oldest->mRenderInfo);
oldest->mRenderInfo = NULL;
- if (mOutputMetadataType == kMetadataBufferTypeGrallocSource) {
- VideoGrallocMetadata *grallocMeta =
- reinterpret_cast<VideoGrallocMetadata *>(oldest->mCodecData->base());
- ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
- (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
- mDequeueCounter - oldest->mDequeuedAt,
- (void *)(uintptr_t)grallocMeta->pHandle,
- oldest->mGraphicBuffer->handle, oldest->mCodecData->base());
- } else if (mOutputMetadataType == kMetadataBufferTypeANWBuffer) {
- VideoNativeMetadata *nativeMeta =
- reinterpret_cast<VideoNativeMetadata *>(oldest->mCodecData->base());
- ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
- (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
- mDequeueCounter - oldest->mDequeuedAt,
- (void *)(uintptr_t)nativeMeta->pBuffer,
- oldest->mGraphicBuffer->getNativeBuffer(), oldest->mCodecData->base());
- }
+ ALOGV("replaced oldest buffer #%u with age %u, graphicBuffer %p",
+ (unsigned)(oldest - &mBuffers[kPortIndexOutput][0]),
+ mDequeueCounter - oldest->mDequeuedAt,
+ oldest->mGraphicBuffer->getNativeBuffer());
updateRenderInfoForDequeuedBuffer(buf, fenceFd, oldest);
return oldest;
@@ -1508,9 +1471,7 @@
status_t err = OK;
// there should not be any fences in the metadata
- MetadataBufferType type =
- portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
- if (type == kMetadataBufferTypeANWBuffer && info->mCodecData != NULL
+ if (mPortMode[portIndex] == IOMX::kPortModeDynamicANWBuffer && info->mCodecData != NULL
&& info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
int fenceFd = ((VideoNativeMetadata *)info->mCodecData->base())->nFenceFd;
if (fenceFd >= 0) {
@@ -1569,7 +1530,7 @@
status_t ACodec::fillBuffer(BufferInfo *info) {
status_t err;
- if (!storingMetadataInDecodedBuffers() || mLegacyAdaptiveExperiment) {
+ if (!storingMetadataInDecodedBuffers()) {
err = mOMXNode->fillBuffer(
info->mBufferID, OMXBuffer::sPreset, info->mFenceFd);
} else {
@@ -1611,8 +1572,8 @@
mIsEncoder = encoder;
- mInputMetadataType = kMetadataBufferTypeInvalid;
- mOutputMetadataType = kMetadataBufferTypeInvalid;
+ mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
+ mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
status_t err = setComponentRole(encoder /* isEncoder */, mime);
@@ -1639,18 +1600,18 @@
if (encoder
&& msg->findInt32("android._input-metadata-buffer-type", &storeMeta)
&& storeMeta != kMetadataBufferTypeInvalid) {
- mInputMetadataType = (MetadataBufferType)storeMeta;
- err = mOMXNode->storeMetaDataInBuffers(
- kPortIndexInput, OMX_TRUE, &mInputMetadataType);
+ IOMX::PortMode mode;
+ if (storeMeta == kMetadataBufferTypeNativeHandleSource) {
+ mode = IOMX::kPortModeDynamicNativeHandle;
+ } else if (storeMeta == kMetadataBufferTypeANWBuffer ||
+ storeMeta == kMetadataBufferTypeGrallocSource) {
+ mode = IOMX::kPortModeDynamicANWBuffer;
+ } else {
+ return BAD_VALUE;
+ }
+ err = setPortMode(kPortIndexInput, mode);
if (err != OK) {
- ALOGE("[%s] storeMetaDataInBuffers (input) failed w/ err %d",
- mComponentName.c_str(), err);
-
return err;
- } else if (storeMeta == kMetadataBufferTypeANWBuffer
- && mInputMetadataType == kMetadataBufferTypeGrallocSource) {
- // IOMX translates ANWBuffers to gralloc source already.
- mInputMetadataType = (MetadataBufferType)storeMeta;
}
uint32_t usageBits;
@@ -1695,12 +1656,14 @@
OMX_BOOL enable = (OMX_BOOL) (prependSPSPPS
&& msg->findInt32("android._store-metadata-in-buffers-output", &storeMeta)
&& storeMeta != 0);
+ if (mFlags & kFlagIsSecure) {
+ enable = OMX_TRUE;
+ }
- mOutputMetadataType = kMetadataBufferTypeNativeHandleSource;
- err = mOMXNode->storeMetaDataInBuffers(kPortIndexOutput, enable, &mOutputMetadataType);
+ err = setPortMode(kPortIndexOutput, enable ?
+ IOMX::kPortModePresetSecureBuffer : IOMX::kPortModePresetByteBuffer);
if (err != OK) {
- ALOGE("[%s] storeMetaDataInBuffers (output) failed w/ err %d",
- mComponentName.c_str(), err);
+ return err;
}
if (!msg->findInt64(
@@ -1737,7 +1700,6 @@
bool haveNativeWindow = msg->findObject("native-window", &obj)
&& obj != NULL && video && !encoder;
mUsingNativeWindow = haveNativeWindow;
- mLegacyAdaptiveExperiment = false;
if (video && !encoder) {
inputFormat->setInt32("adaptive-playback", false);
@@ -1753,10 +1715,13 @@
if (mFlags & kFlagIsSecure) {
// use native_handles for secure input buffers
- err = mOMXNode->enableNativeBuffers(
- kPortIndexInput, OMX_FALSE /* graphic */, OMX_TRUE);
- ALOGI_IF(err != OK, "falling back to non-native_handles");
- err = OK; // ignore error for now
+ err = setPortMode(kPortIndexInput, IOMX::kPortModePresetSecureBuffer);
+
+ if (err != OK) {
+ ALOGI("falling back to non-native_handles");
+ setPortMode(kPortIndexInput, IOMX::kPortModePresetByteBuffer);
+ err = OK; // ignore error for now
+ }
}
}
if (haveNativeWindow) {
@@ -1828,14 +1793,8 @@
return err;
}
- // Always try to enable dynamic output buffers on native surface
- mOutputMetadataType = kMetadataBufferTypeANWBuffer;
- err = mOMXNode->storeMetaDataInBuffers(
- kPortIndexOutput, OMX_TRUE, &mOutputMetadataType);
+ err = setPortMode(kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer);
if (err != OK) {
- ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
- mComponentName.c_str(), err);
-
// if adaptive playback has been requested, try JB fallback
// NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
// LARGE MEMORY REQUIREMENT
@@ -1877,15 +1836,15 @@
inputFormat->setInt32("adaptive-playback", true);
}
}
- // allow failure
- err = OK;
+ // Fall back to legacy mode (use fixed ANWBuffer)
+ err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetANWBuffer);
+ if (err != OK) {
+ return err;
+ }
} else {
- ALOGV("[%s] storeMetaDataInBuffers succeeded",
- mComponentName.c_str());
+ ALOGV("[%s] setPortMode on output to %s succeeded",
+ mComponentName.c_str(), asString(IOMX::kPortModeDynamicANWBuffer));
CHECK(storingMetadataInDecodedBuffers());
- mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled(
- "legacy-adaptive", !msg->contains("no-experiments"));
-
inputFormat->setInt32("adaptive-playback", true);
}
@@ -1930,13 +1889,6 @@
mNativeWindow = static_cast<Surface *>(obj.get());
}
- // initialize native window now to get actual output format
- // TODO: this is needed for some encoders even though they don't use native window
- err = initNativeWindow();
- if (err != OK) {
- return err;
- }
-
// fallback for devices that do not handle flex-YUV for native buffers
if (haveNativeWindow) {
int32_t requestedColorFormat = OMX_COLOR_FormatUnused;
@@ -1964,18 +1916,10 @@
mNativeWindowUsageBits = 0;
haveNativeWindow = false;
usingSwRenderer = true;
- if (storingMetadataInDecodedBuffers()) {
- err = mOMXNode->storeMetaDataInBuffers(
- kPortIndexOutput, OMX_FALSE, &mOutputMetadataType);
- mOutputMetadataType = kMetadataBufferTypeInvalid; // just in case
- // TODO: implement adaptive-playback support for bytebuffer mode.
- // This is done by SW codecs, but most HW codecs don't support it.
- inputFormat->setInt32("adaptive-playback", false);
- }
- if (err == OK) {
- err = mOMXNode->enableNativeBuffers(
- kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
- }
+ // TODO: implement adaptive-playback support for bytebuffer mode.
+ // This is done by SW codecs, but most HW codecs don't support it.
+ err = setPortMode(kPortIndexOutput, IOMX::kPortModePresetByteBuffer);
+ inputFormat->setInt32("adaptive-playback", false);
if (mFlags & kFlagIsGrallocUsageProtected) {
// fallback is not supported for protected playback
err = PERMISSION_DENIED;
@@ -4525,15 +4469,6 @@
return err;
}
-status_t ACodec::initNativeWindow() {
- if (mNativeWindow != NULL) {
- return mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_TRUE);
- }
-
- mOMXNode->enableNativeBuffers(kPortIndexOutput, OMX_TRUE /* graphic */, OMX_FALSE);
- return OK;
-}
-
size_t ACodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
size_t n = 0;
@@ -5634,7 +5569,6 @@
OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
- MetadataBufferType metaType = mCodec->mInputMetadataType;
int32_t isCSD = 0;
if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
if (mCodec->mIsLegacyVP9Decoder) {
@@ -5644,7 +5578,6 @@
break;
}
flags |= OMX_BUFFERFLAG_CODECCONFIG;
- metaType = kMetadataBufferTypeInvalid;
}
if (eos) {
@@ -5710,15 +5643,17 @@
info->checkReadFence("onInputBufferFilled");
status_t err2 = OK;
- switch (metaType) {
- case kMetadataBufferTypeInvalid:
+ switch (mCodec->mPortMode[kPortIndexInput]) {
+ case IOMX::kPortModePresetByteBuffer:
+ case IOMX::kPortModePresetANWBuffer:
+ case IOMX::kPortModePresetSecureBuffer:
{
err2 = mCodec->mOMXNode->emptyBuffer(
bufferID, info->mCodecData, flags, timeUs, info->mFenceFd);
}
break;
#ifndef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
- case kMetadataBufferTypeNativeHandleSource:
+ case IOMX::kPortModeDynamicNativeHandle:
if (info->mCodecData->size() >= sizeof(VideoNativeHandleMetadata)) {
VideoNativeHandleMetadata *vnhmd =
(VideoNativeHandleMetadata*)info->mCodecData->base();
@@ -5728,7 +5663,7 @@
bufferID, handle, flags, timeUs, info->mFenceFd);
}
break;
- case kMetadataBufferTypeANWBuffer:
+ case IOMX::kPortModeDynamicANWBuffer:
if (info->mCodecData->size() >= sizeof(VideoNativeMetadata)) {
VideoNativeMetadata *vnmd = (VideoNativeMetadata*)info->mCodecData->base();
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
@@ -5740,7 +5675,8 @@
#endif
default:
ALOGW("Can't marshall %s data in %zu sized buffers in %zu-bit mode",
- asString(metaType), info->mCodecData->size(),
+ asString(mCodec->mPortMode[kPortIndexInput]),
+ info->mCodecData->size(),
sizeof(buffer_handle_t) * 8);
err2 = ERROR_UNSUPPORTED;
break;
@@ -5927,17 +5863,15 @@
mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
}
- if (mCodec->usingMetadataOnEncoderOutput()) {
+ if (mCodec->usingSecureBufferOnEncoderOutput()) {
native_handle_t *handle = NULL;
- VideoNativeHandleMetadata &nativeMeta =
- *(VideoNativeHandleMetadata *)buffer->data();
- if (buffer->size() >= sizeof(nativeMeta)
- && nativeMeta.eType == kMetadataBufferTypeNativeHandleSource) {
+ sp<SecureBuffer> secureBuffer = static_cast<SecureBuffer *>(buffer.get());
+ if (secureBuffer != NULL) {
#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
// handle is only valid on 32-bit/mediaserver process
handle = NULL;
#else
- handle = (native_handle_t *)nativeMeta.pHandle;
+ handle = (native_handle_t *)secureBuffer->getDestinationPointer();
#endif
}
buffer->meta()->setPointer("handle", handle);
@@ -6176,8 +6110,8 @@
mCodec->mOMX.clear();
mCodec->mOMXNode.clear();
mCodec->mFlags = 0;
- mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
- mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
+ mCodec->mPortMode[kPortIndexInput] = IOMX::kPortModePresetByteBuffer;
+ mCodec->mPortMode[kPortIndexOutput] = IOMX::kPortModePresetByteBuffer;
mCodec->mConverter[0].clear();
mCodec->mConverter[1].clear();
mCodec->mComponentName.clear();
@@ -6637,8 +6571,6 @@
}
if (err == OK) {
- mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
-
notify->setMessage("input-format", mCodec->mInputFormat);
notify->setMessage("output-format", mCodec->mOutputFormat);
@@ -6670,8 +6602,6 @@
status_t err = setupInputSurface();
if (err == OK) {
- mCodec->mInputMetadataType = kMetadataBufferTypeANWBuffer;
-
notify->setMessage("input-format", mCodec->mInputFormat);
notify->setMessage("output-format", mCodec->mOutputFormat);
} else {
@@ -7851,8 +7781,8 @@
// tunneled playback includes adaptive playback
builder->addFlags(MediaCodecInfo::Capabilities::kFlagSupportsAdaptivePlayback
| MediaCodecInfo::Capabilities::kFlagSupportsTunneledPlayback);
- } else if (omxNode->storeMetaDataInBuffers(
- kPortIndexOutput, OMX_TRUE) == OK ||
+ } else if (omxNode->setPortMode(
+ kPortIndexOutput, IOMX::kPortModeDynamicANWBuffer) == OK ||
omxNode->prepareForAdaptivePlayback(
kPortIndexOutput, OMX_TRUE,
1280 /* width */, 720 /* height */) == OK) {
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 85ee4ee..ab12a86 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -50,13 +50,10 @@
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 enableNativeBuffers(OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable);
+ status_t setPortMode(OMX_U32 port_index, IOMX::PortMode mode);
status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage);
- status_t storeMetaDataInBuffers(
- OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type);
-
status_t prepareForAdaptivePlayback(
OMX_U32 portIndex, OMX_BOOL enable,
OMX_U32 maxFrameWidth, OMX_U32 maxFrameHeight);
@@ -137,6 +134,8 @@
KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;
KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID;
+ bool mLegacyAdaptiveExperiment;
+ IOMX::PortMode mPortMode[2];
// metadata and secure buffer type tracking
MetadataBufferType mMetadataType[2];
enum SecureBufferType {
@@ -180,15 +179,11 @@
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);
+ OMX::buffer_id *buffer);
- status_t useGraphicBuffer(
+ status_t useGraphicBuffer_l(
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
OMX::buffer_id *buffer);
@@ -200,16 +195,16 @@
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
OMX::buffer_id *buffer);
- status_t emptyBuffer(
+ status_t emptyBuffer_l(
OMX::buffer_id buffer,
OMX_U32 rangeOffset, OMX_U32 rangeLength,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
- status_t emptyGraphicBuffer(
+ status_t emptyGraphicBuffer_l(
OMX::buffer_id buffer, const sp<GraphicBuffer> &graphicBuffer,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
- status_t emptyNativeHandleBuffer(
+ status_t emptyNativeHandleBuffer_l(
OMX::buffer_id buffer, const sp<NativeHandle> &nativeHandle,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd);
@@ -235,6 +230,9 @@
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
+ status_t enableNativeBuffers_l(
+ OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable);
+
status_t storeMetaDataInBuffers_l(
OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type);
diff --git a/media/libstagefright/include/SimpleSoftOMXComponent.h b/media/libstagefright/include/SimpleSoftOMXComponent.h
index 591b38e..1d1f2bd 100644
--- a/media/libstagefright/include/SimpleSoftOMXComponent.h
+++ b/media/libstagefright/include/SimpleSoftOMXComponent.h
@@ -29,6 +29,11 @@
struct ALooper;
+struct CodecProfileLevel {
+ OMX_U32 mProfile;
+ OMX_U32 mLevel;
+};
+
struct SimpleSoftOMXComponent : public SoftOMXComponent {
SimpleSoftOMXComponent(
const char *name,
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index fdc9d7f..be4a932 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -356,9 +356,12 @@
mDebugLevelBumpPendingBuffers[1] = 0;
mMetadataType[0] = kMetadataBufferTypeInvalid;
mMetadataType[1] = kMetadataBufferTypeInvalid;
+ mPortMode[0] = IOMX::kPortModePresetByteBuffer;
+ mPortMode[1] = IOMX::kPortModePresetByteBuffer;
mSecureBufferType[0] = kSecureBufferTypeUnknown;
mSecureBufferType[1] = kSecureBufferTypeUnknown;
mIsSecure = AString(name).endsWith(".secure");
+ mLegacyAdaptiveExperiment = ADebug::isExperimentEnabled("legacy-adaptive");
}
OMXNodeInstance::~OMXNodeInstance() {
@@ -650,7 +653,114 @@
return StatusFromOMXError(err);
}
-status_t OMXNodeInstance::enableNativeBuffers(
+status_t OMXNodeInstance::setPortMode(OMX_U32 portIndex, IOMX::PortMode mode) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (portIndex >= NELEM(mPortMode)) {
+ ALOGE("b/31385713, portIndex(%u)", portIndex);
+ android_errorWriteLog(0x534e4554, "31385713");
+ return BAD_VALUE;
+ }
+
+ CLOG_CONFIG(setPortMode, "%s(%d), port %d", asString(mode), mode, portIndex);
+
+ switch (mode) {
+ case IOMX::kPortModeDynamicANWBuffer:
+ {
+ if (portIndex == kPortIndexOutput) {
+ if (mLegacyAdaptiveExperiment) {
+ CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
+ "not setting port mode to %s(%d) on output",
+ asString(mode), mode);
+ return StatusFromOMXError(OMX_ErrorUnsupportedIndex);
+ }
+
+ status_t err = enableNativeBuffers_l(
+ portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
+ if (err != OK) {
+ return err;
+ }
+ }
+ (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
+ return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL);
+ }
+
+ case IOMX::kPortModeDynamicNativeHandle:
+ {
+ if (portIndex != kPortIndexInput) {
+ CLOG_ERROR(setPortMode, BAD_VALUE,
+ "%s(%d) mode is only supported on input port", asString(mode), mode);
+ return BAD_VALUE;
+ }
+ (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
+ (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
+
+ MetadataBufferType metaType = kMetadataBufferTypeNativeHandleSource;
+ return storeMetaDataInBuffers_l(portIndex, OMX_TRUE, &metaType);
+ }
+
+ case IOMX::kPortModePresetSecureBuffer:
+ {
+ // Allow on both input and output.
+ (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
+ (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
+ return enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_TRUE);
+ }
+
+ case IOMX::kPortModePresetANWBuffer:
+ {
+ if (portIndex != kPortIndexOutput) {
+ CLOG_ERROR(setPortMode, BAD_VALUE,
+ "%s(%d) mode is only supported on output port", asString(mode), mode);
+ return BAD_VALUE;
+ }
+
+ // Check if we're simulating legacy mode with metadata mode,
+ // if so, enable metadata mode.
+ if (mLegacyAdaptiveExperiment) {
+ if (storeMetaDataInBuffers_l(portIndex, OMX_TRUE, NULL) == OK) {
+ CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
+ "metdata mode enabled successfully");
+ return OK;
+ }
+
+ CLOG_INTERNAL(setPortMode, "Legacy adaptive experiment: "
+ "unable to enable metadata mode on output");
+
+ mLegacyAdaptiveExperiment = false;
+ }
+
+ // Disable secure buffer and enable graphic buffer
+ (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
+ status_t err = enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_TRUE);
+ if (err != OK) {
+ return err;
+ }
+
+ // Not running experiment, or metadata is not supported.
+ // Disable metadata mode and use legacy mode.
+ (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
+ return OK;
+ }
+
+ case IOMX::kPortModePresetByteBuffer:
+ {
+ // Disable secure buffer, native buffer and metadata.
+ (void)enableNativeBuffers_l(portIndex, OMX_TRUE /*graphic*/, OMX_FALSE);
+ (void)enableNativeBuffers_l(portIndex, OMX_FALSE /*graphic*/, OMX_FALSE);
+ (void)storeMetaDataInBuffers_l(portIndex, OMX_FALSE, NULL);
+ return OK;
+ }
+
+ default:
+ break;
+ }
+
+ CLOG_ERROR(setPortMode, BAD_VALUE, "invalid port mode %d", mode);
+ return BAD_VALUE;
+}
+
+status_t OMXNodeInstance::enableNativeBuffers_l(
OMX_U32 portIndex, OMX_BOOL graphic, OMX_BOOL enable) {
if (portIndex >= NELEM(mSecureBufferType)) {
ALOGE("b/31385713, portIndex(%u)", portIndex);
@@ -658,7 +768,6 @@
return BAD_VALUE;
}
- Mutex::Autolock autoLock(mLock);
CLOG_CONFIG(enableNativeBuffers, "%s:%u%s, %d", portString(portIndex), portIndex,
graphic ? ", graphic" : "", enable);
OMX_STRING name = const_cast<OMX_STRING>(
@@ -735,13 +844,6 @@
return OK;
}
-status_t OMXNodeInstance::storeMetaDataInBuffers(
- OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) {
- Mutex::Autolock autolock(mLock);
- CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u en:%d", portString(portIndex), portIndex, enable);
- return storeMetaDataInBuffers_l(portIndex, enable, type);
-}
-
status_t OMXNodeInstance::storeMetaDataInBuffers_l(
OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) {
if (mSailed) {
@@ -832,6 +934,12 @@
CLOG_CONFIG(prepareForAdaptivePlayback, "%s:%u en=%d max=%ux%u",
portString(portIndex), portIndex, enable, maxFrameWidth, maxFrameHeight);
+ if (mLegacyAdaptiveExperiment) {
+ CLOG_INTERNAL(prepareForAdaptivePlayback,
+ "Legacy adaptive experiment: reporting success");
+ return OK;
+ }
+
OMX_INDEXTYPE index;
OMX_STRING name = const_cast<OMX_STRING>(
"OMX.google.android.index.prepareForAdaptivePlayback");
@@ -902,43 +1010,62 @@
}
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);
+ OMX_U32 portIndex, const OMXBuffer &omxBuffer, OMX::buffer_id *buffer) {
+ if (buffer == NULL) {
+ ALOGE("b/25884056");
+ return BAD_VALUE;
}
- if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
- return useGraphicBuffer(portIndex, omxBuffer.mGraphicBuffer, buffer);
+ if (portIndex >= NELEM(mNumPortBuffers)) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+
+ switch (omxBuffer.mBufferType) {
+ case OMXBuffer::kBufferTypePreset:
+ return useBuffer_l(portIndex, NULL, buffer);
+
+ case OMXBuffer::kBufferTypeSharedMem:
+ return useBuffer_l(portIndex, omxBuffer.mMem, buffer);
+
+ case OMXBuffer::kBufferTypeANWBuffer:
+ return useGraphicBuffer_l(portIndex, omxBuffer.mGraphicBuffer, buffer);
+
+ default:
+ break;
}
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) {
- ALOGE("b/25884056");
- return BAD_VALUE;
- }
-
- Mutex::Autolock autoLock(mLock);
- if (allottedSize > params->size() || portIndex >= NELEM(mNumPortBuffers)) {
- 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) {
+ OMX_U32 portIndex, const sp<IMemory> ¶ms, OMX::buffer_id *buffer) {
BufferMeta *buffer_meta;
OMX_BUFFERHEADERTYPE *header;
OMX_ERRORTYPE err = OMX_ErrorNone;
bool isMetadata = mMetadataType[portIndex] != kMetadataBufferTypeInvalid;
+
+ OMX_U32 allottedSize;
+ if (isMetadata) {
+ if (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource) {
+ allottedSize = sizeof(VideoGrallocMetadata);
+ } else if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer) {
+ allottedSize = sizeof(VideoNativeMetadata);
+ } else if (mMetadataType[portIndex] == kMetadataBufferTypeNativeHandleSource) {
+ allottedSize = sizeof(VideoNativeHandleMetadata);
+ } else {
+ return BAD_VALUE;
+ }
+ } else {
+ // NULL params is allowed only in metadata mode.
+ if (params == NULL) {
+ ALOGE("b/25884056");
+ return BAD_VALUE;
+ }
+ allottedSize = params->size();
+ }
+
bool isOutputGraphicMetadata = (portIndex == kPortIndexOutput) &&
(mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource ||
mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer);
@@ -968,13 +1095,6 @@
// 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 (params != NULL && allottedSize != params->size()) {
- CLOG_ERROR(useBuffer, BAD_VALUE, SIMPLE_BUFFER(portIndex, (size_t)allottedSize, data));
- return BAD_VALUE;
- }
-
data = new (std::nothrow) OMX_U8[allottedSize];
if (data == NULL) {
return NO_MEMORY;
@@ -984,8 +1104,6 @@
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(
@@ -1083,14 +1201,13 @@
// XXX: This function is here for backwards compatibility. Once the OMX
// implementations have been updated this can be removed and useGraphicBuffer2
// can be renamed to useGraphicBuffer.
-status_t OMXNodeInstance::useGraphicBuffer(
+status_t OMXNodeInstance::useGraphicBuffer_l(
OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id *buffer) {
if (graphicBuffer == NULL || buffer == NULL) {
ALOGE("b/25884056");
return BAD_VALUE;
}
- 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.
@@ -1161,16 +1278,12 @@
return BAD_VALUE;
}
- OMX_U32 allottedSize = 0;
- if (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource) {
- allottedSize = sizeof(VideoGrallocMetadata);
- } else if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer) {
- allottedSize = sizeof(VideoNativeMetadata);
- } else {
+ if (mMetadataType[portIndex] != kMetadataBufferTypeGrallocSource &&
+ mMetadataType[portIndex] != kMetadataBufferTypeANWBuffer) {
return BAD_VALUE;
}
- status_t err = useBuffer_l(portIndex, NULL, buffer, allottedSize);
+ status_t err = useBuffer_l(portIndex, NULL, buffer);
if (err != OK) {
return err;
}
@@ -1443,29 +1556,32 @@
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(
+ Mutex::Autolock autoLock(mLock);
+
+ switch (omxBuffer.mBufferType) {
+ case OMXBuffer::kBufferTypePreset:
+ return emptyBuffer_l(
buffer, 0, omxBuffer.mRangeLength, flags, timestamp, fenceFd);
- }
- if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeANWBuffer) {
- return emptyGraphicBuffer(
+ case OMXBuffer::kBufferTypeANWBuffer:
+ return emptyGraphicBuffer_l(
buffer, omxBuffer.mGraphicBuffer, flags, timestamp, fenceFd);
- }
- if (omxBuffer.mBufferType == OMXBuffer::kBufferTypeNativeHandle) {
- return emptyNativeHandleBuffer(
+ case OMXBuffer::kBufferTypeNativeHandle:
+ return emptyNativeHandleBuffer_l(
buffer, omxBuffer.mNativeHandle, flags, timestamp, fenceFd);
+
+ default:
+ break;
}
return BAD_VALUE;
}
-status_t OMXNodeInstance::emptyBuffer(
+status_t OMXNodeInstance::emptyBuffer_l(
OMX::buffer_id buffer,
OMX_U32 rangeOffset, OMX_U32 rangeLength,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
- Mutex::Autolock autoLock(mLock);
// no emptybuffer if using input surface
if (getBufferSource() != NULL) {
@@ -1614,11 +1730,9 @@
}
// like emptyBuffer, but the data is already in header->pBuffer
-status_t OMXNodeInstance::emptyGraphicBuffer(
+status_t OMXNodeInstance::emptyGraphicBuffer_l(
OMX::buffer_id buffer, const sp<GraphicBuffer> &graphicBuffer,
OMX_U32 flags, OMX_TICKS timestamp, int fenceFd) {
- Mutex::Autolock autoLock(mLock);
-
OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer, kPortIndexInput);
if (header == NULL) {
ALOGE("b/25884056");
@@ -1688,11 +1802,9 @@
return timestamp;
}
-status_t OMXNodeInstance::emptyNativeHandleBuffer(
+status_t OMXNodeInstance::emptyNativeHandleBuffer_l(
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");
@@ -1702,7 +1814,7 @@
status_t err = updateNativeHandleInMeta_l(
kPortIndexInput, nativeHandle, buffer, header);
if (err != OK) {
- CLOG_ERROR(emptyNativeHandleBuffer, err, FULL_BUFFER(
+ CLOG_ERROR(emptyNativeHandleBuffer_l, err, FULL_BUFFER(
(intptr_t)header->pBuffer, header, fenceFd));
return err;
}
diff --git a/media/libstagefright/omx/OMXUtils.h b/media/libstagefright/omx/OMXUtils.h
index 3f533ff..401d64b 100644
--- a/media/libstagefright/omx/OMXUtils.h
+++ b/media/libstagefright/omx/OMXUtils.h
@@ -51,6 +51,30 @@
const sp<IOMXNode> &omxNode,
DescribeColorFormat2Params &describeParams);
+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;
+ }
+}
+
+inline static const char *asString(IOMX::PortMode mode, const char *def = "??") {
+ using namespace android;
+ switch (mode) {
+ case IOMX::kPortModePresetByteBuffer: return "PresetByteBuffer";
+ case IOMX::kPortModePresetANWBuffer: return "PresetANWBuffer";
+ case IOMX::kPortModePresetSecureBuffer: return "PresetSecureBuffer";
+ case IOMX::kPortModeDynamicANWBuffer: return "DynamicANWBuffer";
+ case IOMX::kPortModeDynamicNativeHandle:return "DynamicNativeHandle";
+ default: return def;
+ }
+}
+
} // namespace android
#endif