OMX_ERRORTYPE VideoFilter::ProcessDataBuffer() { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_U32 flags=0; if(bInReturnBufferState == OMX_TRUE) return OMX_ErrorNoMore; ret = ProcessInputBuffer(); if(ret == OMX_ErrorNotReady) return OMX_ErrorNone; if(ret != OMX_ErrorNone) return ret; ret = ProcessOutputBuffer(); if(ret != OMX_ErrorNone) return ret; FilterBufRetCode DecRet = FILTER_OK; DecRet = FilterOneBuffer(); if(DecRet & FILTER_INPUT_CONSUMED) { DecRet = (FilterBufRetCode)(DecRet & ~FILTER_INPUT_CONSUMED); ReturnInputBuffer(); } if(DecRet & FILTER_ONE_FRM_DECODED) { OMX_S32 nStuffSize; OMX_S32 nFrmSize; OMX_PTR pFrm; ret=GetDecBuffer(&pFrm, &nStuffSize, &nFrmSize); if(ret == OMX_ErrorNone) { LOG_DEBUG("%s: get one decoded frm: 0x%X(%d,%d) \n",__FUNCTION__,(int)pFrm,(int)nStuffSize,(int)nFrmSize); tsmSetFrmBoundary(hTsHandle, nStuffSize, nFrmSize, pFrm); } else { LOG_ERROR("%s: get decoded buffer failure !\n",__FUNCTION__); } DecRet = (FilterBufRetCode)(DecRet & ~FILTER_ONE_FRM_DECODED); } switch(DecRet & FILTER_FLAGS_MASK) { case FILTER_FLAG_CODEC_DATA: flags=OMX_BUFFERFLAG_CODECCONFIG; break; case FILTER_FLAG_NONKEY_FRAME: flags=OMX_BUFFERFLAG_ENDOFFRAME; break; case FILTER_FLAG_KEY_FRAME: flags=OMX_BUFFERFLAG_SYNCFRAME|OMX_BUFFERFLAG_ENDOFFRAME; break; default: flags=0; break; } DecRet = (FilterBufRetCode)(DecRet & ~FILTER_FLAGS_MASK); if(DecRet > 0) { LOG_DEBUG("DecRet: %d\n", DecRet); } switch(DecRet) { case FILTER_OK: break; case FILTER_NO_INPUT_BUFFER: if(pInBufferHdr != NULL) SetInputBuffer(pInBufferHdr->pBuffer + pInBufferHdr->nOffset, pInBufferHdr->nFilledLen, bLastInput); else bNeedInputBuffer = OMX_TRUE; break; case FILTER_NO_OUTPUT_BUFFER: bNeedOutBuffer = OMX_TRUE; break; case FILTER_DO_INIT: ret = InitFilter(); if(ret == OMX_ErrorNone) bInit = OMX_TRUE; break; case FILTER_LAST_OUTPUT: HandleLastOutput(flags); ret = OMX_ErrorNoMore; break; case FILTER_HAS_OUTPUT: { OMX_PTR pBuffer = NULL; OMX_S32 nOutSize=0; OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; GetOutputBuffer(&pBuffer,&nOutSize); pBufferHdr = GetOutBufferHdrFromList(pBuffer); if(pBufferHdr != NULL) { pBufferHdr->nFlags = flags; pBufferHdr->nFilledLen = nOutSize;//pBufferHdr->nAllocLen; ReturnOutputBuffer(pBufferHdr,flags); } else { SetOutputBuffer(pBuffer); //still need to return it to vpu to avoid the frame is isolated in the pipeline LOG_ERROR("Can't find related bufferhdr with frame: %p\n", pBuffer); } } break; case FILTER_SKIP_OUTPUT: tsmGetFrmTs(hTsHandle, NULL); break; case FILTER_ERROR: SendEvent(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); ret=OMX_ErrorStreamCorrupt; break; default: break; } return ret; }
OMX_ERRORTYPE VideoFilter::ProcessDataBuffer() { OMX_ERRORTYPE ret = OMX_ErrorNone; OMX_U32 flags=0; if(bInReturnBufferState == OMX_TRUE) return OMX_ErrorNoMore; ret = ProcessInputBuffer(); if(ret == OMX_ErrorNotReady) return OMX_ErrorNone; if(ret != OMX_ErrorNone) return ret; ret = ProcessOutputBuffer(); if(ret != OMX_ErrorNone) return ret; FilterBufRetCode DecRet = FILTER_OK; DecRet = FilterOneBuffer(); if(DecRet & FILTER_INPUT_CONSUMED) { DecRet = (FilterBufRetCode)(DecRet & ~FILTER_INPUT_CONSUMED); ReturnInputBuffer(); } if(DecRet & FILTER_INPUT_CONSUMED_EXT_READ) { DecRet = (FilterBufRetCode)(DecRet & ~FILTER_INPUT_CONSUMED_EXT_READ); if(pInBufferHdr){ InBufferHdrList.Add(pInBufferHdr); pInBufferHdr = NULL; } else{ //for eos buffer with size=0, pInBufferHdr may be retured aleady before (in ProcessInputBuffer()) } } if(DecRet & FILTER_INPUT_CONSUMED_EXT_RETURN) { OMX_PTR ptr; DecRet = (FilterBufRetCode)(DecRet & ~FILTER_INPUT_CONSUMED_EXT_RETURN); GetReturnedInputDataPtr(&ptr); //since the list is FIFO, we needn't map ptr and pHdr if(InBufferHdrList.GetNodeCnt()>0){ OMX_BUFFERHEADERTYPE* pHdr; pHdr=InBufferHdrList.GetNode(0); if(pHdr==NULL){ LOG_ERROR("warning: get one null hdr from InBufferHdrList !\n"); } if(pHdr->pBuffer!=ptr){ LOG_ERROR("warning: the address doesn't match between ptr and pHdr->pBuffer !\n"); } InBufferHdrList.Remove(pHdr); ports[IN_PORT]->SendBuffer(pHdr); } else{ //this path is only for eos if((DecRet&FILTER_LAST_OUTPUT)==0){ LOG_ERROR("warning: the numbers between insert and get doesn't matched !\n"); } } } if(DecRet & FILTER_ONE_FRM_DECODED){ OMX_S32 nStuffSize; OMX_S32 nFrmSize; OMX_PTR pFrm; ret=GetDecBuffer(&pFrm, &nStuffSize, &nFrmSize); if(ret == OMX_ErrorNone){ LOG_DEBUG("%s: get one decoded frm: 0x%X(%d,%d) \n",__FUNCTION__,(int)pFrm,(int)nStuffSize,(int)nFrmSize); tsmSetFrmBoundary(hTsHandle, nStuffSize, nFrmSize, pFrm); } else{ LOG_ERROR("%s: get decoded buffer failure !\n",__FUNCTION__); } DecRet = (FilterBufRetCode)(DecRet & ~FILTER_ONE_FRM_DECODED); } switch(DecRet & FILTER_FLAGS_MASK) { case FILTER_FLAG_CODEC_DATA: flags=OMX_BUFFERFLAG_CODECCONFIG; break; case FILTER_FLAG_NONKEY_FRAME: flags=OMX_BUFFERFLAG_ENDOFFRAME; break; case FILTER_FLAG_KEY_FRAME: flags=OMX_BUFFERFLAG_SYNCFRAME|OMX_BUFFERFLAG_ENDOFFRAME; break; default: flags=0; break; } DecRet = (FilterBufRetCode)(DecRet & ~FILTER_FLAGS_MASK); if(DecRet > 0) { LOG_DEBUG("DecRet: %d\n", DecRet); } switch(DecRet) { case FILTER_OK: break; case FILTER_NO_INPUT_BUFFER: if(pInBufferHdr != NULL) SetInputBuffer(pInBufferHdr->pBuffer + pInBufferHdr->nOffset, pInBufferHdr->nFilledLen, bLastInput); else bNeedInputBuffer = OMX_TRUE; break; case FILTER_NO_OUTPUT_BUFFER: bNeedOutBuffer = OMX_TRUE; break; case FILTER_DO_INIT: ret = InitFilter(); if(ret == OMX_ErrorNone) bInit = OMX_TRUE; break; case FILTER_LAST_OUTPUT: HandleLastOutput(flags); ret = OMX_ErrorNoMore; break; case FILTER_HAS_OUTPUT: { OMX_PTR pBuffer = NULL; OMX_S32 nOutSize=0; OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; GetOutputBuffer(&pBuffer,&nOutSize); if (nOutSize == 0) { nInvalidFrameCnt ++; if (nInvalidFrameCnt <= MOSAIC_COUNT) { SetOutputBuffer(pBuffer); //still need to return it to vpu to avoid the frame is isolated in the pipeline tsmGetFrmTs(hTsHandle, NULL); break; } } else { nInvalidFrameCnt = 0; } pBufferHdr = GetOutBufferHdrFromList(pBuffer); if(pBufferHdr != NULL) { pBufferHdr->nFlags = flags; pBufferHdr->nFilledLen = nOutSize;//pBufferHdr->nAllocLen; ReturnOutputBuffer(pBufferHdr,flags); } else{ SetOutputBuffer(pBuffer); //still need to return it to vpu to avoid the frame is isolated in the pipeline LOG_ERROR("Can't find related bufferhdr with frame: %p\n", pBuffer); } } break; case FILTER_SKIP_OUTPUT: tsmGetFrmTs(hTsHandle, NULL); break; case FILTER_ERROR: SendEvent(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL); ret=OMX_ErrorStreamCorrupt; break; default: break; } return ret; }