IPCINM3和IPCOutM3
IPCINM3和IPCOutM3 vpss和videoM3之間通訊;
1)IpcInM3 link初始化
Int32 IpcInM3Link_init()
{
Int32 status;
System_LinkObj linkObj;
UInt32 ipcInM3Id;
IpcInM3Link_Obj *pObj;
char tskName[32];
UInt32 procId = System_getSelfProcId();
for (ipcInM3Id = 0; ipcInM3Id < IPC_IN_M3_LINK_OBJ_MAX; ipcInM3Id++)
{
pObj = &gIpcInM3Link_obj[ipcInM3Id];
memset(pObj, 0, sizeof(*pObj));
pObj->tskId =
SYSTEM_MAKE_LINK_ID(procId, SYSTEM_LINK_ID_IPC_IN_M3_0) + ipcInM3Id;
linkObj.pTsk = &pObj->tsk;
linkObj.linkGetFullFrames = IpcInM3Link_getFullFrames;
linkObj.linkPutEmptyFrames = IpcInM3Link_putEmptyFrames;
linkObj.getLinkInfo = IpcInM3Link_getLinkInfo;
System_registerLink(pObj->tskId, &linkObj);
sprintf(tskName, "IPC_IN_M3%d", ipcInM3Id);
System_ipcRegisterNotifyCb(pObj->tskId, IpcInM3Link_notifyCb);
status = Utils_tskCreate(&pObj->tsk,
IpcInM3Link_tskMain,
IPC_LINK_TSK_PRI,
gIpcInM3Link_tskStack[ipcInM3Id],
IPC_LINK_TSK_STACK_SIZE, pObj, tskName);
UTILS_assert(status == FVID2_SOK);
}
return status;
}
2)IpcInM3Link_tskMain函式
Void IpcInM3Link_tskMain(struct Utils_TskHndl * pTsk, Utils_MsgHndl * pMsg)
{
UInt32 cmd = Utils_msgGetCmd(pMsg);
Bool ackMsg, done;
Int32 status;
IpcInM3Link_Obj *pObj = (IpcInM3Link_Obj *) pTsk->appData;
if (cmd != SYSTEM_CMD_CREATE)
{
Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);
return;
}
//呼叫utils_queCreate建立輸出佇列
status = IpcInM3Link_create(pObj, Utils_msgGetPrm(pMsg));
Utils_tskAckOrFreeMsg(pMsg, status);
if (status != FVID2_SOK)
return;
done = FALSE;
ackMsg = FALSE;
while (!done)
{
status = Utils_tskRecvMsg(pTsk, &pMsg, BIOS_WAIT_FOREVER);
if (status != FVID2_SOK)
break;
cmd = Utils_msgGetCmd(pMsg);
switch (cmd)
{
case SYSTEM_CMD_DELETE:
done = TRUE;
ackMsg = TRUE;
break;
case SYSTEM_CMD_NEW_DATA:
Utils_tskAckOrFreeMsg(pMsg, status);
//有新資料到來,獲取資料
IpcInM3Link_processFrames(pObj);
break;
default:
Utils_tskAckOrFreeMsg(pMsg, status);
break;
}
}
IpcInM3Link_delete(pObj);
#ifdef SYSTEM_DEBUG_IPC_IN_M3
Vps_printf(" %d: IPC_IN_M3 : Delete Done !!!\n", Utils_getCurTimeInMsec());
#endif
if (ackMsg && pMsg != NULL)
Utils_tskAckOrFreeMsg(pMsg, status);
return;
}
//IpcInM3link接收到資料
Int32 IpcInM3Link_processFrames(IpcInM3Link_Obj * pObj)
{
FVID2_Frame *pFrame;
System_FrameInfo *pFrameInfo;
SystemIpcM3_ListElem *pListElem;
UInt32 numFrames;
Int32 status;
numFrames = 0;
while (1)
{
//取佇列頭從佇列中取 幀資料;
pListElem = ListMP_getHead(pObj->listMPOutHndl);
if (pListElem == NULL)
break;
pFrame = pListElem->pFrame;
UTILS_assert(pFrame != NULL);
pFrameInfo = (System_FrameInfo *) pFrame->appData;
UTILS_assert(pFrameInfo != NULL);
{
pListElem->nextlistElem = pFrameInfo->pOrgListMPElem;
pFrameInfo->pOrgListMPElem = pListElem;
}
// Vps_printf(" %d: %s--%d %p , %p !! Utils_getCurTimeInMsec(),__func__,__LINE__ ,pListElem->frameBuf.addr[0][0]);
//壓入到輸出佇列供下一個link使用
status = Utils_quePut(&pObj->outFrameQue, pFrame, BIOS_NO_WAIT);
UTILS_assert(status == FVID2_SOK);
numFrames++;
}
#ifdef SYSTEM_DEBUG_IPC_RT
Vps_printf(" %d: IPC_IN_M3 : Recevived %d frames !!!\n", Utils_getCurTimeInMsec(),
numFrames);
#endif
//通知下一個link取資料,傳送SYSTEM_CMD_NEW_DATA訊息後,下一個link就會收到一幀資料
if (numFrames && pObj->createArgs.notifyNextLink)
{
UTILS_assert(pObj->createArgs.numOutQue == 1);
System_sendLinkCmd(pObj->createArgs.outQueParams[0].nextLink,
SYSTEM_CMD_NEW_DATA);
}
return FVID2_SOK;
}
在IpcInM3Link_getFullFrames函式中會呼叫Utils_queGet(&pObj->outFrameQue....,從佇列中獲取資料,該函式提供給外部介面使用;
ipcOutM3
在該函式中應該會呼叫 ListMP_getHead獲取資料;
1)IpcOutM3Link_tskMain函式
Void IpcOutM3Link_tskMain(struct Utils_TskHndl * pTsk, Utils_MsgHndl * pMsg)
{
UInt32 cmd = Utils_msgGetCmd(pMsg);
Bool ackMsg, done;
Int32 status;
IpcOutM3Link_Obj *pObj = (IpcOutM3Link_Obj *) pTsk->appData;
if (cmd != SYSTEM_CMD_CREATE)
{
Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);
return;
}
status = IpcOutM3Link_create(pObj, Utils_msgGetPrm(pMsg));
Utils_tskAckOrFreeMsg(pMsg, status);
if (status != FVID2_SOK)
return;
done = FALSE;
ackMsg = FALSE;
while (!done)
{
status = Utils_tskRecvMsg(pTsk, &pMsg, BIOS_WAIT_FOREVER);
if (status != FVID2_SOK)
break;
cmd = Utils_msgGetCmd(pMsg);
switch (cmd)
{
case SYSTEM_CMD_DELETE:
done = TRUE;
ackMsg = TRUE;
break;
case SYSTEM_CMD_NEW_DATA:
Utils_tskAckOrFreeMsg(pMsg, status);
IpcOutM3Link_processFrames(pObj);
IpcOutM3Link_releaseFrames(pObj);
break;
case IPCOUTM3_LINK_CMD_SET_FRAME_RATE:
{
IpcOutM3Link_ChFpsParams *params;
params = (IpcOutM3Link_ChFpsParams *) Utils_msgGetPrm(pMsg);
IpcOutM3Link_SetFrameRate(pObj, params);
Utils_tskAckOrFreeMsg(pMsg, status);
}
break;
case IPCOUTM3_LINK_CMD_PRINT_STATISTICS:
IpcOutM3Link_printStatistics(pObj, TRUE);
Utils_tskAckOrFreeMsg(pMsg, status);
break;
case SYSTEM_IPC_CMD_RELEASE_FRAMES:
Utils_tskAckOrFreeMsg(pMsg, status);
#ifdef SYSTEM_DEBUG_IPC_RT
Vps_printf(" %d: IPC_OUT_M3 : Received Notify !!!\n",
Utils_getCurTimeInMsec());
#endif
IpcOutM3Link_releaseFrames(pObj);
break;
default:
Utils_tskAckOrFreeMsg(pMsg, status);
break;
}
}
IpcOutM3Link_delete(pObj);
#ifdef SYSTEM_DEBUG_IPC_OUT_M3
Vps_printf(" %d: IPC_OUT_M3 : Delete Done !!!\n", Utils_getCurTimeInMsec());
#endif
if (ackMsg && pMsg != NULL)
Utils_tskAckOrFreeMsg(pMsg, status);
return;
}
2)IpcOutM3Link_processFrames
Int32 IpcOutM3Link_processFrames(IpcOutM3Link_Obj * pObj)
{
System_LinkInQueParams *pInQueParams;
FVID2_FrameList frameList;
FVID2_Frame *pFrame;
SystemIpcM3_ListElem *pListElem;
Int32 status;
Int32 frameId;
IpcOutM3Link_ChObj *pChObj;
pInQueParams = &pObj->createArgs.inQueParams;
//從上一個link獲取資料,儲存在frameList中;
System_getLinksFullFrames(pInQueParams->prevLinkId,
pInQueParams->prevLinkQueId, &frameList);
pObj->freeFrameList.numFrames = 0;
if (frameList.numFrames)
{
#ifdef SYSTEM_DEBUG_IPC_RT
Vps_printf(" %d: IPC_OUT_M3 : Received %d frames !!!\n",
Utils_getCurTimeInMsec(), frameList.numFrames);
#endif
pObj->totalFrameCount += frameList.numFrames;
for (frameId = 0; frameId < frameList.numFrames; frameId++)
{
Bool doFrameDrop;
pFrame = frameList.frames[frameId];
pChObj = &pObj->chObj[pFrame->channelNum];
pChObj->inFrameRecvCount++;
doFrameDrop = Utils_doSkipFrame(&(pChObj->frameSkipCtx));
/* frame skipped due to user setting */
if(doFrameDrop)
{
pChObj->inFrameUserSkipCount++;
pObj->freeFrameList.frames[pObj->freeFrameList.numFrames] =
pFrame;
pObj->freeFrameList.numFrames++;
UTILS_assert(pObj->freeFrameList.numFrames <=
FVID2_MAX_FVID_FRAME_PTR);
continue;;
}
//從佇列中獲取一個listElem,從來儲存獲取到的幀資料;
status =
Utils_queGet(&pObj->listElemQue, (Ptr *) & pListElem, 1,
BIOS_NO_WAIT);
if (status != FVID2_SOK)
{
/* normally this condition should not happen, if it happens
* return the frame back to its generator */
#if 0
Vps_printf(" IPC_OUT: Dropping frame\n");
#endif
pObj->freeFrameList.frames[pObj->freeFrameList.numFrames] =
pFrame;
pObj->freeFrameList.numFrames++;
UTILS_assert(pObj->freeFrameList.numFrames <=
FVID2_MAX_FVID_FRAME_PTR);
pChObj->inFrameUserSkipCount++;
continue;
}
pListElem->pFrame = pFrame;
/* no need to do cache ops since this is inter-M3 list */
//插入到佇列尾,
status = ListMP_putTail(pObj->listMPOutHndl, &pListElem->listElem);
UTILS_assert(status == ListMP_S_SUCCESS);
pChObj->inFrameProcessCount++;
}
if (pObj->freeFrameList.numFrames)
{
System_putLinksEmptyFrames(pInQueParams->prevLinkId,
pInQueParams->prevLinkQueId,
&pObj->freeFrameList);
}
//往下一個link傳送通知
if (pObj->createArgs.notifyNextLink)
{
UTILS_assert(pObj->createArgs.numOutQue == 1);
System_ipcSendNotify(pObj->createArgs.outQueParams[0].nextLink);
}
if (TRUE == pObj->createArgs.noNotifyMode)
{
if (FALSE == pObj->prd.clkStarted)
{
IpcOutM3Link_startPrdObj(pObj,
IPC_M3OUT_LINK_DONE_PERIOD_MS, FALSE);
}
}
}
return FVID2_SOK;
}
相關文章
- ../和./和/的區別
- 路徑中./和../和/
- not in 和 not exists 比較和用法
- !=和<>
- #和&
- linux中/bin和/sbin和/usr/bin和/usr/sbinLinux
- redis的安裝和啟動和檢測和停止Redis
- 深度解析 Delegate 和 Notification 和 KVO
- ♻️同步和非同步;並行和併發;阻塞和非阻塞非同步並行
- xftp和xshell,xftp和xshell的下載和安裝FTP
- 找工作學習筆記1------=和==、&和&&、|和||的區別筆記
- workman 和swoole 區別 和異同
- @NotEmpty和@NotBlank和@NotNull小結Null
- 檔案路徑問題( ./ 和 ../ 和 @/ )
- csv和excel讀取和下載Excel
- Cookie 和 Session 關係和區別CookieSession
- 堆和棧的概念和區別
- js中的typeof和instanceof和===JS
- hbase和zookeeper的安裝和部署
- JSF和Struts、Tiles Portlets和TapestryJS
- oracle中關於in和exists,not in 和 not existsOracle
- js == 和 ===JS
- 字首和
- XML基本操作-建立(DOM和LOINQ)和LINQ查詢和儲存XML
- 函式fgets和fputs、fread和fwrite、fscanf和fprintf用法小結函式
- DOORS和Reqtify — 需求管理和需求追溯工具QT
- Golang 陣列和切片 Slice 和 Map 使用Golang陣列
- count (*) 和 count (1) 和 count (列名) 區別
- DOORS 和Reqtify — 需求管理和需求追溯工具QT
- MySQL 裡的 find_in_set () 和 in () 和 likeMySql
- 淺談mouseenter和mouseover,mouseout和mouseleave
- 和AI談倫理、道德和謊言AI
- count(*) 和 count(1)和count(列名)區別
- ssr、ss和vpn介紹和區別
- Redis RDB和AOF取捨和選擇Redis
- 堆和棧的解釋和區別
- DOORS和Reqtify—需求管理和需求追溯工具QT
- lodsb、stosb(和lodsw、stosw和lodsd、stosd指令)