我们现在的DM385开发板上外挂了一个tvp5151芯片,用来接CVBS摄像头,原理图如下:
tvp5151输出8bit 内嵌同步的CVBS(NTSC或PAL)信号到DM385的VIP1 PORTA的D0~D7位上,数据流如下:
tvp5151(cvbs) -> capture-> deinterlace -> encode -> send
软件版本使用的是dvr rdk 4.0,代码如下:
void MultiCh_createVcapVencVdis() { CaptureLink_CreateParams capturePrm; DeiLink_CreateParams deiPrm; IpcFramesOutLinkRTOS_CreateParams ipcFramesOutVpssToHostPrm; IpcFramesInLinkRTOS_CreateParams ipcFramesInVideoFromHostPrm; EncLink_CreateParams encPrm; IpcBitsOutLinkRTOS_CreateParams ipcBitsOutVideoPrm; IpcBitsInLinkHLOS_CreateParams ipcBitsInHostPrm; CaptureLink_VipInstParams *pCaptureInstPrm; CaptureLink_OutParams *pCaptureOutPrm; VCAP_VIDEO_SOURCE_STATUS_S vidSourceStatus; int i; MULTICH_INIT_STRUCT(DeiLink_CreateParams, deiPrm); MULTICH_INIT_STRUCT(IpcFramesOutLinkRTOS_CreateParams, ipcFramesOutVpssToHostPrm); MULTICH_INIT_STRUCT(IpcFramesInLinkRTOS_CreateParams, ipcFramesInVideoFromHostPrm); MULTICH_INIT_STRUCT(EncLink_CreateParams, encPrm); MULTICH_INIT_STRUCT(IpcBitsOutLinkRTOS_CreateParams, ipcBitsOutVideoPrm); MULTICH_INIT_STRUCT(IpcBitsInLinkHLOS_CreateParams, ipcBitsInHostPrm); gVcapModuleContext.captureId = SYSTEM_LINK_ID_CAPTURE; gVcapModuleContext.deiId[0] = SYSTEM_LINK_ID_DEI_0; gVcapModuleContext.ipcFramesOutVpssToHostId = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0; gVencModuleContext.ipcM3InId = SYSTEM_VIDEO_LINK_ID_IPC_IN_M3_0; gVencModuleContext.encId = SYSTEM_LINK_ID_VENC_0; gVencModuleContext.ipcBitsOutRTOSId = SYSTEM_VIDEO_LINK_ID_IPC_BITS_OUT_0; gVencModuleContext.ipcBitsInHLOSId = SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0; MultiCh_detectBoard(); 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 ); gVcapModuleContext.isWrbkCaptEnable = FALSE; CaptureLink_CreateParams_Init(&capturePrm); capturePrm.outQueParams[0].nextLink = gVcapModuleContext.deiId[0]; capturePrm.isPalMode = TRUE; capturePrm.numVipInst = 1; capturePrm.enableSdCrop = FALSE; capturePrm.doCropInCapture = FALSE; capturePrm.tilerEnable = FALSE; capturePrm.numBufsPerCh = NUM_CAPTURE_BUFFERS; capturePrm.overrideNumBufsInInstPrms = 1u; pCaptureInstPrm = &capturePrm.vipInst[0]; pCaptureInstPrm->inDataFormat = SYSTEM_DF_YUV422P; //pCaptureInstPrm->standard = SYSTEM_STD_D1; pCaptureInstPrm->standard = SYSTEM_STD_MUX_4CH_D1; pCaptureInstPrm->videoDecoderId = 0; pCaptureInstPrm->numOutput = 1; pCaptureInstPrm->numBufsPerCh = NUM_CAPTURE_BUFFERS; pCaptureInstPrm->vipInstId = SYSTEM_CAPTURE_INST_VIP1_PORTA; pCaptureInstPrm->videoIfMode = SYSTEM_CAPT_VIDEO_IF_MODE_8BIT; pCaptureInstPrm->inScanFormat = SYSTEM_SF_INTERLACED; pCaptureOutPrm = &pCaptureInstPrm->outParams[0]; pCaptureOutPrm->dataFormat = SYSTEM_DF_YUV422I_YUYV; pCaptureOutPrm->scEnable = FALSE; pCaptureOutPrm->scOutWidth = 0; pCaptureOutPrm->scOutHeight = 0; pCaptureOutPrm->outQueId = 0; deiPrm.inQueParams.prevLinkId = gVcapModuleContext.captureId; deiPrm.inQueParams.prevLinkQueId = 0; deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].scaleMode = DEI_SCALE_MODE_RATIO; deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.widthRatio.numerator = 1; deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.widthRatio.denominator = 1; deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.heightRatio.numerator = 1; deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.heightRatio.denominator = 1; for (i = 1; i < DEI_LINK_MAX_CH; i++) deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][i] = deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0]; deiPrm.enableOut[DEI_LINK_OUT_QUE_DEI_SC] = FALSE; deiPrm.enableOut[DEI_LINK_OUT_QUE_VIP_SC] = TRUE; deiPrm.enableOut[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT] = FALSE; deiPrm.enableOut[DEI_LINK_OUT_QUE_DEI_SC_SECONDARY_OUT] = FALSE; deiPrm.enableOut[DEI_LINK_OUT_QUE_DEI_SC_TERTIARY_OUT] = FALSE; deiPrm.outQueParams[DEI_LINK_OUT_QUE_VIP_SC].nextLink = gVcapModuleContext.ipcFramesOutVpssToHostId; deiPrm.tilerEnable[DEI_LINK_OUT_QUE_VIP_SC] = FALSE; deiPrm.comprEnable = FALSE; deiPrm.setVipScYuv422Format = FALSE; deiPrm.enableDeiForceBypass = FALSE; ipcFramesOutVpssToHostPrm.baseCreateParams.noNotifyMode = FALSE; ipcFramesOutVpssToHostPrm.baseCreateParams.notifyNextLink = TRUE; ipcFramesOutVpssToHostPrm.baseCreateParams.notifyPrevLink = TRUE; ipcFramesOutVpssToHostPrm.baseCreateParams.inQueParams.prevLinkQueId = 0; ipcFramesOutVpssToHostPrm.baseCreateParams.inQueParams.prevLinkId = gVcapModuleContext.deiId[0]; ipcFramesOutVpssToHostPrm.baseCreateParams.outQueParams[0].nextLink = gVencModuleContext.ipcM3InId; ipcFramesInVideoFromHostPrm.baseCreateParams.noNotifyMode = FALSE; ipcFramesInVideoFromHostPrm.baseCreateParams.notifyNextLink = TRUE; ipcFramesInVideoFromHostPrm.baseCreateParams.notifyPrevLink = TRUE; ipcFramesInVideoFromHostPrm.baseCreateParams.inQueParams.prevLinkQueId = 0; ipcFramesInVideoFromHostPrm.baseCreateParams.inQueParams.prevLinkId = gVcapModuleContext.ipcFramesOutVpssToHostId; ipcFramesInVideoFromHostPrm.baseCreateParams.outQueParams[0].nextLink = gVencModuleContext.encId; { EncLink_ChCreateParams *pLinkChPrm; EncLink_ChDynamicParams *pLinkDynPrm; VENC_CHN_DYNAMIC_PARAM_S *pDynPrm; VENC_CHN_PARAMS_S *pChPrm; for (i = 0; i < gVencModuleContext.vencConfig.numPrimaryChn; i++) { pLinkChPrm = &encPrm.chCreateParams[i]; pLinkDynPrm = &pLinkChPrm->defaultDynamicParams; pChPrm = &gVencModuleContext.vencConfig.encChannelParams[i]; pDynPrm = &pChPrm->dynamicParam; pLinkChPrm->format = IVIDEO_H264HP; pLinkChPrm->profile = gVencModuleContext.vencConfig.h264Profile[i]; pLinkChPrm->dataLayout = IVIDEO_PROGRESSIVE; pLinkChPrm->fieldMergeEncodeEnable = FALSE; pLinkChPrm->enableAnalyticinfo = pChPrm->enableAnalyticinfo; pLinkChPrm->enableWaterMarking = pChPrm->enableWaterMarking; pLinkChPrm->maxBitRate = pChPrm->maxBitRate; pLinkChPrm->encodingPreset = pChPrm->encodingPreset; pLinkChPrm->rateControlPreset = IVIDEO_USER_DEFINED; pLinkChPrm->enableSVCExtensionFlag = pChPrm->enableSVCExtensionFlag; pLinkChPrm->numTemporalLayer = pChPrm->numTemporalLayer; pLinkChPrm->enableHighSpeed = FALSE; pLinkDynPrm->intraFrameInterval = pDynPrm->intraFrameInterval; pLinkDynPrm->targetBitRate = pDynPrm->targetBitRate; pLinkDynPrm->interFrameInterval = 1; pLinkDynPrm->mvAccuracy = IVIDENC2_MOTIONVECTOR_QUARTERPEL; pLinkDynPrm->inputFrameRate = pDynPrm->inputFrameRate; pLinkDynPrm->rcAlg = pDynPrm->rcAlg; pLinkDynPrm->qpMin = pDynPrm->qpMin; pLinkDynPrm->qpMax = pDynPrm->qpMax; pLinkDynPrm->qpInit = pDynPrm->qpInit; pLinkDynPrm->vbrDuration = pDynPrm->vbrDuration; pLinkDynPrm->vbrSensitivity = pDynPrm->vbrSensitivity; encPrm.numBufPerCh[i] = 4; } } encPrm.chCreateParams[0].defaultDynamicParams.inputFrameRate = 30; encPrm.chCreateParams[1].defaultDynamicParams.inputFrameRate = 30; encPrm.inQueParams.prevLinkQueId = 0; encPrm.inQueParams.prevLinkId = gVencModuleContext.ipcM3InId; encPrm.outQueParams.nextLink = gVencModuleContext.ipcBitsOutRTOSId; ipcBitsOutVideoPrm.baseCreateParams.noNotifyMode = FALSE; ipcBitsOutVideoPrm.baseCreateParams.notifyNextLink = TRUE; ipcBitsOutVideoPrm.baseCreateParams.notifyPrevLink = TRUE; ipcBitsOutVideoPrm.baseCreateParams.numOutQue = 1; ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkQueId = 0; ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkId = gVencModuleContext.encId; ipcBitsOutVideoPrm.baseCreateParams.outQueParams[0].nextLink = gVencModuleContext.ipcBitsInHLOSId; ipcBitsInHostPrm.baseCreateParams.inQueParams.prevLinkQueId = 0; ipcBitsInHostPrm.baseCreateParams.inQueParams.prevLinkId = gVencModuleContext.ipcBitsOutRTOSId; MultiCh_ipcBitsInitCreateParams_BitsInHLOS(&ipcBitsInHostPrm); vidSourceStatus.numChannels = 1; vidSourceStatus.chStatus[0].chId = 0; vidSourceStatus.chStatus[0].frameWidth = 720; vidSourceStatus.chStatus[0].frameHeight = 288; vidSourceStatus.chStatus[0].vipInstId = SYSTEM_CAPTURE_INST_VIP1_PORTA; vidSourceStatus.chStatus[0].isInterlaced = TRUE; vidSourceStatus.chStatus[0].frameInterval = 20000; vidSourceStatus.chStatus[0].isVideoDetect = FALSE; Vcap_setVideoSourceStatus(&vidSourceStatus); System_linkCreate(gVcapModuleContext.captureId, &capturePrm, sizeof(capturePrm)); System_linkCreate(gVcapModuleContext.deiId[0], &deiPrm, sizeof(deiPrm)); System_linkCreate(gVcapModuleContext.ipcFramesOutVpssToHostId, &ipcFramesOutVpssToHostPrm, sizeof(ipcFramesOutVpssToHostPrm)); System_linkCreate(gVencModuleContext.ipcM3InId, &ipcFramesInVideoFromHostPrm, sizeof(ipcFramesInVideoFromHostPrm)); System_linkCreate(gVencModuleContext.encId, &encPrm, sizeof(encPrm)); System_linkCreate(gVencModuleContext.ipcBitsOutRTOSId, &ipcBitsOutVideoPrm, sizeof(ipcBitsOutVideoPrm)); System_linkCreate(gVencModuleContext.ipcBitsInHLOSId, &ipcBitsInHostPrm, sizeof(ipcBitsInHostPrm)); }
测试结果如下:
1. 当“pCaptureInstPrm->standard = SYSTEM_STD_D1”时,capture采不到视频;
2. 当“pCaptureInstPrm->standard = SYSTEM_STD_MUX_4CH_D1”时,capture可以采到视频,但deinterlace会出错;
麻烦各位帮忙看一下上面的哪些配置是错误的,到底该怎么配置才能让视频出来? 谢谢!
Eason Wang:
SYSTEM_STD_MUX_4CH_D1 这个应该不对的,是用于TVP5158这样4个通道复合的视频ADC的。SYSTEM_STD_D1应该是对的。
你提到capture能采集到视频,是通过什么来看的?
BR,
Eason
tao Zhu2:
回复 Eason Wang:
你好,我也知道SYSTEM_STD_MUX_4CH_D1不对,但总是采不到数据,我就把所有分辨为720*576的格式都试了一遍,结果只有SYSTEM_STD_MUX_4CH_D1可以采集到视频;
我是根据"DVRRDK_04.01.00.02/ti_tools/hdvpss/dvr_rdk_hdvpss/packages/ti/psp/vps/drivers/capture/src/vpsdrv_captureList.c"文件中的Vps_captTskSubmitFieldList函数的如下代码作判断的:
Int32 Vps_captTskSubmitFieldList() {pid |= Vps_captLmPostDescList(listAddr, listSize); }当采集到1场数据时,Vps_captLmPostDescList函数返回0x1;当采集到2场(1帧)数据时,Vps_captLmPostDescList函数返回0x11;没有采集到数据时,Vps_captLmPostDescList函数返回0x0;
我们在DM385的VIP0 PORTA上接了一块HDMI解码芯片,那条通道是可以正常出视频的,此时Vps_captLmPostDescList函数返回0x11;将VIP1 PORTA设置成SYSTEM_STD_MUX_4CH_D1, 此时Vps_captLmPostDescList函数返回0x1;将VIP1 PORTA设置成SYSTEM_STD_D1, 此时Vps_captLmPostDescList函数返回0x0;
user4516476:
回复 tao Zhu2:
你好,我也做了一个和你这个类似的开发,使用的是tvp5150,我的程序如果去掉DEI模块就是正常的,但当我加入DEI模块后就会出现VPSS挂掉的现象,出现错误sh是unhandle exception,希望你看到后给我点建议,qq:1083789279