diff options
author | Xin Wang <xin1.wang@intel.com> | 2016-06-03 16:25:10 +0800 |
---|---|---|
committer | Nick Desaulniers <ndesaulniers@google.com> | 2016-06-09 10:32:15 -0700 |
commit | e8e99de020ad4508f1db4d9fb3178a5f7a4fa974 (patch) | |
tree | c5567e626018fef5612021f90270087849a2d4d1 | |
parent | 6b2c35f759069df850da5c0364cea0657a5cb837 (diff) | |
download | omx-components-e8e99de020ad4508f1db4d9fb3178a5f7a4fa974.tar.gz |
To fix the VP9 timestamp mismatching issue.
Bug: 28083802
BZ: 49732
By the steps:
1. draining the last frame of previous format, and keep the input buffer;
2. notifying format change, with input buffer kept;
3. decoding the kept input buffer.
Change-Id: I37507a97d24d795ab1ca4b5a976439de477fd008
Signed-off-by: Xin Wang <xin1.wang@intel.com>
Signed-off-by: Lang Dai <langx.dai@intel.com>
Signed-off-by: Austin Hu <austin.hu@intel.com>
-rw-r--r-- | videocodec/OMXVideoDecoderVP9Hybrid.cpp | 66 |
1 files changed, 49 insertions, 17 deletions
diff --git a/videocodec/OMXVideoDecoderVP9Hybrid.cpp b/videocodec/OMXVideoDecoderVP9Hybrid.cpp index aef9821..20075ab 100644 --- a/videocodec/OMXVideoDecoderVP9Hybrid.cpp +++ b/videocodec/OMXVideoDecoderVP9Hybrid.cpp @@ -295,25 +295,11 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorProcess( OMX_ERRORTYPE ret; OMX_BUFFERHEADERTYPE *inBuffer = *pBuffers[INPORT_INDEX]; OMX_BUFFERHEADERTYPE *outBuffer = *pBuffers[OUTPORT_INDEX]; - - if ((mWorkingMode == GRAPHICBUFFER_MODE) && (mAPMode == METADATA_MODE) && - (mLastTimeStamp == 0) && (!mFormatChanged)) { - bool mRet = mGetFrameResolution(inBuffer->pBuffer + inBuffer->nOffset, inBuffer->nFilledLen, - &mDecodedImageNewWidth,&mDecodedImageNewHeight); - - if (mRet && ((mDecodedImageNewWidth != 0) && (mDecodedImageNewHeight != 0)) && - ((mDecodedImageWidth != 0) && (mDecodedImageHeight != 0)) && - ((mDecodedImageNewWidth != mDecodedImageWidth || mDecodedImageNewHeight != mDecodedImageHeight))) { - retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; - HandleFormatChange(); - return OMX_ErrorNone; - } - } - - bool eos = (inBuffer->nFlags & OMX_BUFFERFLAG_EOS)? true:false; OMX_BOOL isResolutionChange = OMX_FALSE; - bool formatChange = false; + bool eos = (inBuffer->nFlags & OMX_BUFFERFLAG_EOS)? true : false; eos = eos && (inBuffer->nFilledLen == 0); + static unsigned char *firstFrame = NULL; + static uint32_t firstFrameSize = 0; if (inBuffer->pBuffer == NULL) { LOGE("Buffer to decode is empty."); @@ -328,6 +314,52 @@ OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorProcess( LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag."); } + if (firstFrameSize == 0 && inBuffer->nFilledLen != 0 && inBuffer->nTimeStamp != 0) { + if (firstFrame != NULL) { + free(firstFrame); + firstFrame = NULL; + } + + firstFrame = (unsigned char *)malloc(inBuffer->nFilledLen); + memcpy(firstFrame, inBuffer->pBuffer + inBuffer->nOffset, inBuffer->nFilledLen); + firstFrameSize = inBuffer->nFilledLen; + } + + if ((mWorkingMode == GRAPHICBUFFER_MODE) && (mAPMode == METADATA_MODE) && (!mFormatChanged)) { + bool mRet = mGetFrameResolution(inBuffer->pBuffer + inBuffer->nOffset, inBuffer->nFilledLen, + &mDecodedImageNewWidth,&mDecodedImageNewHeight); + + if (mRet && ((mDecodedImageNewWidth != 0) && (mDecodedImageNewHeight != 0)) && + ((mDecodedImageWidth != 0) && (mDecodedImageHeight != 0)) && + ((mDecodedImageNewWidth != mDecodedImageWidth || mDecodedImageNewHeight != mDecodedImageHeight))) { + if (mLastTimeStamp == 0) { + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + HandleFormatChange(); + return OMX_ErrorNone; + } else { + // Detected format change in time. + // drain the last frame, keep the current input buffer + mDecoderDecode(mCtx, mHybridCtx, firstFrame, firstFrameSize, false); + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + + mFormatChanged = true; + + ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX], &retains[OUTPORT_INDEX], + eos ? OMX_BUFFERFLAG_EOS : 0, &isResolutionChange); + + if (ret == OMX_ErrorNone) + (*pBuffers[OUTPORT_INDEX])->nTimeStamp = mLastTimeStamp; + + mLastTimeStamp = inBuffer->nTimeStamp; + + free(firstFrame); + firstFrame = NULL; + firstFrameSize = 0; + return ret; + } + } + } + #if LOG_TIME == 1 struct timeval tv_start, tv_end; int32_t time_ms; |