完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
是周期性调用吗?具体代码在哪?谢谢!
|
|
相关推荐
8 个讨论
|
|
你好, 应该是通过显示的Vsync。请参考HDVPSS驱动。 typedef struct [ UInt32 memType; /**< VPDMA Memory type. For valid values see #Vps_VpdmaMemoryType. */ UInt32 periodicCallbackEnable; /**< TRUE: User callback passed during FVID2 create is called periodically. For progressive display, this interval is equal to VSYNC interval. For interlaced display, this interval is equal to twice the VSYNC interval as frames (two fields) are queued to the driver. FALSE: User callback passed during FVID2 create is called only if one or more frames (requests) are available in the driver output queue for the application to dequeue. */ ] Vps_DispCreateParams;。 |
|
|
|
|
|
是的,谢谢! 如下代码说明: /* Create capture driver */ Int32 CaptureLink_drvCreateInst(CaptureLink_Obj * pObj, UInt16 instId) [ ... pVipCreateArgs->periodicCallbackEnable = TRUE; ... ] 但是我在《HDVPSS_UserGuide》手册中没有找到Vsync相关说明。 而且还是不能完全明白displayLink的数据接收处理机制,还请进一步指导: (1) displayLink的前一个Link(m3vpssInLink)通过下面的代码给displayLink发送“SYSTEM_CMD_NEW_DATA”消息指示: System_sendLinkCmd(pObj->createArgs.baseCreateParams.outQueParams.nextLink, SYSTEM_CMD_NEW_DATA); 但是为何displayLink内没有“SYSTEM_CMD_NEW_DATA”对应处理? 而是对“ DISPLAY_LINK_CMD_DO_DEQUE”消息的处理: Int32 DisplayLink_tskRun(DisplayLink_Obj * pObj, Utils_TskHndl * pTsk, Utils_MsgHndl ** pMsg, Bool * done, Bool * ackMsg) [ ... case DISPLAY_LINK_CMD_DO_DEQUE: status = DisplayLink_drvProcessData(pObj); ... ] “ DISPLAY_LINK_CMD_DO_DEQUE”消息是由下面的回调函数发出的: Int32 DisplayLink_drvFvidCb(FVID2_Handle handle, Ptr appData, Ptr reserved) [ ... Utils_tskSendCmd(&pObj->tsk, DISPLAY_LINK_CMD_DO_DEQUE); ... ] (2) displayLink通过下面三种情况获取帧数据,不是很理解,请帮忙解释一下三种情况: Int32 DisplayLink_drvProcessData(DisplayLink_Obj * pObj) [ FVID2_FrameList frameList; FVID2_FrameList freeFrameList; FVID2_FrameList displayFrameList; UInt32 freeFrameNum, elaspedTime; System_LinkInQueParams *pInQueParams; FVID2_Frame *pFrame; Int32 status; UInt32 latency; Int i; UInt32 frameIdx; elaspedTime = Utils_getCurTimeInMsec() - pObj->startTime; if ((elaspedTime - pObj->prevTime) > 24 * 60 * 60 * 1000) [ DisplayLink_drvPrintRtStatus(pObj, elaspedTime); pObj->prevTime = elaspedTime; ] if(pObj->displayInstId==0) [ System_displayUnderflowCheck(FALSE); ] do [ UInt32 freeQueueId; //*情况一:*/ /* dequeue all completed frames * status = DisplayLink_drvDeQueue(pObj,&freeFrameList, &freeQueueId); #ifdef SYSTEM_DEBUG_FLOW Vps_printf(" %d: DisplayLink_drvProcessData : drvDeQueue Frames %d !!!n", Utils_getCurTimeInMsec(), freeFrameList.numFrames); #endif if (freeFrameList.numFrames) [ pObj->inFramePutCount += freeFrameList.numFrames; UTILS_assert(freeQueueId < pObj->createArgs.numInputQueues); pInQueParams = &pObj->createArgs.inQueParams[freeQueueId]; System_putLinksEmptyFrames(pInQueParams->prevLinkId, pInQueParams->prevLinkQueId, &freeFrameList); #ifdef SYSTEM_DEBUG_FLOW Vps_printf(" %d: DisplayLink_drvProcessData : 1st putLinksEmptyFrames %d !!!n", Utils_getCurTimeInMsec(), freeFrameList.numFrames); #endif ] ] while (status == FVID2_SOK); #ifdef SYSTEM_DEBUG_FLOW Vps_printf(" %d: DisplayLink_drvProcessData : numInputQueues = %d , curActiveQueue = %d !!!n", Utils_getCurTimeInMsec(), pObj->createArgs.numInputQueues,pObj->curActiveQueue); #endif /*情况二:*//* Free frames queued in inactive queues immediately */ for (i = 0; i < pObj->createArgs.numInputQueues;i++) [ if (i != pObj->curActiveQueue) [ frameList.numFrames = 0; pInQueParams = &pObj->createArgs.inQueParams; System_getLinksFullFrames(pInQueParams->prevLinkId, pInQueParams->prevLinkQueId, &frameList); #ifdef SYSTEM_DEBUG_FLOW Vps_printf(" %d: DisplayLink_drvProcessData : 1st getLinksFullFrames %d !!!n", Utils_getCurTimeInMsec(), frameList.numFrames); #endif if (frameList.numFrames) [ pObj->inFrameGetCount += frameList.numFrames; pObj->inFramePutCount += frameList.numFrames; System_putLinksEmptyFrames(pInQueParams->prevLinkId, pInQueParams->prevLinkQueId, &frameList); #ifdef SYSTEM_DEBUG_FLOW Vps_printf(" %d: DisplayLink_drvProcessData : 2nd putLinksEmptyFrames %d !!!n", Utils_getCurTimeInMsec(), freeFrameList.numFrames); #endif ] ] ] UTILS_assert(pObj->curActiveQueue < pObj->createArgs.numInputQueues); pInQueParams = &pObj->createArgs.inQueParams[pObj->curActiveQueue]; /*情况三:*/ /* que frames if any */ System_getLinksFullFrames(pInQueParams->prevLinkId, pInQueParams->prevLinkQueId, &frameList); #ifdef SYSTEM_DEBUG_FLOW Vps_printf(" %d: DisplayLink_drvProcessData : 2st getLinksFullFrames %d !!!n", Utils_getCurTimeInMsec(), frameList.numFrames); #endif pObj->inFrameGetCount += frameList.numFrames; freeFrameNum = 0; DisplayLink_drvLock(pObj); frameIdx = 0; while((pObj->maxQueueCount) && (frameIdx < frameList.numFrames)) [ pFrame = frameList.frames[frameIdx]; frameIdx++; UTILS_assert(pFrame != NULL); if (pFrame->channelNum == pObj->curDisplayChannelNum) [ Bool frameReject; UInt32 pitch0,pitch1; pitch0 = pObj->displayFormat.pitch[0]; pitch1 = pObj->displayFormat.pitch[1]; if (DisplayLink_drvDoInputPitchDoubling(pObj)) [ pitch0 /= 2; pitch1 /= 2; ] UTILS_assert(DISPLAY_LINK_BLANK_FRAME_CHANNEL_NUM != pFrame->channelNum); pFrame->addr[1][0] = (UInt8 *) pFrame->addr[0][0] + pitch0; pFrame->addr[1][1] = (UInt8 *) pFrame->addr[0][1] + pitch1; #ifdef SYSTEM_DEBUG_DISPLAY_RT Vps_printf(" %d: DISPLAY: Queue %d framesn", Utils_getCurTimeInMsec(), displayFrameList.numFrames); #endif latency = Utils_getCurTimeInMsec() - pFrame->timeStamp; if(latency>pObj->maxLatency) pObj->maxLatency = latency; if(latency pObj->minLatency = latency; /* queue frame for display */ displayFrameList.numFrames = 0; DisplayLink_drvSetFrameInfo(pObj, &pFrame, &frameReject); if (pFrame) [ if (frameReject) [ UTILS_assert(freeFrameNum < UTILS_ARRAYSIZE(freeFrameList.frames)); /* error in queing to display, instead of asserting release the frame and continue */ freeFrameList.frames[freeFrameNum] = pFrame; freeFrameNum++; ] else [ displayFrameList.frames[displayFrameList.numFrames] = pFrame; displayFrameList.numFrames++; displayFrameList.perListCfg = NULL; DisplayLink_drvHandleDynamicPitchChange(pObj,&displayFrameList); DisplayLink_validateFrameList(pObj, &displayFrameList); pObj->queueCount += displayFrameList.numFrames; pObj->numBufsInDriver++; status = FVID2_queue(pObj->displayHndl, &displayFrameList, 0); pObj->maxQueueCount--; if(status!=FVID2_SOK) [ Vps_rprintf(" %d: DISPLAY (%d): Queue to driver failed !!!n", Utils_getCurTimeInMsec(), pObj->tskId); UTILS_assert(freeFrameNum < UTILS_ARRAYSIZE(freeFrameList.frames)); /* error in queing to display, instead of asserting release the frame and continue */ freeFrameList.frames[freeFrameNum] = pFrame; freeFrameNum++; DisplayLink_drvFreeFrameInfo(pObj, &displayFrameList); ] ] ] ] else [ UTILS_assert(freeFrameNum < UTILS_ARRAYSIZE(freeFrameList.frames)); freeFrameList.frames[freeFrameNum] = pFrame; freeFrameNum++; ] ] DisplayLink_drvUnlock(pObj); for (i = frameIdx; i < frameList.numFrames;i++) [ UTILS_assert(freeFrameNum < UTILS_ARRAYSIZE(freeFrameList.frames)); freeFrameList.frames[freeFrameNum] = frameList.frames; freeFrameNum++; ] if (freeFrameNum) [ freeFrameList.numFrames = freeFrameNum; pObj->inFramePutCount += freeFrameList.numFrames; System_putLinksEmptyFrames(pInQueParams->prevLinkId, pInQueParams->prevLinkQueId, &freeFrameList); #ifdef SYSTEM_DEBUG_FLOW Vps_printf(" %d: DisplayLink_drvProcessData : 3rd putLinksEmptyFrames %d !!!n", Utils_getCurTimeInMsec(), freeFrameList.numFrames); #endif ] return FVID2_SOK; ] (3)我们现在遇到的问题如下(经打印的Log分析显示),请帮忙分析原因: (3.1) displayLink的前一个Link(m3vpssInLink)通过下面的代码给displayLink发送“SYSTEM_CMD_NEW_DATA”消息指示,发送了19个帧(19次,每次一个帧)数据; (3.2) displayLink仅在上述: /*情况一:*/ 获取5帧数据,有release framebuffer操作; /*情况三:*/ 获取7帧数据,没有release framebuffer操作(要继续查原因); (3.3) 后续m3vpssInLink不再接收到frame数据,c6xdsp在 ListMP_getHead(pObj->listMPInHndl)后来总是返回NULL后挂死: Int32 IpcFramesOutLink_releaseFrameBufs(IpcFramesOutLink_Obj * pObj) [ System_LinkInQueParams *pInQueParams; SystemIpcFrames_ListElem *pListElem = NULL; Int32 status; UInt32 curTime, roundTripTime; FVID2_Frame *pFrameBuf = NULL; FVID2_FrameList freeFrameBufList; UInt8 queId; UInt32 chPerQueue; UInt32 times = 0; pInQueParams = &pObj->createArgs.baseCreateParams.inQueParams; do [ freeFrameBufList.numFrames = 0; curTime = Utils_getCurTimeInMsec(); while (freeFrameBufList.numFrames < FVID2_MAX_FVID_FRAME_PTR) [ pListElem = ListMP_getHead(pObj->listMPInHndl); if (pListElem == NULL) break; UTILS_assert(SYSTEM_IPC_FRAMES_GET_BUFSTATE(pListElem->bufState) == IPC_FRAMEBUF_STATE_INQUE); IpcFramesOutLink_mapListElem2FrameBuf(pObj, pListElem, &pFrameBuf); UTILS_assert(pFrameBuf != NULL); if (curTime > pFrameBuf->timeStamp) [ roundTripTime = curTime - pFrameBuf->timeStamp; pObj->stats.totalRoundTrip += roundTripTime; ] /* Restore the original timestamp as it may be used by next link */ pFrameBuf->timeStamp = pListElem->frameBuf.timeStamp; freeFrameBufList.frames[freeFrameBufList.numFrames] = pFrameBuf; freeFrameBufList.numFrames++; UTILS_assert(freeFrameBufList.numFrames <= FVID2_MAX_FVID_FRAME_PTR); /* release ListElem back to queue */ SYSTEM_IPC_FRAMES_SET_BUFOWNERPROCID(pListElem->bufState); SYSTEM_IPC_FRAMES_SET_BUFSTATE(pListElem->bufState, IPC_FRAMEBUF_STATE_FREE); status = Utils_quePut(&pObj->listElemQue, pListElem, BIOS_NO_WAIT); UTILS_assert(status == FVID2_SOK); ] #ifdef SYSTEM_DEBUG_IPC_RT Vps_printf(" %d: IPC_FRAMES_OUT : Releasing %d framebufs !!!n", Utils_getCurTimeInMsec(), freeFrameBufList.numFrames); #endif if (freeFrameBufList.numFrames) [ /* If the buffer is released via processing link, pass it to next link */ /* NextLink will take care to release the buffer to privLink */ if(pObj->createArgs.baseCreateParams.processLink != SYSTEM_LINK_ID_INVALID) [ Int i; UInt32 sendMsgToTsk = 0; for (i = 0; i < freeFrameBufList.numFrames;i++) [ pObj->stats.forwardCount++; /** Split the frames into both the output queues, * if they are enabled. Else use output queue 0 only. * Also, if output queue 1 is used, frames sent to this queue * should be modified before submitting so that the * pFrame->channelNum should start with 0 and not with * (pObj->nsfCreateParams.numCh / 2). */ pFrameBuf = freeFrameBufList.frames; chPerQueue = (pObj->numCh / pObj->createArgs.baseCreateParams.numOutQue); queId = (pFrameBuf->channelNum / chPerQueue); pFrameBuf->channelNum = pFrameBuf->channelNum % chPerQueue; status = Utils_quePut(&pObj->outFrameBufQue[queId], freeFrameBufList.frames, BIOS_NO_WAIT); UTILS_assert(!UTILS_ISERROR(status)); sendMsgToTsk |= (1 << queId); ] if (pObj->createArgs.baseCreateParams.notifyNextLink) [ for (i = 0; i < pObj->createArgs.baseCreateParams.numOutQue;i++) [ if (sendMsgToTsk & 0x1) [ System_sendLinkCmd(pObj->createArgs.baseCreateParams.outQueParams. nextLink, SYSTEM_CMD_NEW_DATA); ] sendMsgToTsk >>= 1; if (sendMsgToTsk == 0) break; ] ] ] else [ System_putLinksEmptyFrames(pInQueParams->prevLinkId, pInQueParams->prevLinkQueId, &freeFrameBufList); ] ] ] while (pListElem != NULL); return FVID2_SOK; ] |
|
|
|
|
|
你好,
显示模块是周期性显示数据的,不需要前面一个link一发送数据,就去显示。所以显示link只需要在需要显示的时候去看有没有新数据,如果有就显示新数据,如果没有,就显示之前的数据。 下面的论坛讨论有如下描述: https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/717/p/210164/743682#743682 if the driver does not have any more buffers for the display, it keeps displaying last buffer and since it is displaying the buffer, it retains the last buffer. In call cases frames are displayed at Vsync intervals. At every vsync display driver checks for new frames and if new frames are present it releases old frame.So if new frame is queued old frame is released at next Vsync after the frame is queued. There two, queue and buffer update, are different operations, application call queue from the task context and driver updates the buffer in the isr context, so it does not update the buffer immediately after buffer is queued. All the buffer including the last buffer will get displayed at the display frame rates, how many times last buffer gets displayed depends on the applicaiton delay in queueing the buffer. 显示的驱动是比较复杂的,如果你再看看hdvpss驱动,里面还有一个DLM(dispaly list manager)。如果去掉DSP link显示就没有问题,那我认为还是应该看看其他link。 |
|
|
|
|
|
物是人非aaa 发表于 2020-8-17 20:13 仔细对照Log分析了displayLink代码,认为displayLink处理数据流是这样的:1. displayLink调用前一个link(m3vpssInLink)的GetFullFrameBufs()获取发送过来的帧数据buffer;2. displayLink调用Frame_que()将获取的帧数据buffer再交给displayLink驱动;3. displayLink调用Frame_deque() 获取 displayLink驱动返回的数据buffer,再将此buffer释放给前一个Link;我们的问题还是上面第1步获取的帧数据较前一个Link发送的少很多,导致前一个Link后来再也获取不到displayLink释放的buffer而挂死.还请大家指导! |
|
|
|
|
|
只有小组成员才能发言,加入小组>>
309 浏览 1 评论
513 浏览 2 评论
NA555DR VCC最低电压需要在5V供电,为什么用3.3V供电搭了个单稳态触发器也使用正常?
754 浏览 3 评论
MSP430F249TPMR出现高温存储后失效了的情况,怎么解决?
641 浏览 1 评论
对于多级放大电路板,在PCB布局中,电源摆放的位置应该注意什么?
1113 浏览 1 评论
请问下tpa3220实际测试引脚功能和官方资料不符,哪位大佬可以帮忙解答下
226浏览 20评论
请教下关于TAS5825PEVM评估模块原理图中不太明白的地方,寻求答疑
181浏览 14评论
两个TMP117传感器一个可以正常读取温度值,一个读取的值一直是0,为什么?
46浏览 13评论
在使用3254进行录音的时候出现一个奇怪的现象,右声道有吱吱声,请教一下,是否是什么寄存器设置存在问题?
149浏览 13评论
TLV320芯片内部自带数字滤波功能,请问linein进来的模拟信号是否是先经过ADC的超采样?
158浏览 12评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 12:13 , Processed in 1.046280 second(s), Total 52, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号