功能介绍:收到前一个link发过来的多通道数据时,根据当时时间戳和UC设置的允许时间戳误差进行同步,如果在误差范围之内则发送下一个link,一般和merge配套使用,使用merge把多个通道的数据整合成一路,然后把这几路数据进行同步组合
代码位置:links_fw/src/rtos/links_common/sync rtos
links_fw/src/hlos/links_a15/sync hlos
使用示例:
Capture -> Dup -> alg_dsp0 -> merge
Dup -> Merge
Merge -> sync -> Display
一些重要参数:
pObj->numCh 上一个link通道数(例如merge中通道数)
pObj->chObj[chId].localQueHandle 本地队列,有多少个通道建立多少个,用来保存pre link数据
pObj->outFrameQue 输出队列,同步后放在该队列中
pObj->timer = BspOsal_clockCreate( //这个定时器每33ms往本模块发送一个SYSTEM_CMD_NEW_DATA
&SyncLink_timerCallback, //用来修正发送给下一link的时间间隔
33U, (Bool)FALSE, pObj);
处理步骤:
1、检查本地所有通道队列数据时间戳是否符合要求(UC设置了阈值),不符合则取出放入到dropList等待释放给pre link
2、释放dropList
3、获取pre link所有通道数据,放入对应通道本地队列
4、检查本地所有通道队列是否都有数据,如果都有,计算平均时间戳,否则跳过本地process
5、执行同步逻辑
6、取一个空buff,组装成综合buf,包含了video frame和metadata frame
7、发送到next link
部分主要函数分析:
Int32 SyncLink_fillLocalQueues(SyncLink_Obj * pObj)
//从pre link取出所有通道的数据,并分别放入本地对应通道的队列中保存
System_getLinksFullBuffers(inputBufList)
for(inputBufList.numBuf)
Utils_quePut(&pObj->chObj[pBuffer->chNum].localQueHandle)
SyncLink_addBuffersToDropListLesserThanThreshold
//丢弃离本次处理时间太长的帧
//所有chId buf的src时间戳 - 当前处理时间戳 超过UC设置的syncThreshold时,
全部放入dropList
Utils_quePeek(localQueHandle)
curTime = Utils_getCurGlobalTimeInUsec();
计算diffTime,如果超过syncThreshold,则该通道数据放入dropList
Void SyncLink_dropBuffers(SyncLink_Obj * pObj)
//释放dropBufList的buf到pre link
System_putLinksEmptyBuffers(&pObj->dropBufList)
Int32 SyncLink_fillLocalQueues(SyncLink_Obj * pObj)
//获取pre link所有通道数据,并分别放入本地对应chId的队列中(每个chId有一个本地队列)
System_getLinksFullBuffers(inputBufList)
for(inputBufList.numBuf)
Utils_quePut(&pObj->chObj[pBuffer->chNum].localQueHandle)
Bool SyncLink_computeMasterTimeStamp(SyncLink_Obj * pObj)
//所有通道都有数据的情况下,计算所有numCh的平均时间戳masterTimeStamp
for(pObj->numCh)
Utils_quePeek(&pObj->chObj[chId].localQueHandle)
计算pObj->masterTimeStamp
Int32 SyncLink_computeDecisionParams(SyncLink_Obj * pObj,
Bool *syncDone)
//不同通道的localQueHandle中时间戳和平均时间戳对比(和UC设置的delta做上下阈值),
如果该通道时间戳小于masterTimeStamp-delta,该chId放入dropList
如果该通道时间戳大于masterTimeStamp+delta,说明除当前chId的帧外其他帧都偏早,丢弃他们放入dropList
如果所有通道时间戳介于之间,则syncDone
Int32 SyncLink_makeCompositeBuffer(SyncLink_Obj * pObj, System_Buffer *pSysBuf)
// 当所有通道有效且同步成功时,组装成composite buf
for(pObj->numCh)
Utils_queGet(chObj[chId].localQueHandle,pBuf)
根据bufType为SYSTEM_BUFFER_TYPE_VIDEO_FRAME和SYSTEM_BUFFER_TYPE_METADATA填充数据
video frame: pSysCompBuf->bufAddr[i][numFrames] 每个chId numFrames+1