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;
}


 

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐