From 315fcbb35ef1f355db2f761408c0a22e47ca8222 Mon Sep 17 00:00:00 2001 From: Tianmi Chen Date: Wed, 29 Apr 2015 17:08:46 +0800 Subject: enable meta data mode for AVC and VP8 on FUGU Use meta data mode for AVC and VP8 adaptive playback. Bug: 19197299 Change-Id: Ifd635d37b107502b8008eaf539bad1dab0de443b Signed-off-by: Tianmi Chen --- videocodec/Android.mk | 3 + videocodec/OMXVideoDecoderBase.cpp | 204 +++++++++++++++++++++++++++++++++---- videocodec/OMXVideoDecoderBase.h | 10 ++ 3 files changed, 198 insertions(+), 19 deletions(-) diff --git a/videocodec/Android.mk b/videocodec/Android.mk index eeec169..31a75b3 100644 --- a/videocodec/Android.mk +++ b/videocodec/Android.mk @@ -55,6 +55,7 @@ endif ifeq ($(TARGET_BOARD_PLATFORM),moorefield) LOCAL_CFLAGS += -DVED_TILING +LOCAL_CFLAGS += -DUSE_META_DATA endif ifeq ($(TARGET_VPP_USE_GEN),true) @@ -114,6 +115,7 @@ endif ifeq ($(TARGET_BOARD_PLATFORM),moorefield) LOCAL_CFLAGS += -DVED_TILING +LOCAL_CFLAGS += -DUSE_META_DATA endif PLATFORM_USE_GEN_HW := \ @@ -454,6 +456,7 @@ LOCAL_SRC_FILES += \ securevideo/moorefield/OMXVideoDecoderAVCSecure.cpp \ securevideo/moorefield/drm_vendor_api.c LOCAL_CFLAGS += -DVED_TILING +LOCAL_CFLAGS += -DUSE_META_DATA LOCAL_SHARED_LIBRARIES += libdl endif diff --git a/videocodec/OMXVideoDecoderBase.cpp b/videocodec/OMXVideoDecoderBase.cpp index 49c68f1..12ad93c 100644 --- a/videocodec/OMXVideoDecoderBase.cpp +++ b/videocodec/OMXVideoDecoderBase.cpp @@ -36,8 +36,11 @@ OMXVideoDecoderBase::OMXVideoDecoderBase() mVideoDecoder(NULL), mNativeBufferCount(OUTPORT_NATIVE_BUFFER_COUNT), mWorkingMode(RAWDATA_MODE), - mErrorReportEnabled (false) { + mErrorReportEnabled (false), + mAPMode(LEGACY_MODE), + mFormatChanged(false) { mOMXBufferHeaderTypePtrNum = 0; + mMetaDataBuffersNum = 0; memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); } @@ -297,7 +300,27 @@ OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorPreFreeBuffer(OMX_U32 nPortIndex, OM LOGW("ProcessorPreFillBuffer: Video decoder is not created"); return OMX_ErrorDynamicResourcesUnavailable; } - status = mVideoDecoder->signalRenderDone(buffer->pBuffer); + + if (mAPMode == METADATA_MODE) { + bool found = false; + if (mOMXBufferHeaderTypePtrNum < mMetaDataBuffersNum) { + for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++) { + if (mOMXBufferHeaderTypePtrArray[i] == buffer) { + found = true; + break; + } + } + if (!found) { + mOMXBufferHeaderTypePtrArray[mOMXBufferHeaderTypePtrNum] = buffer; + mOMXBufferHeaderTypePtrNum++; + } + } + + VideoDecoderOutputMetaData *metadata = (VideoDecoderOutputMetaData *)(buffer->pBuffer); + status = mVideoDecoder->signalRenderDone((void *)(metadata->pHandle), !found); + } else { + status = mVideoDecoder->signalRenderDone(buffer->pBuffer); + } if (status != DECODE_SUCCESS) { LOGW("ProcessorPreFillBuffer:: signalRenderDone return error"); @@ -326,6 +349,14 @@ OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorProcess( if (isResolutionChange) { HandleFormatChange(); } + + // Actually, if mAPMode is set, mWorkingMode should be GRAPHICBUFFER_MODE. + if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) { + if (((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS) || (mVideoDecoder->getOutputQueueLength() == 0)) { + HandleFormatChange(); + } + } + // TODO: continue decoding return ret; } else if (ret != OMX_ErrorNotReady) { @@ -348,15 +379,20 @@ OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorProcess( //pthread_mutex_unlock(&mSerializationLock); if (status == DECODE_FORMAT_CHANGE) { - ret = HandleFormatChange(); - CHECK_RETURN_VALUE("HandleFormatChange"); - ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0; - retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; - retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; - // real dynamic resolution change will be handled later - // Here is just a temporary workaround - // don't use the output buffer if format is changed. - return OMX_ErrorNone; + if ((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) { + mFormatChanged = true; + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + } else { + ret = HandleFormatChange(); + CHECK_RETURN_VALUE("HandleFormatChange"); + ((*pBuffers[OUTPORT_INDEX]))->nFilledLen = 0; + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + // real dynamic resolution change will be handled later + // Here is just a temporary workaround + // don't use the output buffer if format is changed. + return OMX_ErrorNone; + } } else if (status == DECODE_NO_CONFIG) { LOGW("Decoder returns DECODE_NO_CONFIG."); retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; @@ -398,6 +434,12 @@ OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorProcess( HandleFormatChange(); } + if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) { + if (((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS) || (mVideoDecoder->getOutputQueueLength() == 0)) { + HandleFormatChange(); + } + } + bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS); bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS); // if output port is not eos, retain the input buffer until all the output buffers are drained. @@ -445,11 +487,32 @@ OMX_ERRORTYPE OMXVideoDecoderBase::PrepareConfigBuffer(VideoConfigBuffer *p) { } if (mWorkingMode == GRAPHICBUFFER_MODE) { - p->surfaceNumber = mOMXBufferHeaderTypePtrNum; - for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++){ - OMX_BUFFERHEADERTYPE *buffer_hdr = mOMXBufferHeaderTypePtrArray[i]; - p->graphicBufferHandler[i] = buffer_hdr->pBuffer; - LOGV("PrepareConfigBuffer bufferid = %p, handle = %p", buffer_hdr, buffer_hdr->pBuffer); + if (mAPMode == METADATA_MODE) { + const OMX_PARAM_PORTDEFINITIONTYPE *def_output = this->ports[OUTPORT_INDEX]->GetPortDefinition(); + if (def_output == NULL) { + return OMX_ErrorBadParameter; + } + + mMetaDataBuffersNum = def_output->nBufferCountActual; + mOMXBufferHeaderTypePtrNum = 0; + + mGraphicBufferParam.graphicBufferColorFormat = def_output->format.video.eColorFormat; + mGraphicBufferParam.graphicBufferStride = getStride(def_output->format.video.eColorFormat, def_output->format.video.nFrameWidth); + mGraphicBufferParam.graphicBufferWidth = def_output->format.video.nFrameWidth; + mGraphicBufferParam.graphicBufferHeight = (def_output->format.video.nFrameHeight + 0xf) & ~0xf; + + p->surfaceNumber = mMetaDataBuffersNum; + for (int i = 0; i < MAX_GRAPHIC_BUFFER_NUM; i++) { + p->graphicBufferHandler[i] = NULL; + } + p->flag |= WANT_STORE_META_DATA; + } else { + p->surfaceNumber = mOMXBufferHeaderTypePtrNum; + for (uint32_t i = 0; i < mOMXBufferHeaderTypePtrNum; i++){ + OMX_BUFFERHEADERTYPE *buffer_hdr = mOMXBufferHeaderTypePtrArray[i]; + p->graphicBufferHandler[i] = buffer_hdr->pBuffer; + LOGV("PrepareConfigBuffer bufferid = %p, handle = %p", buffer_hdr, buffer_hdr->pBuffer); + } } p->flag |= USE_NATIVE_GRAPHIC_BUFFER; p->graphicBufferStride = mGraphicBufferParam.graphicBufferStride; @@ -536,8 +599,7 @@ OMX_ERRORTYPE OMXVideoDecoderBase::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buf return OMX_ErrorNone; } -OMX_ERRORTYPE OMXVideoDecoderBase::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer, buffer_retain_t *retain, - OMX_U32 inportBufferFlags, OMX_BOOL *isResolutionChange) { +OMX_ERRORTYPE OMXVideoDecoderBase::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer, buffer_retain_t *retain, OMX_U32 inportBufferFlags, OMX_BOOL *isResolutionChange) { OMX_BUFFERHEADERTYPE *buffer = *pBuffer; OMX_BUFFERHEADERTYPE *buffer_orign = buffer; VideoErrorBuffer *ErrBufPtr = NULL; @@ -557,8 +619,13 @@ OMX_ERRORTYPE OMXVideoDecoderBase::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuff bool draining = (inportBufferFlags & OMX_BUFFERFLAG_EOS); //pthread_mutex_lock(&mSerializationLock); - const VideoRenderBuffer *renderBuffer = mVideoDecoder->getOutput(draining, ErrBufPtr); + const VideoRenderBuffer *renderBuffer; //pthread_mutex_unlock(&mSerializationLock); + if (((mAPMode == METADATA_MODE) && (mWorkingMode == GRAPHICBUFFER_MODE)) && mFormatChanged) { + renderBuffer = mVideoDecoder->getOutput(true, ErrBufPtr); + } else { + renderBuffer = mVideoDecoder->getOutput(draining, ErrBufPtr); + } if (renderBuffer == NULL) { buffer->nFilledLen = 0; if (draining) { @@ -638,6 +705,44 @@ OMX_ERRORTYPE OMXVideoDecoderBase::HandleFormatChange(void) { int force_realloc = 0; bool isVP8 = false; + if (mAPMode == METADATA_MODE && mWorkingMode == GRAPHICBUFFER_MODE) { +#ifdef TARGET_HAS_ISV + if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { +#else + if (paramPortDefinitionOutput.nBufferCountActual < formatInfo->actualBufferNeeded) { +#endif + paramPortDefinitionOutput.nBufferCountActual = mNativeBufferCount = formatInfo->actualBufferNeeded; + paramPortDefinitionOutput.nBufferCountMin = formatInfo->actualBufferNeeded - 4; + } + // input port + paramPortDefinitionInput.format.video.nFrameWidth = width; + paramPortDefinitionInput.format.video.nFrameHeight = height; + paramPortDefinitionInput.format.video.nStride = stride; + paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; + // output port + paramPortDefinitionOutput.format.video.nFrameWidth = width; + paramPortDefinitionOutput.format.video.nFrameHeight = height; + paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(paramPortDefinitionOutput.format.video.nFrameWidth); + paramPortDefinitionOutput.format.video.nStride = stride; + paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight; + + paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false; + mOMXBufferHeaderTypePtrNum = 0; + memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam)); + mMetaDataBuffersNum = 0; + + this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); + this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); + + mVideoDecoder->freeSurfaceBuffers(); + + ProcessorFlush(INPORT_INDEX); + this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); + + mFormatChanged = false; + return OMX_ErrorNone; + } + #ifdef TARGET_HAS_ISV LOGI("============== mVppBufferNum = %d\n", mVppBufferNum); if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) { @@ -778,6 +883,9 @@ OMX_ERRORTYPE OMXVideoDecoderBase::BuildHandlerList(void) { AddHandler(static_cast(OMX_IndexExtVppBufferNum), GetDecoderVppBufferNum, SetDecoderVppBufferNum); #endif AddHandler(OMX_IndexConfigCommonOutputCrop, GetDecoderOutputCrop, SetDecoderOutputCrop); +#ifdef USE_META_DATA + AddHandler(static_cast(OMX_IndexStoreMetaDataInBuffers), GetStoreMetaDataMode, SetStoreMetaDataMode); +#endif AddHandler(static_cast(OMX_IndexExtEnableErrorReport), GetErrorReportMode, SetErrorReportMode); AddHandler(static_cast(OMX_IndexConfigPriority), GetCodecPriority, SetCodecPriority); AddHandler(static_cast(OMX_IndexConfigOperatingRate), GetDecoderOperatingRate, SetDecoderOperatingRate); @@ -923,6 +1031,39 @@ OMX_ERRORTYPE OMXVideoDecoderBase::SetNativeBufferModeSpecific(OMX_PTR pStructur return OMX_ErrorNone; } +OMX_ERRORTYPE OMXVideoDecoderBase::GetStoreMetaDataMode(OMX_PTR) { + ALOGE("GetMetaDataMode is not implemented"); + return OMX_ErrorNotImplemented; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::SetStoreMetaDataMode(OMX_PTR pStructure) { + OMX_PARAM_PORTDEFINITIONTYPE defInput; + memcpy(&defInput, + this->ports[INPORT_INDEX]->GetPortDefinition(), + sizeof(defInput)); + if (defInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP9) { + ALOGE("SetMetaDataMode for VP9 is not implemented"); + return OMX_ErrorNotImplemented; + } + + OMX_ERRORTYPE ret; + StoreMetaDataInBuffersParams *param = (StoreMetaDataInBuffersParams*)pStructure; + + CHECK_TYPE_HEADER(param); + CHECK_PORT_INDEX(param, OUTPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + if (!param->bStoreMetaData) { + mAPMode = LEGACY_MODE; + // Don't return error which otherwise may cause framework crash + return OMX_ErrorNone; + } + mAPMode = METADATA_MODE; + ALOGI("We are in meta data mode!!!"); + + return OMX_ErrorNone; +} + OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderRotation(OMX_PTR) { return OMX_ErrorBadParameter; } @@ -1057,3 +1198,28 @@ OMX_COLOR_FORMATTYPE OMXVideoDecoderBase::GetOutputColorFormat(int width) { OMX_ERRORTYPE OMXVideoDecoderBase::SetMaxOutputBufferCount(OMX_PARAM_PORTDEFINITIONTYPE *) { return OMX_ErrorNone; } + +uint32_t OMXVideoDecoderBase::getStride(uint32_t format, uint32_t width) { + uint32_t stride = 0; + format = format; + + if (width <= 512) + stride = 512; + else if (width <= 1024) + stride = 1024; + else if (width <= 1280) { + stride = 1280; +#ifdef USE_GEN_HW + if (format == HAL_PIXEL_FORMAT_NV12_X_TILED_INTEL) { + stride = 2048; + } +#endif + } else if (width <= 2048) + stride = 2048; + else if (width <= 4096) + stride = 4096; + else + stride = (width + 0x3f) & ~0x3f; + + return stride; +} diff --git a/videocodec/OMXVideoDecoderBase.h b/videocodec/OMXVideoDecoderBase.h index ee1cff3..5ad8d3f 100644 --- a/videocodec/OMXVideoDecoderBase.h +++ b/videocodec/OMXVideoDecoderBase.h @@ -83,6 +83,7 @@ protected: #ifdef TARGET_HAS_ISV DECLARE_HANDLER(OMXVideoDecoderBase, DecoderVppBufferNum); #endif + DECLARE_HANDLER(OMXVideoDecoderBase, StoreMetaDataMode); DECLARE_HANDLER(OMXVideoDecoderBase, ErrorReportMode); DECLARE_HANDLER(OMXVideoDecoderBase, CodecPriority); DECLARE_HANDLER(OMXVideoDecoderBase, DecoderOperatingRate); @@ -135,6 +136,15 @@ protected: GraphicBufferParam mGraphicBufferParam; uint32_t mOMXBufferHeaderTypePtrNum; OMX_BUFFERHEADERTYPE *mOMXBufferHeaderTypePtrArray[MAX_GRAPHIC_BUFFER_NUM]; + + enum AdaptivePlaybackMode { + METADATA_MODE, + LEGACY_MODE, + }; + AdaptivePlaybackMode mAPMode; + uint32_t mMetaDataBuffersNum; + bool mFormatChanged; + uint32_t getStride(uint32_t format, uint32_t width); }; #endif /* OMX_VIDEO_DECODER_BASE_H_ */ -- cgit v1.2.3