Hi,
I use the DVRRDK 04.00.00.3 on a EVM8168 plateform.
I use the Link API to create custom application that can capture video and encode it in h264.
CAPT (1Ch 720p50) --> IPCM3OUT(VPSS) --> IPCM3IN(VID) --> ENC --> IPC BIT OUT RTOS --> IPC BIT IN HLOS --> file.
The application works well but int the resulting file, I have a problem about the image sequence. This means that every 5/6 pictures, there is an old picture.
It seems that the buffers are not properly cleaned and that are registered in the new h264 file.
This problem is about the configuration of the encoder or the capture configuration ?
Void capture_encode_bitsWriteCbFxn(Ptr pPrm) { Bitstream_BufList bitsBuf; Bitstream_Buf *pBuf; Int32 frameId; Int32 status; unsigned long writeDataSize; #if ENABLE_TIME_BUFFER static unsigned long countImage = 0; #endif /* Get buffer list from the IPC Link*/ bitsBuf.numBufs = 0; status = IpcBitsInLink_getFullVideoBitStreamBufs(SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0, &bitsBuf); if( (status == 0 ) && (bitsBuf.numBufs) && (_fout != NULL) ) { for(frameId = 0; frameId < bitsBuf.numBufs ; frameId++ ) { pBuf = bitsBuf.bufs[frameId]; if( pBuf->fillLength > 0 ) { writeDataSize = fwrite(pBuf->addr, sizeof(char),pBuf->fillLength, _fout); if( writeDataSize != pBuf->fillLength) { //fclose(_fout); //_fout = NULL; printf(" Error write : Closing file\n"); } #if ENABLE_TIME_BUFFER printf("******************************\n"); printf("countImage %lu:%lu\n",countImage++,(unsigned long)bitsBuf.numBufs); printf("timeStamp %lu\n",(unsigned long)pBuf->timeStamp); printf("encodeTimeStamp %lu\n",(unsigned long)pBuf->encodeTimeStamp); printf("isKeyFrame %lu\n",(unsigned long)pBuf->isKeyFrame); #endif } } } /* Release buffer list back to the IPC Link*/ /* On relese tout le temps même si pas de données dispo */ IpcBitsInLink_putEmptyVideoBitStreamBufs(SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0, &bitsBuf); } void capture_encode_start(Config_struct *Pt_Conf) { CaptureLink_CreateParams capturePrm; IpcLink_CreateParams ipcOutVpssPrm; IpcLink_CreateParams ipcInVideoPrm; EncLink_CreateParams encPrm; IpcBitsOutLinkRTOS_CreateParams ipcBitsOutVideoPrm; IpcBitsInLinkHLOS_CreateParams ipcBitsInHostPrm; CaptureLink_VipInstParams *pCaptureInstPrm = NULL; CaptureLink_OutParams *pCaptureOutPrm = NULL; UInt32 i/*, status*/; printf("NME : capture_encode_start\n"); _captureId = SYSTEM_LINK_ID_CAPTURE; _encId = SYSTEM_LINK_ID_VENC_0; _ipcBitsOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0; _ipcBitsInVideoId = SYSTEM_VIDEO_LINK_ID_IPC_IN_M3_0; _ipcBitsOutVideoId = SYSTEM_VIDEO_LINK_ID_IPC_BITS_OUT_0; _ipcBitsInHostId = SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0; System_linkControl( SYSTEM_LINK_ID_M3VPSS, SYSTEM_M3VPSS_CMD_RESET_VIDEO_DEVICES, NULL, 0, TRUE ); System_linkControl( SYSTEM_LINK_ID_M3VIDEO, SYSTEM_COMMON_CMD_SET_CH2IVAHD_MAP_TBL, &_systemVid_encDecIvaChMapTbl, sizeof(SystemVideo_Ivahd2ChMap_Tbl), TRUE ); //Chains_ipcBitsInit(); CHAINS_INIT_STRUCT(CaptureLink_CreateParams, capturePrm); CHAINS_INIT_STRUCT(IpcLink_CreateParams, ipcOutVpssPrm); CHAINS_INIT_STRUCT(IpcLink_CreateParams, ipcInVideoPrm); CHAINS_INIT_STRUCT(EncLink_CreateParams, encPrm); CHAINS_INIT_STRUCT(IpcBitsOutLinkRTOS_CreateParams, ipcBitsOutVideoPrm); CHAINS_INIT_STRUCT(IpcBitsInLinkHLOS_CreateParams, ipcBitsInHostPrm); CaptureLink_CreateParams_Init(&capturePrm); capturePrm.numVipInst = 1; /* on utilise qu'un seul VIP inst */ capturePrm.outQueParams[0].nextLink = _ipcBitsOutVpssId; // capturePrm.tilerEnable = FALSE; // capturePrm.enableSdCrop = FALSE; // capturePrm.isPalMode = FALSE; // capturePrm.numBufsPerCh = 4; // capturePrm.numExtraBufs = 0; // capturePrm.maxBlindAreasPerCh = 0; // capturePrm.doCropInCapture = FALSE; printf("NME : init pCaptureInstPrm\n"); for(vipInstId=0; vipInstId< capturePrm.numVipInst ; vipInstId++) { pCaptureInstPrm = &capturePrm.vipInst[vipInstId]; pCaptureInstPrm->vipInstId = (SYSTEM_CAPTURE_INST_VIP0_PORTA+vipInstId) % SYSTEM_CAPTURE_INST_MAX; pCaptureInstPrm->videoDecoderId = 0/*SYSTEM_DEVICE_VID_DEC_TVP5158_DRV*/; pCaptureInstPrm->inDataFormat = SYSTEM_DF_YUV422P; pCaptureInstPrm->standard = Pt_Conf->res0; /* resolution est frequence de la video en entrée */ pCaptureInstPrm->numOutput = 1; pCaptureInstPrm->numChPerOutput = 1; pCaptureOutPrm = &pCaptureInstPrm->outParams[0]; pCaptureOutPrm->dataFormat = SYSTEM_DF_YUV420SP_UV; //pCaptureOutPrm->dataFormat = SYSTEM_DF_YUV422I_UYVY; //pCaptureOutPrm->dataFormat = SYSTEM_DF_YUV422P; pCaptureOutPrm->scEnable = FALSE; /* desativation du module de scale */ pCaptureOutPrm->scOutWidth = Pt_Conf->width[vipInstId]; pCaptureOutPrm->scOutHeight = Pt_Conf->height[vipInstId]; pCaptureOutPrm->outQueId = 0; switch(pCaptureInstPrm->standard) { ... case VSYS_STD_720P_60: case VSYS_STD_720P_50: pCaptureInstPrm->inDataFormat = SYSTEM_DF_YUV422P; pCaptureInstPrm->videoIfMode = SYSTEM_CAPT_VIDEO_IF_MODE_16BIT; pCaptureInstPrm->inScanFormat = SYSTEM_SF_PROGRESSIVE; pCaptureInstPrm->videoCaptureMode = SYSTEM_CAPT_VIDEO_CAPTURE_MODE_SINGLE_CH_NON_MUX_EMBEDDED_SYNC; break; default: pCaptureInstPrm->standard = VSYS_STD_720P_50; pCaptureInstPrm->inDataFormat = SYSTEM_DF_YUV422SP_UV; pCaptureInstPrm->videoIfMode = SYSTEM_CAPT_VIDEO_IF_MODE_16BIT; pCaptureInstPrm->inScanFormat = SYSTEM_SF_PROGRESSIVE; break; } } ipcOutVpssPrm.inQueParams.prevLinkId = _captureId; ipcOutVpssPrm.inQueParams.prevLinkQueId = 0; ipcOutVpssPrm.numOutQue = 1; ipcOutVpssPrm.notifyNextLink = TRUE; ipcOutVpssPrm.notifyPrevLink = TRUE; ipcOutVpssPrm.noNotifyMode = FALSE; ipcOutVpssPrm.inputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcOutVpssPrm.outputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcOutVpssPrm.outQueParams[0].nextLink = _ipcBitsInVideoId; ipcOutVpssPrm.numChPerOutQue[0] = 1; /** * ipcBitsOutVpss to ipcBitsInVideo **/ printf("NME : ipcBitsOutVpss to ipcBitsInVideo\n"); ipcInVideoPrm.inQueParams.prevLinkId = _ipcBitsOutVpssId; ipcInVideoPrm.inQueParams.prevLinkQueId = 0; ipcInVideoPrm.numOutQue = 1; ipcInVideoPrm.notifyNextLink = TRUE; ipcInVideoPrm.notifyPrevLink = TRUE; ipcInVideoPrm.noNotifyMode = FALSE; //FALSE; ipcInVideoPrm.inputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcInVideoPrm.outputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcInVideoPrm.outQueParams[0].nextLink = _encId; ipcInVideoPrm.numChPerOutQue[0] = 1; /** * ipcBitsInVideo to Encoder **/ printf("NME : ipcBitsInVideo to Encoder\n"); /* configuartion du module de compression, ici qu'un seul */ for( i = 0 ; i < 1 ; i++ ) { EncLink_ChCreateParams *pLinkChPrm; EncLink_ChDynamicParams *pLinkDynPrm; if( Pt_Conf->codec == VCODEC_TYPE_H264 ) { encPrm.numBufPerCh[i] = 6; pLinkChPrm = &encPrm.chCreateParams[i]; pLinkDynPrm = &pLinkChPrm->defaultDynamicParams; pLinkChPrm->format = IVIDEO_H264HP; pLinkChPrm->profile = IH264_HIGH_PROFILE; pLinkChPrm->enableAnalyticinfo = 0; pLinkChPrm->enableWaterMarking = 0; pLinkChPrm->maxBitRate = Pt_Conf->bitrate * 1000 ; pLinkChPrm->encodingPreset = VENC_XDM_USER_DEFINED; encPrm.numBufPerCh[i] = 4; /** VENC_XDM_DEFAULT = 0, VENC_XDM_HIGH_QUALITY = 1, VENC_XDM_HIGH_SPEED = 2, VENC_XDM_USER_DEFINED = 3, VENC_XDM_HIGH_SPEED_MED_QUALITY = 4, VENC_XDM_MED_SPEED_MED_QUALITY = 5, VENC_XDM_MED_SPEED_HIGH_QUALITY = 6, */ pLinkChPrm->rateControlPreset = VENC_RATE_CTRL_VBR;//VENC_RATE_CTRL_VBR; //IVIDEO_STORAGE /** VENC_RATE_CTRL_VBR = 0, VENC_RATE_CTRL_CBR = 1,*/ pLinkChPrm->enableHighSpeed = 0; /* enable only if encodingPreset is set to VENC_XDM_USER_DEFINED*/ pLinkChPrm->overrideInputScanFormat = TRUE; pLinkChPrm->fieldPicEncode = FALSE; pLinkDynPrm->intraFrameInterval = Pt_Conf->gopsize[i]; pLinkDynPrm->targetBitRate = Pt_Conf->bitrate * 1000 ; pLinkDynPrm->interFrameInterval = 1; pLinkDynPrm->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL; pLinkDynPrm->rcAlg = 0;//VENC_RATE_CTRL_VBR; pLinkDynPrm->qpMin = 10; pLinkDynPrm->qpMax = 40; pLinkDynPrm->qpInit = -1; pLinkDynPrm->vbrDuration = 8; pLinkDynPrm->vbrSensitivity = 0; pLinkDynPrm->inputFrameRate = Pt_Conf->framerate[i]; switch(Pt_Conf->res0) { ... case VSYS_STD_480P: case VSYS_STD_576P: case VSYS_STD_720P_60: case VSYS_STD_720P_50: case VSYS_STD_1080P_60: case VSYS_STD_1080P_50: case VSYS_STD_1080P_24: case VSYS_STD_1080P_30: default: pLinkChPrm->fieldMergeEncodeEnable = FALSE; pLinkChPrm->dataLayout = VCODEC_FIELD_SEPARATED; /*IVIDEO_PROGRESSIVE;*/ break; } } } encPrm.inQueParams.prevLinkId = _ipcBitsInVideoId; encPrm.inQueParams.prevLinkQueId= 0; encPrm.outQueParams.nextLink = _ipcBitsOutVideoId; /** * Encoder to ipcBitsOutVideo **/ printf("NME : Encoder to ipcBitsOutVideo\n"); ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkId = _encId; ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkQueId = 0; ipcBitsOutVideoPrm.baseCreateParams.numOutQue = 1; ipcBitsOutVideoPrm.baseCreateParams.inputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcBitsOutVideoPrm.baseCreateParams.outputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcBitsOutVideoPrm.baseCreateParams.outQueParams[0].nextLink = _ipcBitsInHostId; ipcBitsOutVideoPrm.baseCreateParams.numChPerOutQue[0] = 1; capture_encode_ipcBitsInitCreateParams_BitsOutRTOS(&ipcBitsOutVideoPrm, TRUE); ipcBitsInHostPrm.baseCreateParams.inQueParams.prevLinkId = _ipcBitsOutVideoId; ipcBitsInHostPrm.baseCreateParams.inQueParams.prevLinkQueId = 0; ipcBitsInHostPrm.baseCreateParams.numOutQue = 1; ipcBitsInHostPrm.baseCreateParams.inputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcBitsInHostPrm.baseCreateParams.outputFrameRate = (UInt32)((double)Pt_Conf->framerate[0] / (double)IPC_FRAMERATE); ipcBitsInHostPrm.baseCreateParams.outQueParams[0].nextLink = SYSTEM_LINK_ID_INVALID; ipcBitsInHostPrm.baseCreateParams.numChPerOutQue[0] = 0; capture_encode_ipcBitsInitCreateParams_BitsInHLOS(&ipcBitsInHostPrm); printf("NME : System_linkCreate _captureId\n"); System_linkCreate(_captureId, &capturePrm, sizeof(capturePrm)); //System_linkControl(_captureId, CAPTURE_LINK_CMD_CONFIGURE_VIP_DECODERS, NULL, 0, TRUE); printf("NME : System_linkCreate _ipcBitsOutVpssId\n"); System_linkCreate(_ipcBitsOutVpssId, &ipcOutVpssPrm, sizeof(ipcOutVpssPrm)); printf("NME : System_linkCreate _ipcBitsInVideoId\n"); System_linkCreate(_ipcBitsInVideoId, &ipcInVideoPrm, sizeof(ipcInVideoPrm)); printf("NME : System_linkCreate _encId\n"); System_linkCreate(_encId, &encPrm, sizeof(encPrm)); printf("NME : System_linkCreate _ipcBitsOutVideoId\n"); System_linkCreate(_ipcBitsOutVideoId, &ipcBitsOutVideoPrm, sizeof(ipcBitsOutVideoPrm)); printf("NME : System_linkCreate _ipcBitsInHostId\n"); System_linkCreate(_ipcBitsInHostId, &ipcBitsInHostPrm, sizeof(ipcBitsInHostPrm)); printf("NME : System_linkStart _ipcBitsInHostId\n"); System_linkStart(_ipcBitsInHostId); printf("NME : System_linkStart _ipcBitsOutVideoId\n"); System_linkStart(_ipcBitsOutVideoId); printf("NME : System_linkStart _encId\n"); System_linkStart(_encId); printf("NME : System_linkStart _ipcBitsInVideoId\n"); System_linkStart(_ipcBitsInVideoId); printf("NME : System_linkStart _ipcBitsOutVpssId\n"); System_linkStart(_ipcBitsOutVpssId); printf("NME : System_linkStart _captureId\n"); System_linkStart(_captureId); }
Thank you !!