OMX_ERRORTYPE VideoFilter::ProcessInputBuffer() { OMX_ERRORTYPE ret = OMX_ErrorNone; LOG_DEBUG("Filter In port has #%d buffers.\n", ports[IN_PORT]->BufferNum()); if(pInBufferHdr == NULL) { if(ports[IN_PORT]->BufferNum() > 0) { if(OMX_TRUE != tsmHasEnoughSlot(hTsHandle)) { LOG_DEBUG("No more space to handle input ts.\n"); return OMX_ErrorNone; } ports[IN_PORT]->GetBuffer(&pInBufferHdr); if(pInBufferHdr == NULL) return OMX_ErrorUnderflow; LOG_DEBUG("Get Inbuffer %p:%d:%lld:%x\n", pInBufferHdr->pBuffer, pInBufferHdr->nFilledLen, pInBufferHdr->nTimeStamp, pInBufferHdr->nFlags); ret = ProcessInBufferFlags(); if(ret != OMX_ErrorNone) return ret; ret = SetInputBuffer(pInBufferHdr->pBuffer + pInBufferHdr->nOffset, pInBufferHdr->nFilledLen, bLastInput); if(ret != OMX_ErrorNone) { ReturnInputBuffer(); return ret; } if(pInBufferHdr->nFilledLen == 0) { ReturnInputBuffer(); return OMX_ErrorNone; } bNeedInputBuffer = OMX_FALSE; tsmSetBlkTs(hTsHandle, pInBufferHdr->nFilledLen, pInBufferHdr->nTimeStamp); } else { if(bNeedInputBuffer == OMX_TRUE) return OMX_ErrorNoMore; } } return OMX_ErrorNone; }
OMX_ERRORTYPE VideoFilter::ComponentReturnBuffer(OMX_U32 nPortIndex) { if(nPortIndex == IN_PORT) { FlushInputBuffer(); ReturnInputBuffer(); } if(nPortIndex == OUT_PORT) { FlushOutputBuffer(); while(1) { OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; pBufferHdr = GetFirstOutBufferHdrFromList(); if(pBufferHdr == NULL) break; ports[OUT_PORT]->SendBuffer(pBufferHdr); } bNeedOutBuffer = OMX_TRUE; } bInReturnBufferState = OMX_FALSE; return OMX_ErrorNone; }
OMX_ERRORTYPE VideoFilter::FlushComponent(OMX_U32 nPortIndex) { LOG_DEBUG("Flush filter port: %d\n", (int)nPortIndex); if(nPortIndex == IN_PORT) { FlushInputBuffer(); ReturnInputBuffer(); bLastInput = OMX_FALSE; bLastOutput = OMX_FALSE; nDecodeOnly = 0; bGetNewSegment = OMX_TRUE; } if(nPortIndex == OUT_PORT) { FlushOutputBuffer(); while(1) { OMX_BUFFERHEADERTYPE *pBufferHdr = NULL; pBufferHdr = GetFirstOutBufferHdrFromList(); if(pBufferHdr == NULL) break; ports[OUT_PORT]->SendBuffer(pBufferHdr); } bNeedOutBuffer = OMX_TRUE; } return OMX_ErrorNone; }
OMX_ERRORTYPE VideoFilter::ProcessInBufferFlags() { if(pInBufferHdr->nFlags & OMX_BUFFERFLAG_STARTTIME) bGetNewSegment = OMX_TRUE; if(bGetNewSegment == OMX_TRUE && (!(pInBufferHdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG))) { LOG_DEBUG("Get New sement buffer, ts %lld\n", pInBufferHdr->nTimeStamp); bGetNewSegment = OMX_FALSE; bNewSegment = OMX_TRUE; bLastInput = OMX_FALSE; bLastOutput = OMX_FALSE; if(pInBufferHdr->nFlags & OMX_BUFFERFLAG_STARTTRICK) { LOG_DEBUG("Set ts manager to FIFO mode.\n"); tsmFlush(hTsHandle, pInBufferHdr->nTimeStamp, MODE_FIFO); } else { LOG_DEBUG("Set ts manager to AI mode.\n"); tsmFlush(hTsHandle, pInBufferHdr->nTimeStamp, MODE_AI); } } if(bLastInput != OMX_FALSE) { LOG_DEBUG("Filter drop input buffers in EOS state.\n"); ReturnInputBuffer(); return OMX_ErrorNoMore; } if(pInBufferHdr->nFlags & OMX_BUFFERFLAG_EOS) { bLastInput = OMX_TRUE; bNeedInputBuffer = OMX_FALSE; pInBufferHdr->nTimeStamp = -1; pInBufferHdr->nFilledLen = 0; return OMX_ErrorNone; } if(!(pInBufferHdr->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) && bFilterSupportPartilInput != OMX_TRUE) { ProcessPartialInput(); return OMX_ErrorNotReady; } if(PartialInputHdr.pBuffer != NULL) { ProcessPartialInput(); pInBufferHdr = &PartialInputHdr; } if(pInBufferHdr->nFlags & OMX_BUFFERFLAG_DECODEONLY) nDecodeOnly ++; if(pInBufferHdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG && pInBufferHdr->nFilledLen > 0) { if(pCodecData == NULL) { pCodecData = FSL_MALLOC(pInBufferHdr->nFilledLen); if(pCodecData == NULL) { SendEvent(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL); return OMX_ErrorInsufficientResources; } } else { pCodecData = FSL_REALLOC(pCodecData, nCodecDataLen + pInBufferHdr->nFilledLen); if(pCodecData == NULL) { SendEvent(OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL); return OMX_ErrorInsufficientResources; } } fsl_osal_memcpy((char *)pCodecData + nCodecDataLen, pInBufferHdr->pBuffer, pInBufferHdr->nFilledLen); nCodecDataLen += pInBufferHdr->nFilledLen; LOG_INFO("Get Codec configure data, len: %d\n", nCodecDataLen); ReturnInputBuffer(); return OMX_ErrorNotReady; } return OMX_ErrorNone; }
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; }
void hst_bindings_shmpcm_shmout::process() { OMX_BUFFERHEADERTYPE* bufIn, *bufOut; t_sint32 offset, input_size, output_size; t_sint16 * inptr, * outptr; int nb_samples_out, nb_samples_in;; #ifdef SHMPCMOUT_TRACE_CONTROL printf("hst_shmpcm_shmout::process\n"); #endif if(mPorts[INPUT_PORT].queuedBufferCount() == 0 || mPorts[OUTPUT_PORT].queuedBufferCount() == 0) { return; } ARMNMF_DBC_ASSERT(mShmConfig.channelsIn == mShmConfig.channelsOut); bufIn = (OMX_BUFFERHEADERTYPE*) mPorts[INPUT_PORT].getBuffer(0); bufOut = (OMX_BUFFERHEADERTYPE*) mPorts[OUTPUT_PORT].getBuffer(0); offset = (t_sint32)bufOut->nFilledLen; if ((bInputBufJustArrived == true) && (bufIn->nFlags & OMX_BUFFERFLAG_STARTTIME)) { bInputBufJustArrived = false; mInitialTS = bufIn->nTimeStamp; mNbSamplesForTSComputation = - (offset / (t_sint32)SAMPLE_SIZE_OUT); bPropagateTS = true; } inptr = (t_sint16 *)(bufIn->pBuffer + mDataConsumed); outptr = (t_sint16 *)(bufOut->pBuffer + offset); input_size = bufIn->nFilledLen - mDataConsumed; output_size = bufOut->nAllocLen - offset; nb_samples_in = input_size / SAMPLE_SIZE_IN; nb_samples_out = output_size / SAMPLE_SIZE_OUT; if (nb_samples_in == nb_samples_out) { //copy(inptr, outptr, nb_samples_in); (*hst_bindings_shmpcm_shmout::Shmout_copy_routine) (inptr, outptr, nb_samples_in); bufOut->nFilledLen += nb_samples_in * SAMPLE_SIZE_OUT; bufOut->nFlags |= bufIn->nFlags; ReturnInputBuffer(); ReturnOutputBuffer(bufOut); } else if (nb_samples_in < nb_samples_out) { //copy(inptr, outptr, nb_samples_in); (*hst_bindings_shmpcm_shmout::Shmout_copy_routine) (inptr, outptr, nb_samples_in); bufOut->nFilledLen += nb_samples_in * SAMPLE_SIZE_OUT; if(bufIn->nFlags & OMX_BUFFERFLAG_EOS){ bufOut->nFlags = bufIn->nFlags; ReturnOutputBuffer(bufOut); } bufOut->nFlags |= (bufIn->nFlags & OMX_BUFFERFLAG_STARTTIME); ReturnInputBuffer(); } else { //copy(inptr, outptr, nb_samples_out); (*hst_bindings_shmpcm_shmout::Shmout_copy_routine) (inptr, outptr, nb_samples_out); mDataConsumed += nb_samples_out * SAMPLE_SIZE_IN; bufOut->nFilledLen += nb_samples_out * SAMPLE_SIZE_OUT; bufOut->nFlags |= (bufIn->nFlags & OMX_BUFFERFLAG_STARTTIME); if (bufIn->nFlags & OMX_BUFFERFLAG_STARTTIME) { bufIn->nFlags ^= OMX_BUFFERFLAG_STARTTIME; // reset STARTTIME flag } ReturnOutputBuffer(bufOut); if(mPorts[OUTPUT_PORT].queuedBufferCount() != 0){ scheduleProcessEvent(); } } }
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; }