diff options
author | Lajos Molnar <lajos@google.com> | 2015-05-15 20:39:14 -0700 |
---|---|---|
committer | Lajos Molnar <lajos@google.com> | 2015-06-01 20:24:26 -0700 |
commit | 054219874873b41f1c815552987c10465c34ba2b (patch) | |
tree | b9aaf90692f68ed786880d7daf6ae4f2d2b6b9d7 /media/libstagefright/omx | |
parent | cb18ec05b7097a63262b81afe1e866105d400f4a (diff) | |
download | frameworks_av-054219874873b41f1c815552987c10465c34ba2b.zip frameworks_av-054219874873b41f1c815552987c10465c34ba2b.tar.gz frameworks_av-054219874873b41f1c815552987c10465c34ba2b.tar.bz2 |
stagefright: rework metadata buffer support
- Add fence to new metadata buffer mode structure, but don't use it
yet, so that we don't have to add another mode soon.
- Change GraphicBuffers to ANativeWindowBuffer in new metadata mode.
This removes internal depencency from vendor codecs.
- Extend new metadata mode from SW encoders to all codecs.
- Fallback from new metadata mode to old mode (so Camera can always
use the new mode even with legacy codecs)
Related-bug: 19614055
Bug: 13222807
Change-Id: I405a21dd6ce8e99808f633bfeab8f14278eb7079
Diffstat (limited to 'media/libstagefright/omx')
-rw-r--r-- | media/libstagefright/omx/GraphicBufferSource.cpp | 74 | ||||
-rw-r--r-- | media/libstagefright/omx/GraphicBufferSource.h | 3 | ||||
-rw-r--r-- | media/libstagefright/omx/OMX.cpp | 12 | ||||
-rw-r--r-- | media/libstagefright/omx/OMXNodeInstance.cpp | 184 | ||||
-rw-r--r-- | media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp | 24 |
5 files changed, 168 insertions, 129 deletions
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp index 01cd8f0..f797e63 100644 --- a/media/libstagefright/omx/GraphicBufferSource.cpp +++ b/media/libstagefright/omx/GraphicBufferSource.cpp @@ -29,6 +29,7 @@ #include <media/hardware/MetadataBufferType.h> #include <ui/GraphicBuffer.h> #include <gui/BufferItem.h> +#include <HardwareAPI.h> #include <inttypes.h> #include "FrameDropper.h" @@ -43,7 +44,6 @@ GraphicBufferSource::GraphicBufferSource( uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount, - bool useGraphicBufferInMeta, const sp<IGraphicBufferConsumer> &consumer) : mInitCheck(UNKNOWN_ERROR), mNodeInstance(nodeInstance), @@ -68,8 +68,7 @@ GraphicBufferSource::GraphicBufferSource( mTimePerCaptureUs(-1ll), mTimePerFrameUs(-1ll), mPrevCaptureUs(-1ll), - mPrevFrameUs(-1ll), - mUseGraphicBufferInMeta(useGraphicBufferInMeta) { + mPrevFrameUs(-1ll) { ALOGV("GraphicBufferSource w=%u h=%u c=%u", bufferWidth, bufferHeight, bufferCount); @@ -262,27 +261,27 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) { return; } - if (EXTRA_CHECK) { + if (EXTRA_CHECK && header->nAllocLen >= sizeof(MetadataBufferType)) { // Pull the graphic buffer handle back out of the buffer, and confirm // that it matches expectations. OMX_U8* data = header->pBuffer; MetadataBufferType type = *(MetadataBufferType *)data; - if (type == kMetadataBufferTypeGrallocSource) { - buffer_handle_t bufferHandle; - memcpy(&bufferHandle, data + 4, sizeof(buffer_handle_t)); - if (bufferHandle != codecBuffer.mGraphicBuffer->handle) { + if (type == kMetadataBufferTypeGrallocSource + && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { + VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)data; + if (grallocMeta.hHandle != codecBuffer.mGraphicBuffer->handle) { // should never happen ALOGE("codecBufferEmptied: buffer's handle is %p, expected %p", - bufferHandle, codecBuffer.mGraphicBuffer->handle); + grallocMeta.hHandle, codecBuffer.mGraphicBuffer->handle); CHECK(!"codecBufferEmptied: mismatched buffer"); } - } else if (type == kMetadataBufferTypeGraphicBuffer) { - GraphicBuffer *buffer; - memcpy(&buffer, data + 4, sizeof(buffer)); - if (buffer != codecBuffer.mGraphicBuffer.get()) { + } else if (type == kMetadataBufferTypeANWBuffer + && header->nAllocLen >= sizeof(VideoNativeMetadata)) { + VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)data; + if (nativeMeta.pBuffer != codecBuffer.mGraphicBuffer->getNativeBuffer()) { // should never happen ALOGE("codecBufferEmptied: buffer is %p, expected %p", - buffer, codecBuffer.mGraphicBuffer.get()); + nativeMeta.pBuffer, codecBuffer.mGraphicBuffer->getNativeBuffer()); CHECK(!"codecBufferEmptied: mismatched buffer"); } } @@ -703,36 +702,17 @@ status_t GraphicBufferSource::submitBuffer_l( codecBuffer.mFrameNumber = item.mFrameNumber; OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; - CHECK(header->nAllocLen >= 4 + sizeof(buffer_handle_t)); - OMX_U8* data = header->pBuffer; - buffer_handle_t handle; - if (!mUseGraphicBufferInMeta) { - const OMX_U32 type = kMetadataBufferTypeGrallocSource; - handle = codecBuffer.mGraphicBuffer->handle; - memcpy(data, &type, 4); - memcpy(data + 4, &handle, sizeof(buffer_handle_t)); - } else { - // codecBuffer holds a reference to the GraphicBuffer, so - // it is valid while it is with the OMX component - const OMX_U32 type = kMetadataBufferTypeGraphicBuffer; - memcpy(data, &type, 4); - // passing a non-reference-counted graphicBuffer - GraphicBuffer *buffer = codecBuffer.mGraphicBuffer.get(); - handle = buffer->handle; - memcpy(data + 4, &buffer, sizeof(buffer)); - } - - status_t err = mNodeInstance->emptyDirectBuffer(header, 0, - 4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME, - timeUs); + sp<GraphicBuffer> buffer = codecBuffer.mGraphicBuffer; + status_t err = mNodeInstance->emptyGraphicBuffer( + header, buffer, OMX_BUFFERFLAG_ENDOFFRAME, timeUs); if (err != OK) { - ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err); + ALOGW("WARNING: emptyNativeWindowBuffer failed: 0x%x", err); codecBuffer.mGraphicBuffer = NULL; return err; } - ALOGV("emptyDirectBuffer succeeded, h=%p p=%p bufhandle=%p", - header, header->pBuffer, handle); + ALOGV("emptyNativeWindowBuffer succeeded, h=%p p=%p buf=%p bufhandle=%p", + header, header->pBuffer, buffer->getNativeBuffer(), buffer->handle); return OK; } @@ -755,19 +735,9 @@ void GraphicBufferSource::submitEndOfInputStream_l() { CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi)); OMX_BUFFERHEADERTYPE* header = codecBuffer.mHeader; - if (EXTRA_CHECK) { - // Guard against implementations that don't check nFilledLen. - size_t fillLen = 4 + sizeof(buffer_handle_t); - CHECK(header->nAllocLen >= fillLen); - OMX_U8* data = header->pBuffer; - memset(data, 0xcd, fillLen); - } - - uint64_t timestamp = 0; // does this matter? - - status_t err = mNodeInstance->emptyDirectBuffer(header, /*offset*/ 0, - /*length*/ 0, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, - timestamp); + status_t err = mNodeInstance->emptyGraphicBuffer( + header, NULL /* buffer */, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS, + 0 /* timestamp */); if (err != OK) { ALOGW("emptyDirectBuffer EOS failed: 0x%x", err); } else { diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h index 1047fb3..21ee96a 100644 --- a/media/libstagefright/omx/GraphicBufferSource.h +++ b/media/libstagefright/omx/GraphicBufferSource.h @@ -55,7 +55,6 @@ public: uint32_t bufferWidth, uint32_t bufferHeight, uint32_t bufferCount, - bool useGraphicBufferInMeta = false, const sp<IGraphicBufferConsumer> &consumer = NULL ); @@ -286,7 +285,7 @@ private: int64_t mPrevCaptureUs; int64_t mPrevFrameUs; - bool mUseGraphicBufferInMeta; + MetadataBufferType mMetadataBufferType; void onMessageReceived(const sp<AMessage> &msg); diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index d46bf9d..4ca827c 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -332,8 +332,8 @@ status_t OMX::getGraphicBufferUsage( } status_t OMX::storeMetaDataInBuffers( - node_id node, OMX_U32 port_index, OMX_BOOL enable) { - return findInstance(node)->storeMetaDataInBuffers(port_index, enable); + node_id node, OMX_U32 port_index, OMX_BOOL enable, MetadataBufferType *type) { + return findInstance(node)->storeMetaDataInBuffers(port_index, enable, type); } status_t OMX::prepareForAdaptivePlayback( @@ -373,9 +373,9 @@ status_t OMX::updateGraphicBufferInMeta( status_t OMX::createInputSurface( node_id node, OMX_U32 port_index, - sp<IGraphicBufferProducer> *bufferProducer) { + sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) { return findInstance(node)->createInputSurface( - port_index, bufferProducer); + port_index, bufferProducer, type); } status_t OMX::createPersistentInputSurface( @@ -387,8 +387,8 @@ status_t OMX::createPersistentInputSurface( status_t OMX::setInputSurface( node_id node, OMX_U32 port_index, - const sp<IGraphicBufferConsumer> &bufferConsumer) { - return findInstance(node)->setInputSurface(port_index, bufferConsumer); + const sp<IGraphicBufferConsumer> &bufferConsumer, MetadataBufferType *type) { + return findInstance(node)->setInputSurface(port_index, bufferConsumer, type); } diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index f5f0f4f..e4b2de4 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -32,6 +32,7 @@ #include <gui/BufferQueue.h> #include <HardwareAPI.h> #include <media/stagefright/foundation/ADebug.h> +#include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/MediaErrors.h> #include <utils/misc.h> @@ -135,6 +136,18 @@ struct BufferMeta { header->nFilledLen); } + // return either the codec or the backup buffer + sp<ABuffer> getBuffer(const OMX_BUFFERHEADERTYPE *header, bool backup) { + sp<ABuffer> buf; + if (backup && mMem != NULL) { + buf = new ABuffer(mMem->pointer(), mMem->size()); + } else { + buf = new ABuffer(header->pBuffer, header->nAllocLen); + } + buf->setRange(header->nOffset, header->nFilledLen); + return buf; + } + void setGraphicBuffer(const sp<GraphicBuffer> &graphicBuffer) { mGraphicBuffer = graphicBuffer; } @@ -180,6 +193,8 @@ OMXNodeInstance::OMXNodeInstance( mNumPortBuffers[1] = 0; mDebugLevelBumpPendingBuffers[0] = 0; mDebugLevelBumpPendingBuffers[1] = 0; + mMetadataType[0] = kMetadataBufferTypeInvalid; + mMetadataType[1] = kMetadataBufferTypeInvalid; } OMXNodeInstance::~OMXNodeInstance() { @@ -486,63 +501,73 @@ status_t OMXNodeInstance::getGraphicBufferUsage( } status_t OMXNodeInstance::storeMetaDataInBuffers( - OMX_U32 portIndex, - OMX_BOOL enable) { + 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, - OMX_FALSE /* useGraphicBuffer */, NULL /* usingGraphicBufferInMetadata */); + return storeMetaDataInBuffers_l(portIndex, enable, type); } status_t OMXNodeInstance::storeMetaDataInBuffers_l( - OMX_U32 portIndex, - OMX_BOOL enable, - OMX_BOOL useGraphicBuffer, - OMX_BOOL *usingGraphicBufferInMetadata) { + OMX_U32 portIndex, OMX_BOOL enable, MetadataBufferType *type) { + if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { + return BAD_VALUE; + } + OMX_INDEXTYPE index; OMX_STRING name = const_cast<OMX_STRING>( "OMX.google.android.index.storeMetaDataInBuffers"); - OMX_STRING graphicBufferName = const_cast<OMX_STRING>( - "OMX.google.android.index.storeGraphicBufferInMetaData"); - if (usingGraphicBufferInMetadata == NULL) { - usingGraphicBufferInMetadata = &useGraphicBuffer; - } + OMX_STRING nativeBufferName = const_cast<OMX_STRING>( + "OMX.google.android.index.storeANWBufferInMetadata"); + MetadataBufferType negotiatedType; - OMX_ERRORTYPE err = - (useGraphicBuffer && portIndex == kPortIndexInput) - ? OMX_GetExtensionIndex(mHandle, graphicBufferName, &index) - : OMX_ErrorBadParameter; - if (err == OMX_ErrorNone) { - *usingGraphicBufferInMetadata = OMX_TRUE; - name = graphicBufferName; - } else { - err = OMX_GetExtensionIndex(mHandle, name, &index); - } + StoreMetaDataInBuffersParams params; + InitOMXParams(¶ms); + params.nPortIndex = portIndex; + params.bStoreMetaData = enable; + OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, nativeBufferName, &index); OMX_ERRORTYPE xerr = err; if (err == OMX_ErrorNone) { - StoreMetaDataInBuffersParams params; - InitOMXParams(¶ms); - params.nPortIndex = portIndex; - params.bStoreMetaData = enable; - err = OMX_SetParameter(mHandle, index, ¶ms); + if (err == OMX_ErrorNone) { + name = nativeBufferName; // set name for debugging + negotiatedType = kMetadataBufferTypeANWBuffer; + } + } + if (err != OMX_ErrorNone) { + err = OMX_GetExtensionIndex(mHandle, name, &index); + xerr = err; + if (err == OMX_ErrorNone) { + negotiatedType = kMetadataBufferTypeGrallocSource; + err = OMX_SetParameter(mHandle, index, ¶ms); + } } // don't log loud error if component does not support metadata mode on the output if (err != OMX_ErrorNone) { - *usingGraphicBufferInMetadata = OMX_FALSE; if (err == OMX_ErrorUnsupportedIndex && portIndex == kPortIndexOutput) { CLOGW("component does not support metadata mode; using fallback"); } else if (xerr != OMX_ErrorNone) { CLOG_ERROR(getExtensionIndex, xerr, "%s", name); } else { - CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d GB=%d", name, index, - portString(portIndex), portIndex, enable, useGraphicBuffer); + CLOG_ERROR(setParameter, err, "%s(%#x): %s:%u en=%d type=%d", name, index, + portString(portIndex), portIndex, enable, negotiatedType); + } + negotiatedType = mMetadataType[portIndex]; + } else { + if (!enable) { + negotiatedType = kMetadataBufferTypeInvalid; } + mMetadataType[portIndex] = negotiatedType; } + CLOG_CONFIG(storeMetaDataInBuffers, "%s:%u negotiated %s:%d", + portString(portIndex), portIndex, asString(negotiatedType), negotiatedType); + + if (type != NULL) { + *type = negotiatedType; + } + return StatusFromOMXError(err); } @@ -774,37 +799,59 @@ status_t OMXNodeInstance::useGraphicBuffer( return OK; } -status_t OMXNodeInstance::updateGraphicBufferInMeta( +status_t OMXNodeInstance::updateGraphicBufferInMeta_l( OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer, - OMX::buffer_id buffer) { - Mutex::Autolock autoLock(mLock); + OMX::buffer_id buffer, OMX_BUFFERHEADERTYPE *header) { + if (portIndex != kPortIndexInput && portIndex != kPortIndexOutput) { + return BAD_VALUE; + } - OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer); - VideoDecoderOutputMetaData *metadata = - (VideoDecoderOutputMetaData *)(header->pBuffer); BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate); bufferMeta->setGraphicBuffer(graphicBuffer); - metadata->eType = kMetadataBufferTypeGrallocSource; - metadata->pHandle = graphicBuffer->handle; + if (mMetadataType[portIndex] == kMetadataBufferTypeGrallocSource + && header->nAllocLen >= sizeof(VideoGrallocMetadata)) { + VideoGrallocMetadata &metadata = *(VideoGrallocMetadata *)(header->pBuffer); + metadata.eType = kMetadataBufferTypeGrallocSource; + metadata.hHandle = graphicBuffer == NULL ? NULL : graphicBuffer->handle; + } else if (mMetadataType[portIndex] == kMetadataBufferTypeANWBuffer + && header->nAllocLen >= sizeof(VideoNativeMetadata)) { + VideoNativeMetadata &metadata = *(VideoNativeMetadata *)(header->pBuffer); + metadata.eType = kMetadataBufferTypeANWBuffer; + metadata.pBuffer = graphicBuffer == NULL ? NULL : graphicBuffer->getNativeBuffer(); + metadata.nFenceFd = -1; + } else { + CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x bad type (%d) or size (%u)", + portString(portIndex), portIndex, buffer, mMetadataType[portIndex], header->nAllocLen); + return BAD_VALUE; + } + CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p", portString(portIndex), portIndex, buffer, graphicBuffer->handle); 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); + return updateGraphicBufferInMeta_l(portIndex, graphicBuffer, buffer, header); +} + status_t OMXNodeInstance::createGraphicBufferSource( - OMX_U32 portIndex, sp<IGraphicBufferConsumer> bufferConsumer) { + OMX_U32 portIndex, sp<IGraphicBufferConsumer> bufferConsumer, MetadataBufferType *type) { status_t err; const sp<GraphicBufferSource>& surfaceCheck = getGraphicBufferSource(); if (surfaceCheck != NULL) { + if (portIndex < NELEM(mMetadataType) && type != NULL) { + *type = mMetadataType[portIndex]; + } return ALREADY_EXISTS; } - // Input buffers will hold meta-data (gralloc references). - OMX_BOOL usingGraphicBuffer = OMX_FALSE; - err = storeMetaDataInBuffers_l( - portIndex, OMX_TRUE, - OMX_TRUE /* useGraphicBuffer */, &usingGraphicBuffer); + // Input buffers will hold meta-data (ANativeWindowBuffer references). + err = storeMetaDataInBuffers_l(portIndex, OMX_TRUE, type); if (err != OK) { return err; } @@ -834,7 +881,6 @@ status_t OMXNodeInstance::createGraphicBufferSource( def.format.video.nFrameWidth, def.format.video.nFrameHeight, def.nBufferCountActual, - usingGraphicBuffer, bufferConsumer); if ((err = bufferSource->initCheck()) != OK) { @@ -846,9 +892,9 @@ status_t OMXNodeInstance::createGraphicBufferSource( } status_t OMXNodeInstance::createInputSurface( - OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer) { + OMX_U32 portIndex, sp<IGraphicBufferProducer> *bufferProducer, MetadataBufferType *type) { Mutex::Autolock autolock(mLock); - status_t err = createGraphicBufferSource(portIndex); + status_t err = createGraphicBufferSource(portIndex, NULL /* bufferConsumer */, type); if (err != OK) { return err; @@ -886,9 +932,10 @@ status_t OMXNodeInstance::createPersistentInputSurface( } status_t OMXNodeInstance::setInputSurface( - OMX_U32 portIndex, const sp<IGraphicBufferConsumer> &bufferConsumer) { + OMX_U32 portIndex, const sp<IGraphicBufferConsumer> &bufferConsumer, + MetadataBufferType *type) { Mutex::Autolock autolock(mLock); - return createGraphicBufferSource(portIndex, bufferConsumer); + return createGraphicBufferSource(portIndex, bufferConsumer, type); } status_t OMXNodeInstance::signalEndOfInputStream() { @@ -1044,7 +1091,24 @@ status_t OMXNodeInstance::emptyBuffer( BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate); - buffer_meta->CopyToOMX(header); + sp<ABuffer> backup = buffer_meta->getBuffer(header, true /* backup */); + sp<ABuffer> codec = buffer_meta->getBuffer(header, false /* backup */); + + // convert incoming ANW meta buffers if component is configured for gralloc metadata mode + if (mMetadataType[kPortIndexInput] == kMetadataBufferTypeGrallocSource + && backup->capacity() >= sizeof(VideoNativeMetadata) + && codec->capacity() >= sizeof(VideoGrallocMetadata) + && ((VideoNativeMetadata *)backup->base())->eType + == kMetadataBufferTypeANWBuffer) { + VideoNativeMetadata &backupMeta = *(VideoNativeMetadata *)backup->base(); + VideoGrallocMetadata &codecMeta = *(VideoGrallocMetadata *)codec->base(); + ALOGV("converting ANWB %p to handle %p", backupMeta.pBuffer, backupMeta.pBuffer->handle); + codecMeta.hHandle = backupMeta.pBuffer->handle; + codecMeta.eType = kMetadataBufferTypeGrallocSource; + header->nFilledLen = sizeof(codecMeta); + } else { + buffer_meta->CopyToOMX(header); + } return emptyBuffer_l(header, flags, timestamp, (intptr_t)buffer); } @@ -1106,15 +1170,19 @@ status_t OMXNodeInstance::emptyBuffer_l( } // like emptyBuffer, but the data is already in header->pBuffer -status_t OMXNodeInstance::emptyDirectBuffer( - OMX_BUFFERHEADERTYPE *header, - OMX_U32 rangeOffset, OMX_U32 rangeLength, +status_t OMXNodeInstance::emptyGraphicBuffer( + OMX_BUFFERHEADERTYPE *header, const sp<GraphicBuffer> &graphicBuffer, OMX_U32 flags, OMX_TICKS timestamp) { Mutex::Autolock autoLock(mLock); + OMX::buffer_id buffer = findBufferID(header); + status_t err = updateGraphicBufferInMeta_l(kPortIndexInput, graphicBuffer, buffer, header); + if (err != OK) { + CLOG_ERROR(emptyGraphicBuffer, err, FULL_BUFFER((intptr_t)header->pBuffer, header)); + return err; + } - header->nFilledLen = rangeLength; - header->nOffset = rangeOffset; - + header->nOffset = 0; + header->nFilledLen = graphicBuffer == NULL ? 0 : header->nAllocLen; return emptyBuffer_l(header, flags, timestamp, (intptr_t)header->pBuffer); } diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp index d4d6217..5f80cbc 100644 --- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp @@ -155,7 +155,7 @@ void SoftVideoEncoderOMXComponent::updatePortParams() { uint32_t rawBufferSize = inDef->format.video.nStride * inDef->format.video.nSliceHeight * 3 / 2; if (inDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { - inDef->nBufferSize = 4 + max(sizeof(buffer_handle_t), sizeof(GraphicBuffer *)); + inDef->nBufferSize = max(sizeof(VideoNativeMetadata), sizeof(VideoGrallocMetadata)); } else { inDef->nBufferSize = rawBufferSize; } @@ -482,8 +482,8 @@ const uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer( size_t dstVStride = height; MetadataBufferType bufferType = *(MetadataBufferType *)src; - bool usingGraphicBuffer = bufferType == kMetadataBufferTypeGraphicBuffer; - if (!usingGraphicBuffer && bufferType != kMetadataBufferTypeGrallocSource) { + bool usingANWBuffer = bufferType == kMetadataBufferTypeANWBuffer; + if (!usingANWBuffer && bufferType != kMetadataBufferTypeGrallocSource) { ALOGE("Unsupported metadata type (%d)", bufferType); return NULL; } @@ -499,13 +499,14 @@ const uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer( int format; size_t srcStride; size_t srcVStride; - if (usingGraphicBuffer) { - if (srcSize < sizeof(OMX_U32) + sizeof(GraphicBuffer *)) { - ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(OMX_U32) + sizeof(GraphicBuffer *)); + if (usingANWBuffer) { + if (srcSize < sizeof(VideoNativeMetadata)) { + ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoNativeMetadata)); return NULL; } - GraphicBuffer *buffer = *(GraphicBuffer **)(src + sizeof(OMX_U32)); + VideoNativeMetadata &nativeMeta = *(VideoNativeMetadata *)src; + ANativeWindowBuffer *buffer = nativeMeta.pBuffer; handle = buffer->handle; format = buffer->format; srcStride = buffer->stride; @@ -519,12 +520,13 @@ const uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer( } else { // TODO: remove this part. Check if anyone uses this. - if (srcSize < sizeof(OMX_U32) + sizeof(buffer_handle_t)) { - ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(OMX_U32) + sizeof(buffer_handle_t)); + if (srcSize < sizeof(VideoGrallocMetadata)) { + ALOGE("Metadata is too small (%zu vs %zu)", srcSize, sizeof(VideoGrallocMetadata)); return NULL; } - handle = *(buffer_handle_t *)(src + sizeof(OMX_U32)); + VideoGrallocMetadata &grallocMeta = *(VideoGrallocMetadata *)(src); + handle = grallocMeta.hHandle; // assume HAL_PIXEL_FORMAT_RGBA_8888 // there is no way to get the src stride without the graphic buffer format = HAL_PIXEL_FORMAT_RGBA_8888; @@ -606,7 +608,7 @@ const uint8_t *SoftVideoEncoderOMXComponent::extractGraphicBuffer( OMX_ERRORTYPE SoftVideoEncoderOMXComponent::getExtensionIndex( const char *name, OMX_INDEXTYPE *index) { if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers") || - !strcmp(name, "OMX.google.android.index.storeGraphicBufferInMetaData")) { + !strcmp(name, "OMX.google.android.index.storeANWBufferInMetadata")) { *(int32_t*)index = kStoreMetaDataExtensionIndex; return OMX_ErrorNone; } |