例子:从A8送一帧jpeg图片到videoM3解码,然后在将解码的数据传递到A8, 这个流程涉及的link源码如下:
- dm8148 link之间数据传递
- 1)在A8上调用IpcBitsOutLink_getEmptyVideoBitStreamBufs从IpcBitsOutLink获取buff;然后调用IpcBitsOutLink_putFullVideoBitStreamBufs将数据送入到IpcBitsOutLink;
- 1.1)IpcBitsOutLink
- A8调用IpcBitsOutLink将压缩数据(jpeg,mpeg4,h264)送入到videoM3;首先在/src_linux\links\system的system_common.c中调用IpcBitsOutLink_init函数;
- //system_init函数在app初始化时调用;
- Int32 System_init()
- {
- Int32 status;
- #ifdef SYSTEM_DEBUG
- OSA_printf ( " %u: SYSTEM: System Common Init in progress !!!\n", OSA_getCurTimeInMsec());
- #endif
- memset(&gSystem_objCommon, 0, sizeof(gSystem_objCommon));
- System_ipcInit();
- IpcBitsInLink_init();
- IpcBitsOutLink_init();
- IpcFramesInLink_init();
- IpcFramesOutLink_init();
- ...........
- status = OSA_mbxCreate(&gSystem_objCommon.mbx);
- UTILS_assert( status==OSA_SOK);
- SystemLink_init();
- #ifdef SYSTEM_DEBUG
- OSA_printf ( " %u: SYSTEM: System Common Init Done !!!\n", OSA_getCurTimeInMsec());
- #endif
- return status;
- }
- 1.2)IpcBitsOutLink_init函数
- Int32 IpcBitsOutLink_init()
- {
- Int32 status;
- System_LinkObj linkObj;
- UInt32 ipcBitsOutId;
- IpcBitsOutLink_Obj *pObj;
- char tskName[32];
- UInt32 procId = System_getSelfProcId();
- OSA_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) == 0);
- OSA_COMPILETIME_ASSERT(offsetof(Bitstream_Buf, reserved) == 0);
- OSA_COMPILETIME_ASSERT(sizeof(((Bitstream_Buf *) 0)->reserved) ==
- sizeof(ListMP_Elem));
- for (ipcBitsOutId = 0; ipcBitsOutId < IPC_BITS_OUT_LINK_OBJ_MAX;
- ipcBitsOutId++)
- {
- pObj = &gIpcBitsOutLink_obj[ipcBitsOutId];
- memset(pObj, 0, sizeof(*pObj));
- pObj->tskId =
- SYSTEM_MAKE_LINK_ID(procId,
- SYSTEM_LINK_ID_IPC_BITS_OUT_0) + ipcBitsOutId;
- linkObj.pTsk = &pObj->tsk;
- linkObj.getLinkInfo = IpcBitsOutLink_getLinkInfo;
- System_registerLink(pObj->tskId, &linkObj);
- OSA_SNPRINTF(tskName, "IPC_BITS_OUT%d", ipcBitsOutId);
- //注册通知
- System_ipcRegisterNotifyCb(pObj->tskId, IpcBitsOutLink_notifyCb);
- //初始化ListMP
- IpcBitsOutLink_initListMP(pObj);
- status = OSA_tskCreate(&pObj->tsk,
- IpcBitsOutLink_tskMain,
- IPC_LINK_TSK_PRI,
- IPC_LINK_TSK_STACK_SIZE, 0, pObj);
- OSA_assert(status == OSA_SOK);
- }
- return status;
- }
- 1.3)IpcBitsOutLink_tskMain函数
- Int IpcBitsOutLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
- Uint32 curState)
- {
- UInt32 cmd = OSA_msgGetCmd(pMsg);
- Bool ackMsg, done;
- Int32 status = IPC_BITSOUT_LINK_S_SUCCESS;
- //appData中保存的是和link相关的参数
- IpcBitsOutLink_Obj *pObj = (IpcBitsOutLink_Obj *) pTsk->appData;
- //SYSTEM_CMD_CREATE为System_linkCreate函数的命令号,如果cmd!=SYSTEM_CMD_CREATE,主函数退出???
- if (cmd != SYSTEM_CMD_CREATE)
- {
- OSA_tskAckOrFreeMsg(pMsg, OSA_EFAIL);
- return status;
- }
- status = IpcBitsOutLink_create(pObj, OSA_msgGetPrm(pMsg));
- OSA_tskAckOrFreeMsg(pMsg, status);
- if (status != OSA_SOK)
- return status;
- done = FALSE;
- ackMsg = FALSE;
- while (!done)
- {
- status = OSA_tskWaitMsg(pTsk, &pMsg);
- if (status != OSA_SOK)
- break;
- cmd = OSA_msgGetCmd(pMsg);
- switch (cmd)
- {
- case SYSTEM_CMD_DELETE:
- done = TRUE;
- ackMsg = TRUE;
- break;
- case SYSTEM_IPC_CMD_RELEASE_FRAMES:
- OSA_tskAckOrFreeMsg(pMsg, status);
- #ifdef SYSTEM_DEBUG_IPC_RT
- OSA_printf(" %d: IPC_BITS_OUT : Received Notify !!!\n",
- OSA_getCurTimeInMsec());
- #endif
- IpcBitsOutLink_releaseBitBufs(pObj);
- break;
- case SYSTEM_CMD_START:
- //link start
- IpcBitsOutLink_start(pObj);
- OSA_tskAckOrFreeMsg(pMsg, status);
- break;
- case SYSTEM_CMD_STOP:
- //link stop
- IpcBitsOutLink_stop(pObj);
- OSA_tskAckOrFreeMsg(pMsg, status);
- break;
- default:
- OSA_tskAckOrFreeMsg(pMsg, status);
- break;
- }
- }
- IpcBitsOutLink_delete(pObj);
- #ifdef SYSTEM_DEBUG_IPC_BITS_OUT
- OSA_printf(" %d: IPC_BITS_OUT : Delete Done !!!\n",
- OSA_getCurTimeInMsec());
- #endif
- if (ackMsg && pMsg != NULL)
- OSA_tskAckOrFreeMsg(pMsg, status);
- return IPC_BITSOUT_LINK_S_SUCCESS;
- }
- 1.4)IpcBitsOutLink_create函数
- Int32 IpcBitsOutLink_create(IpcBitsOutLink_Obj * pObj,
- IpcBitsOutLinkHLOS_CreateParams * pPrm)
- {
- Int32 status;
- UInt32 i;
- #ifdef SYSTEM_DEBUG_IPC
- OSA_printf(" %d: IPC_BITS_OUT : Create in progress !!!\n",
- OSA_getCurTimeInMsec());
- #endif
- memcpy(&pObj->createArgs, pPrm, sizeof(pObj->createArgs));
- for (i=0; i<IPC_LINK_BITS_OUT_MAX_NUM_ALLOC_POOLS; i++)
- {
- OSA_assert(i < IPC_BITS_OUT_MAX_NUM_ALLOC_POOLS);
- if(pObj->createArgs.numBufPerCh[i] == 0)
- pObj->createArgs.numBufPerCh[i] =
- IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH;
- if(pObj->createArgs.numBufPerCh[i] >
- IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH)
- {
- OSA_printf("\n IPCBITSOUTLINK: WARNING: User is asking for %d buffers per CH. But max allowed is %d. \n"
- " Over riding user requested with max allowed \n\n",
- pObj->createArgs.numBufPerCh[i],
- IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH
- );
- pObj->createArgs.numBufPerCh[i] =
- IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH;
- }
- }
- //listMP 队列清空
- status = System_ipcListMPReset(pObj->listMPOutHndl, pObj->listMPInHndl);
- OSA_assert(status == OSA_SOK);
- //分配link的内存
- IpcBitsOutLink_createOutObj(pObj);
- IpcBitsOutLink_initStats(pObj);
- pObj->startProcessing = FALSE;
- #ifdef SYSTEM_DEBUG_IPC
- OSA_printf(" %d: IPC_BITS_OUT : Create Done !!!\n",
- OSA_getCurTimeInMsec());
- #endif
- return IPC_BITSOUT_LINK_S_SUCCESS;
- }
- 1.5)IpcBitsOutLink_createOutObj函数分配该link需要多少内存,link的内存由link自己管理,在建立link时,告诉该link 内存池的个数,每个池中的buff的个数,link自己决定分配多少内存;
- static Int IpcBitsOutLink_createOutObj(IpcBitsOutLink_Obj * pObj)
- {
- Int status = OSA_SOK;
- Int32 poolId, elemId, bufId;
- IHeap_Handle srBitBufHeapHandle;
- UInt32 bufSize, numBufs, totBufSize, cacheLineSize;
- const UInt32 srIndex = SYSTEM_IPC_SR_CACHED;
- Ptr phyAddr;
- ipcbitsoutlink_populate_outbuf_pool_size_info(&pObj->createArgs,
- &pObj->createArgs.inQueInfo,
- &pObj->outQueInfo);
- elemId = 0;
- srBitBufHeapHandle = SharedRegion_getHeap(srIndex);
- OSA_assert(srBitBufHeapHandle != NULL);
- cacheLineSize = SharedRegion_getCacheLineSize(srIndex);
- for (poolId = 0; poolId < pObj->outQueInfo.allocPoolInfo.numPools; poolId++)
- {
- status = OSA_queCreate(&pObj->listElemQue[poolId],
- SYSTEM_IPC_BITS_MAX_LIST_ELEM);
- OSA_assert(status == OSA_SOK);
- bufSize =
- OSA_align(pObj->outQueInfo.allocPoolInfo.bufPoolInfo[poolId].
- bufSize, cacheLineSize);
- numBufs = pObj->outQueInfo.allocPoolInfo.bufPoolInfo[poolId].numBufs;
- //总共需要分配的内存大小
- totBufSize = bufSize * numBufs;
- OSA_printf ("###Bit buff of size from the SR # %d : %d\n", srIndex, totBufSize);
- pObj->bitBufPoolPtr[poolId] =
- Memory_alloc(srBitBufHeapHandle, totBufSize, cacheLineSize, NULL);
- OSA_assert(pObj->bitBufPoolPtr[poolId] != NULL);
- OSA_printf("IPC_BITSOUT:BitBuffer Alloc.PoolID:%d,Size:0x%X",
- poolId,totBufSize);
- phyAddr = IpcBitsOutLink_MapUsrVirt2Phy(pObj->bitBufPoolPtr[poolId]);
- pObj->bitBufPoolSize[poolId] = totBufSize;
- for (bufId = 0; bufId < numBufs; bufId++)
- {
- SystemIpcBits_ListElem *listElem;
- OSA_assert(elemId < SYSTEM_IPC_BITS_MAX_LIST_ELEM);
- listElem = pObj->listElem[elemId];
- elemId++;
- SYSTEM_IPC_BITS_SET_BUFOWNERPROCID(listElem->bufState);
- SYSTEM_IPC_BITS_SET_BUFSTATE(listElem->bufState,
- IPC_BITBUF_STATE_FREE);
- listElem->bitBuf.addr =
- (Ptr) (((UInt32) (pObj->bitBufPoolPtr[poolId])) +
- (bufSize * bufId));
- if (phyAddr)
- {
- listElem->bitBuf.phyAddr =
- (UInt32) ((UInt32) (phyAddr) + (bufSize * bufId));
- }
- listElem->bitBuf.allocPoolID = poolId;
- listElem->bitBuf.bufSize = bufSize;
- listElem->bitBuf.fillLength = 0;
- listElem->bitBuf.mvDataFilledSize = 0;
- listElem->bitBuf.startOffset = 0;
- listElem->bitBuf.bottomFieldBitBufSize = 0;
- listElem->bitBuf.doNotDisplay = FALSE;
- //获取Buf的指针
- listElem->srBufPtr = SharedRegion_getSRPtr(listElem->bitBuf.addr,
- srIndex);
- OSA_assert(listElem->srBufPtr != IPC_LINK_INVALID_SRPTR);
- //将分配的buff挂在插入list队列,使用时,从队列中取empty buff,比如在A8需要将bit数据拷贝传递到IpcBitsOutLink,调用IpcBitsOutLink_getEmptyVideoBitStreamBufs
- (IpcBitsOutLink_getEmptyBufs)从队列中取buff;
- status =
- OSA_quePut(&pObj->listElemQue[poolId], (Int32) listElem,
- OSA_TIMEOUT_NONE);
- OSA_assert(status == OSA_SOK);
- }
- }
- return status;
- }
- 1.6)A8中调用该函数将buff传递IpcBitsOutLink
- Int32 IpcBitsOutLink_putFullVideoBitStreamBufs(UInt32 linkId,
- Bitstream_BufList *bufList)
- {
- OSA_TskHndl * pTsk;
- IpcBitsOutLink_Obj * pObj;
- Int status;
- OSA_assert(bufList != NULL);
- if (!((linkId >= SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0)
- &&
- (linkId < (SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0 + IPC_BITS_OUT_LINK_OBJ_MAX))))
- {
- return IPC_BITSOUT_LINK_E_INVALIDLINKID;
- }
- pTsk = System_getLinkTskHndl(linkId);
- pObj = pTsk->appData;
- //将buff传递到下一个link
- status = IpcBitsOutLink_putFullBufs(pObj,bufList);
- return status;
- }
- 1.7)IpcBitsOutLink_putFullBufs 将buff传递到下一个link,注意IpcBitsOutLink_listMPPut,将buff压入到输出队列,然后发送System_ipcSendNotify 发送通知,通知下一个link来取数据;
- static
- Int32 IpcBitsOutLink_putFullBufs(IpcBitsOutLink_Obj *pObj,
- Bitstream_BufList *pBufList)
- {
- SystemIpcBits_ListElem *pListElem;
- Bitstream_Buf *pBitBuf;
- Bitstream_BufList freeBitBufList;
- Bool putDone = FALSE;
- Int32 bufId;
- UInt32 curTime;
- freeBitBufList.numBufs = 0;
- curTime = OSA_getCurTimeInMsec();
- for (bufId = 0; bufId < pBufList->numBufs; bufId++)
- {
- pBitBuf = pBufList->bufs[bufId];
- curTime = pBitBuf->timeStamp = Get_timeStamp(pBitBuf->channelNum);
- pListElem = (SystemIpcBits_ListElem *)pBitBuf;
- OSA_assert(SharedRegion_getPtr(pListElem->srBufPtr) ==
- pBitBuf->addr);
- if (0 == pBitBuf->fillLength)
- {
- /* filled length of 0 indicates application
- * did not fill any data in this buffer.
- * Free it immediately */
- #ifdef SYSTEM_DEBUG_IPC_RT
- OSA_printf(" IPC_OUT: Dropping bitbuf\n");
- #endif
- OSA_assert(freeBitBufList.numBufs <
- VIDBITSTREAM_MAX_BITSTREAM_BUFS);
- freeBitBufList.bufs[freeBitBufList.numBufs] = pBitBuf;
- freeBitBufList.numBufs++;
- pObj->stats.droppedCount++;
- continue;
- }
- else
- {
- pObj->stats.recvCount++;
- OSA_assert(SYSTEM_IPC_BITS_GET_BUFSTATE(pListElem->bufState)
- == IPC_BITBUF_STATE_FREE);
- OSA_assert(SYSTEM_IPC_BITS_GET_BUFOWNERPROCID(pListElem->bufState)
- == System_getSelfProcId());
- pListElem->ipcPrivData = (Ptr) curTime;
- SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,
- IPC_BITBUF_STATE_ALLOCED);
- //压入到输出队列
- IpcBitsOutLink_listMPPut(pObj, pListElem);
- putDone = TRUE;
- }
- }
- if (freeBitBufList.numBufs)
- {
- IpcBitsOutLink_putEmptyBufs(pObj, &freeBitBufList);
- }
- if (putDone && (pObj->createArgs.baseCreateParams.notifyNextLink))
- {
- //通知下一个link,调用Notify_sendEvent函数
- System_ipcSendNotify(pObj->createArgs.baseCreateParams.outQueParams[0].
- nextLink);
- }
- if (!putDone)
- {
- pObj->stats.numNoFullBufCount++;
- if ((pObj->stats.numNoFullBufCount % IPC_BITSOUT_STATS_WARN_INTERVAL) == 0)
- {
- #ifdef DEBUG_IPC_BITS
- OSA_printf("IPCBITSOUT:!!!WARNING.!!! NO FULL BUF AVAILABLE. OCCURENCE COUNT:[%d]",
- pObj->stats.numNoFullBufCount);
- #endif
- }
- }
- return IPC_BITSOUT_LINK_S_SUCCESS;
- }
- 1.8)IpcBitsOutLink_listMPPut 函数
- static
- Int32 IpcBitsOutLink_listMPPut(IpcBitsOutLink_Obj * pObj,
- SystemIpcBits_ListElem * pListElem)
- {
- Int32 status = IPC_BITSOUT_LINK_S_SUCCESS;
- SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState, IPC_BITBUF_STATE_OUTQUE);
- //cache 多核之间数据拷贝,传递到ipcbitsIn(videoM3) link
- IpcBitsOutLink_doPrePutCacheOp(pObj, pListElem);
- status = ListMP_putTail(pObj->listMPOutHndl, (ListMP_Elem *) pListElem);
- OSA_assert(status == ListMP_S_SUCCESS);
- return IPC_BITSOUT_LINK_S_SUCCESS;
- }
- 1.9)IpcBitsOutLink_doPrePutCacheOp 函数;
- static
- Int32 IpcBitsOutLink_doPrePutCacheOp(IpcBitsOutLink_Obj * pObj,
- SystemIpcBits_ListElem * pListElem)
- {
- if (pListElem->bitBuf.fillLength)
- {
- Cache_wbInv(pListElem->bitBuf.addr,
- pListElem->bitBuf.fillLength, Cache_Type_ALL, TRUE);
- }
- /* No cache ops done since pListElem is allocated from non-cached memory */
- UTILS_assert(SharedRegion_isCacheEnabled(SharedRegion_getId(pListElem)) ==
- FALSE);
- return IPC_BITSOUT_LINK_S_SUCCESS;
- }
- ListMP_putTail 和ListMP_getHead 作用,多核之间用吗?相邻2个核之间的link公用一个ListMp队列吗?ipcBitsOutLink(A8)发送通知Notify_sendEvent告诉ipcBitsInLink(videoM3),在
- ListMP队列已经存在数据;
- ListMP实现了多宿主双向循环链表,即该双向循环链表为多个处理器共同拥有,可以由多个处理器共同维护,共同使用。
- ListMP的实现区别于一般的双向循环链表,因此它不仅具有双向循环链表的特性外,还增添了其他的特性,比如以下几点:
- 1.实现了简单的多宿主协议,支持多个读写者(multi-reader、multi-writee);
- 2.使用Gate作为内部保护机制,防止多个宿主处理器同时访问该链表;
- ListMP的实现并未加入通知机制,如果需要的话,可以在外部封装是引入Notify机制来实现;使用ListMP机制来管理的buffers都需要从共享内存区分配,包括从堆内存分配的buffers以及动
- 态分配的内存。
- 2)videoM3 systemLink 多核之间数据传递要用到systemlink,以下是videoM3中systemLink的初始化函数;主要有IpcOutM3Link_init()函数和IpcInM3Link_init()函数;
- mcfw/src_bios6/links_m3video/system ;system_m3video.c
- Int32 System_init()
- {
- Int32 status = FVID2_SOK;
- #ifdef SYSTEM_DEBUG
- Vps_printf(" %d: SYSTEM : System Video Init in progress !!!\n",
- Utils_getCurTimeInMsec());
- #endif
- #ifdef SYSTEM_DEBUG
- Vps_printf(" %d: SYSTEM : System Video Init Done !!!\n", Utils_getCurTimeInMsec());
- #endif
- IpcOutM3Link_init();
- IpcInM3Link_init();
- IpcBitsInLink_init();
- IpcBitsOutLink_init();
- IpcFramesInLink_init();
- IpcFramesOutLink_init();
- Utils_encdecInit();
- //编解码link初始化
- System_initLinks();
- return status;
- }
- 3)IpcBitsInLink(mcfw_bios6)
- 3.1)初始化函数
- Int32 IpcBitsInLink_init()
- {
- Int32 status;
- System_LinkObj linkObj;
- UInt32 ipcBitsInId;
- IpcBitsInLink_Obj *pObj;
- char tskName[32];
- UInt32 procId = System_getSelfProcId();
- UTILS_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) == 0);
- UTILS_COMPILETIME_ASSERT(offsetof(Bitstream_Buf, reserved) == 0);
- UTILS_COMPILETIME_ASSERT(sizeof(((Bitstream_Buf *) 0)->reserved) ==
- sizeof(ListMP_Elem));
- for (ipcBitsInId = 0; ipcBitsInId < IPC_BITS_IN_LINK_OBJ_MAX; ipcBitsInId++)
- {
- pObj = &gIpcBitsInLink_obj[ipcBitsInId];
- memset(pObj, 0, sizeof(*pObj));
- pObj->tskId =
- SYSTEM_MAKE_LINK_ID(procId,
- SYSTEM_LINK_ID_IPC_BITS_IN_0) + ipcBitsInId;
- pObj->state = IPC_BITS_IN_LINK_STATE_INACTIVE;
- linkObj.pTsk = &pObj->tsk;
- linkObj.linkGetFullFrames = NULL;
- linkObj.linkPutEmptyFrames = NULL;
- linkObj.linkGetFullBitBufs = IpcBitsInLink_getFullBitBufs;
- linkObj.linkPutEmptyBitBufs = IpcBitsInLink_putEmptyBitBufs;
- linkObj.getLinkInfo = IpcBitsInLink_getLinkInfo;
- System_registerLink(pObj->tskId, &linkObj);
- UTILS_SNPRINTF(tskName, "IPC_BITS_IN%d", ipcBitsInId);
- System_ipcRegisterNotifyCb(pObj->tskId, IpcBitsInLink_notifyCb);
- status = Utils_tskCreate(&pObj->tsk,
- IpcBitsInLink_tskMain,
- IPC_LINK_TSK_PRI,
- gIpcBitsInLink_tskStack[ipcBitsInId],
- IPC_LINK_TSK_STACK_SIZE, pObj, tskName);
- UTILS_assert(status == FVID2_SOK);
- }
- return status;
- }
- 3.2)IpcBitsInLink_tskMain 主函数
- Void IpcBitsInLink_tskMain(struct Utils_TskHndl * pTsk, Utils_MsgHndl * pMsg)
- {
- UInt32 cmd = Utils_msgGetCmd(pMsg);
- Bool ackMsg, done;
- Int32 status;
- IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) pTsk->appData;
- if (cmd != SYSTEM_CMD_CREATE)
- {
- Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);
- return;
- }
- //ListMP 和队列资源初始化
- status = IpcBitsInLink_create(pObj, Utils_msgGetPrm(pMsg));
- Utils_tskAckOrFreeMsg(pMsg, status);
- if (status != FVID2_SOK)
- return;
- done = FALSE;
- ackMsg = FALSE;
- while (!done)
- {
- //接收消息,是接收从ipcbitsOutlink(A8)
- 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:
- //从IpcInM3 Link获取消息
- Utils_tskAckOrFreeMsg(pMsg, status);
- IpcBitsInLink_processBitBufs(pObj);
- break;
- case SYSTEM_CMD_STOP:
- IpcBitsInLink_stop(pObj);
- Utils_tskAckOrFreeMsg(pMsg, status);
- break;
- default:
- Utils_tskAckOrFreeMsg(pMsg, status);
- break;
- }
- }
- IpcBitsInLink_delete(pObj);
- #ifdef SYSTEM_DEBUG_IPC_BITS_IN
- Vps_printf(" %d: IPC_BITS_IN : Delete Done !!!\n", Utils_getCurTimeInMsec());
- #endif
- if (ackMsg && pMsg != NULL)
- Utils_tskAckOrFreeMsg(pMsg, status);
- return;
- }
- 3.3)IpcBitsInLink_processBitBufs函数
- Int32 IpcBitsInLink_processBitBufs(IpcBitsInLink_Obj * pObj)
- {
- Bitstream_Buf *pBitBuf;
- SystemIpcBits_ListElem *pListElem;
- UInt32 numBitBufs;
- Int32 status;
- UInt32 curTime;
- numBitBufs = 0;
- curTime = Utils_getCurTimeInMsec();
- while (1)
- {
- //获取listElem,多核之间获取数据;
- pListElem = ListMP_getHead(pObj->listMPOutHndl);
- if (pListElem == NULL)
- break;
- //转化为bitbuff
- IpcBitsInLink_getBitBuf(pObj, pListElem, &pBitBuf);
- UTILS_assert(SYSTEM_IPC_BITS_GET_BUFSTATE(pListElem->bufState)
- == IPC_BITBUF_STATE_OUTQUE);
- pBitBuf->reserved[0] = curTime;
- SYSTEM_IPC_BITS_SET_BUFOWNERPROCID(pListElem->bufState);
- SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,
- IPC_BITBUF_STATE_DEQUEUED);
- pObj->stats.recvCount++;
- //压入到输出队列;
- status = Utils_quePut(&pObj->outBitBufQue, pBitBuf, BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- numBitBufs++;
- }
- #ifdef SYSTEM_DEBUG_IPC_RT
- Vps_printf(" %d: IPC_BITS_IN : Recevived %d bitbufs !!!\n",
- Utils_getCurTimeInMsec(), numBitBufs);
- #endif
- //给下一个link发送消息
- if (numBitBufs && pObj->createArgs.baseCreateParams.notifyNextLink)
- {
- UTILS_assert(pObj->createArgs.baseCreateParams.numOutQue == 1);
- System_sendLinkCmd(pObj->createArgs.baseCreateParams.outQueParams[0].
- nextLink, SYSTEM_CMD_NEW_DATA);
- }
- return IPC_BITS_IN_LINK_S_SUCCESS;
- }
- 4)VideoM3 declink
- 4.1)解码link初始化函数
- Int32 DecLink_init()
- {
- Int32 status;
- System_LinkObj linkObj;
- DecLink_Obj *pObj;
- char name[32];
- UInt32 objId;
- for (objId = 0; objId < DEC_LINK_OBJ_MAX; objId++)
- {
- pObj = &gDecLink_obj[objId];
- memset(pObj, 0, sizeof(*pObj));
- pObj->linkId = SYSTEM_LINK_ID_VDEC_0 + objId;
- linkObj.pTsk = &pObj->tsk;
- linkObj.linkGetFullFrames = DecLink_getFullFrames;
- linkObj.linkPutEmptyFrames = DecLink_putEmptyFrames;
- linkObj.linkGetFullBitBufs = NULL;
- linkObj.linkPutEmptyBitBufs = NULL;
- linkObj.getLinkInfo = DecLink_getInfo;
- UTILS_SNPRINTF(name, "DEC%d ", objId);
- System_registerLink(pObj->linkId, &linkObj);
- status = Utils_tskCreate(&pObj->tsk,
- DecLink_tskMain,
- DEC_LINK_TSK_PRI,
- gDecLink_tskStack[objId],
- DEC_LINK_TSK_STACK_SIZE, pObj, name);
- UTILS_assert(status == FVID2_SOK);
- }
- return status;
- }
- 4.2)DecLink_tskMain 主函数
- Void DecLink_tskMain(struct Utils_TskHndl *pTsk, Utils_MsgHndl * pMsg)
- {
- UInt32 cmd = Utils_msgGetCmd(pMsg);
- Bool ackMsg, done;
- Int32 status;
- DecLink_Obj *pObj;
- UInt32 flushCmds[2];
- pObj = (DecLink_Obj *) pTsk->appData;
- if (cmd != SYSTEM_CMD_CREATE)
- {
- #ifndef DEC_LINK_SUPRESS_ERROR_AND_RESET
- DECLINK_INTERNAL_ERROR_LOG(DEC_LINK_E_INVALIDCMD,
- "Link create should be first cmd."
- "Received Cmd:%d", cmd);
- #endif
- Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);
- return;
- }
- //分配link的内存等资源,创建解码线程(调用该函数DecLink_codecCreateProcessTsk(pObj, tskId);)
- status = DecLink_codecCreate(pObj, Utils_msgGetPrm(pMsg));
- Utils_tskAckOrFreeMsg(pMsg, status);
- if (status != FVID2_SOK)
- return;
- Utils_encdecHdvicpPrfInit();
- 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_NEW_DATA:
- Utils_tskAckOrFreeMsg(pMsg, status);
- flushCmds[0] = SYSTEM_CMD_NEW_DATA;
- Utils_tskFlushMsg(pTsk, flushCmds, 1);
- //link收到数据,调用该函数进行解码
- DecLink_codecProcessData(pObj);
- break;
- case DEC_LINK_CMD_GET_PROCESSED_DATA:
- Utils_tskAckOrFreeMsg(pMsg, status);
- flushCmds[0] = DEC_LINK_CMD_GET_PROCESSED_DATA;
- Utils_tskFlushMsg(pTsk, flushCmds, 1);
- DecLink_codecGetProcessedDataMsgHandler(pObj);
- break;
- case DEC_LINK_CMD_PRINT_IVAHD_STATISTICS:
- Utils_tskAckOrFreeMsg(pMsg, status);
- Utils_encdecHdvicpPrfPrint();
- break;
- case DEC_LINK_CMD_PRINT_STATISTICS:
- DecLink_printStatistics(pObj, TRUE);
- Utils_tskAckOrFreeMsg(pMsg, status);
- break;
- case DEC_LINK_CMD_PRINT_BUFFER_STATISTICS:
- Utils_tskAckOrFreeMsg(pMsg, status);
- DecLink_printBufferStatus(pObj);
- break;
- case DEC_LINK_CMD_DISABLE_CHANNEL:
- {
- DecLink_ChannelInfo *params;
- params = (DecLink_ChannelInfo *) Utils_msgGetPrm(pMsg);
- DecLink_codecDisableChannel(pObj, params);
- Utils_tskAckOrFreeMsg(pMsg, status);
- }
- break;
- case DEC_LINK_CMD_ENABLE_CHANNEL:
- {
- DecLink_ChannelInfo *params;
- params = (DecLink_ChannelInfo *) Utils_msgGetPrm(pMsg);
- DecLink_codecEnableChannel(pObj, params);
- Utils_tskAckOrFreeMsg(pMsg, status);
- }
- break;
- case DEC_LINK_CMD_SET_TRICKPLAYCONFIG:
- {
- DecLink_TPlayConfig * params;
- params = (DecLink_TPlayConfig *) Utils_msgGetPrm(pMsg);
- DecLink_setTPlayConfig(pObj, params);
- Utils_tskAckOrFreeMsg(pMsg, status);
- }
- break;
- case SYSTEM_CMD_STOP:
- DecLink_codecStop(pObj);
- Utils_tskAckOrFreeMsg(pMsg, status);
- break;
- case SYSTEM_CMD_DELETE:
- DecLink_codecStop(pObj);
- done = TRUE;
- ackMsg = TRUE;
- break;
- default:
- Utils_tskAckOrFreeMsg(pMsg, status);
- break;
- }
- }
- DecLink_codecDelete(pObj);
- if (ackMsg && pMsg != NULL)
- Utils_tskAckOrFreeMsg(pMsg, status);
- return;
- }
- 4.3)DecLink_codecProcessData函数从上一个link中获取bit数据,调用videoM3的解码器进行解码;
- Int32 DecLink_codecProcessData(DecLink_Obj * pObj)
- {
- Int32 status;
- pObj->newDataProcessOnFrameFree = FALSE;
- DecLink_codecQueueBufsToChQue(pObj);
- do
- {
- status = DecLink_codecSubmitData(pObj);
- } while (status == FVID2_SOK);
- return FVID2_SOK;
- }
- 4.4)DecLink_codecQueueBufsToChQue调用System_getLinksFullBufs从prelink中获取bit数据,保存在BitStream_Buf结构中;
- static Int32 DecLink_codecQueueBufsToChQue(DecLink_Obj * pObj)
- {
- UInt32 bufId, freeBufNum;
- Bitstream_Buf *pBuf;
- System_LinkInQueParams *pInQueParams;
- Bitstream_BufList bufList;
- DecLink_ChObj *pChObj;
- Int32 status;
- UInt32 curTime;
- pInQueParams = &pObj->createArgs.inQueParams;
- System_getLinksFullBufs(pInQueParams->prevLinkId,
- pInQueParams->prevLinkQueId, &bufList);
- if (bufList.numBufs)
- {
- pObj->inBufGetCount += bufList.numBufs;
- freeBufNum = 0;
- curTime = Utils_getCurTimeInMsec();
- for (bufId = 0; bufId < bufList.numBufs; bufId++)
- {
- pBuf = bufList.bufs[bufId];
- pChObj = &pObj->chObj[pBuf->channelNum];
- pChObj->inFrameRecvCount++;
- // pBuf->fid = pChObj->nextFid;
- if(pChObj->disableChn && pChObj->skipFrame == FALSE)
- {
- pChObj->skipFrame = TRUE;
- }
- else if((pChObj->disableChn == FALSE) && pChObj->skipFrame)
- {
- if(pBuf->isKeyFrame == TRUE)
- {
- pChObj->skipFrame = FALSE;
- }
- }
- if (((pChObj->IFrameOnlyDecode) &&
- (!pBuf->isKeyFrame)) || pChObj->skipFrame)
- {
- pChObj->inBufSkipCount++;
- pChObj->inFrameUserSkipCount++;
- // Drop if not a I frame
- bufList.bufs[freeBufNum] = pBuf;
- freeBufNum++;
- }
- else
- {
- pChObj->totalInFrameCnt++;
- if (pChObj->totalInFrameCnt > DEC_LINK_STATS_START_THRESHOLD)
- {
- pChObj->totalFrameIntervalTime +=
- (curTime - pChObj->prevFrmRecvTime);
- }
- else
- {
- pChObj->totalFrameIntervalTime = 0;
- pChObj->totalProcessTime = 0;
- DecLink_resetStatistics(pObj);
- }
- pChObj->prevFrmRecvTime = curTime;
- //将buff压入队列提供解码器
- status = Utils_quePut(&pChObj->inQue, pBuf, BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- pChObj->inBufQueCount++;
- }
- }
- if (freeBufNum)
- {
- bufList.numBufs = freeBufNum;
- System_putLinksEmptyBufs(pInQueParams->prevLinkId,
- pInQueParams->prevLinkQueId, &bufList);
- pObj->inBufPutCount += freeBufNum;
- }
- }
- return FVID2_SOK;
- }
- 4.5)System_getLinksFullBufs函数调用systemLink api(pTsk->linkGetFullBitBufs函数)从上一个link获取bit码流数据
- Int32 System_getLinksFullBufs(UInt32 linkId, UInt16 queId,
- Bitstream_BufList * pBufList)
- {
- System_LinkObj *pTsk;
- linkId = SYSTEM_GET_LINK_ID(linkId);
- UTILS_assert(linkId < SYSTEM_LINK_ID_MAX);
- pTsk = &gSystem_objCommon.linkObj[linkId];
- if (pTsk->linkGetFullBitBufs != NULL)
- return pTsk->linkGetFullBitBufs(pTsk->pTsk, queId, pBufList);
- return FVID2_EFAIL;
- }
- 4.6)DecLink_codecSubmitData对bit数据进行解码
- static Int32 DecLink_codecSubmitData(DecLink_Obj * pObj)
- {
- DecLink_ReqObj *pReqObj;
- DecLink_ChObj *pChObj;
- UInt32 chCount,chIdIndex, numProcessCh;
- Bitstream_Buf *pInBuf;
- FVID2_Frame *pOutFrame;
- Int32 status = FVID2_EFAIL, numReqObjPerProcess;
- UInt32 tskId, i;
- static UInt32 startChID = 0;
- System_FrameInfo *pOutFrameInfo;
- UInt32 curTime = Utils_getCurTimeInMsec();
- numProcessCh = 0;
- chIdIndex = startChID;
- for (chCount = 0; chCount < pObj->inQueInfo.numCh; chCount++,chIdIndex++)
- {
- numReqObjPerProcess = 0;
- if (chIdIndex >= pObj->inQueInfo.numCh)
- chIdIndex = 0;
- pChObj = &pObj->chObj[chIdIndex];
- if (Utils_queIsEmpty(&pObj->outObj.bufOutQue.
- emptyQue[pChObj->allocPoolID]))
- {
- pObj->newDataProcessOnFrameFree = TRUE;
- }
- while(numReqObjPerProcess < pChObj->numReqObjPerProcess) {
- numReqObjPerProcess++;
- status =
- Utils_queGet(&pObj->reqQue, (Ptr *) & pReqObj, 1,
- BIOS_NO_WAIT);
- if (UTILS_ISERROR(status)) {
- break;
- }
- pObj->reqQueCount++;
- UTILS_assert(DEC_LINK_MAX_REQ >= pObj->reqQueCount);
- tskId = pObj->ch2ProcessTskId[chIdIndex];
- if (pChObj->algObj.algCreateParams.fieldMergeDecodeEnable)
- {
- /* pReqObj->OutFrameList.numFrames should be set to 2 once */
- /* codec has support to consume 2 output pointers rather than */
- /* just one pointer with 2 contigous fields in field merged */
- /* interlaced decode use case. */
- pReqObj->OutFrameList.numFrames = 1;
- }
- else
- {
- pReqObj->OutFrameList.numFrames = 1;
- }
- if ((status == FVID2_SOK) &&
- (pChObj->inBufQueCount) &&
- (Utils_queGetQueuedCount(&pObj->outObj.bufOutQue.emptyQue[pChObj->
- allocPoolID]) >= pReqObj->OutFrameList.numFrames) &&
- !(Utils_queIsFull(&pObj->decProcessTsk[tskId].processQue)))
- {
- for (i=0; i<pReqObj->OutFrameList.numFrames; i++)
- {
- pOutFrame = NULL;
- status =
- Utils_bufGetEmptyFrameExt(&pObj->outObj.bufOutQue,
- &pOutFrame,
- pObj->outObj.ch2poolMap[chIdIndex],
- BIOS_NO_WAIT);
- if (pOutFrame)
- {
- declink_codec_init_outframe(pObj, chIdIndex, pOutFrame);
- pReqObj->OutFrameList.frames[i] = pOutFrame;
- }
- else
- {
- break;
- }
- }
- if ((status == FVID2_SOK) && (pOutFrame))
- {
- //获取待解码的数据
- Utils_queGet(&pChObj->inQue, (Ptr *) & pInBuf, 1, BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- pReqObj->InBuf = pInBuf;
- pChObj->inBufQueCount--;
- for (i=0; i<pReqObj->OutFrameList.numFrames; i++)
- {
- pReqObj->OutFrameList.frames[i]->channelNum =
- pInBuf->channelNum;
- //pInBuf->timeStamp = curTime;
- pReqObj->OutFrameList.frames[i]->timeStamp=
- pInBuf->timeStamp;
- pOutFrameInfo = (System_FrameInfo *) pReqObj->OutFrameList.frames[i]->appData;
- pOutFrameInfo->ts64 = (UInt32)pInBuf->upperTimeStamp;
- pOutFrameInfo->ts64 <<= 32;
- pOutFrameInfo->ts64 = pOutFrameInfo->ts64 | ((UInt32)pInBuf->lowerTimeStamp);
- }
- numProcessCh++;
- //插入到解码处理队列
- status =
- Utils_quePut(&pObj->decProcessTsk[tskId].processQue,
- pReqObj, BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- pChObj->processReqestCount++;
- }
- else
- {
- status = Utils_quePut(&pObj->reqQue, pReqObj, BIOS_NO_WAIT);
- startChID = chIdIndex;
- UTILS_assert(status == FVID2_SOK);
- pObj->reqQueCount--;
- status = FVID2_EFAIL;
- continue;
- }
- }
- else
- {
- status = Utils_quePut(&pObj->reqQue, pReqObj, BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- pObj->reqQueCount--;
- startChID = chIdIndex;
- status = FVID2_EFAIL;
- if (Utils_queIsEmpty(&pObj->outObj.bufOutQue.
- emptyQue[pChObj->allocPoolID]))
- {
- pObj->newDataProcessOnFrameFree = TRUE;
- }
- }
- }
- }
- return status;
- }
- 4.7)DecLink_codecCreateProcessTsk函数
- 该函数为解码任务函数;从pObj->decProcessTsk[tskId].processQue队列中获取数据,然后进行解码;
- static Void DecLink_codecProcessTskFxn(UArg arg1, UArg arg2)
- {
- Int32 status, chId, i, j;
- DecLink_Obj *pObj;
- DecLink_ChObj *pChObj;
- DecLink_ReqObj *pReqObj;
- FVID2_FrameList freeFrameList;
- UInt32 tskId;
- pObj = (DecLink_Obj *) arg1;
- tskId = (UInt32) arg2;
- while (pObj->state != SYSTEM_LINK_STATE_STOP)
- {
- pObj->reqObjBatch[tskId].numReqObjsInBatch = 0;
- status = DEC_LINK_S_SUCCESS;
- //从队列中获取待解码的数据
- status = Utils_queGet(&pObj->decProcessTsk[tskId].processQue,
- (Ptr *) & pReqObj, 1, BIOS_WAIT_FOREVER);
- if (!UTILS_ISERROR(status))
- {
- status = DecLink_PrepareBatch (pObj, tskId, pReqObj,
- &pObj->reqObjBatch[tskId]);
- if (UTILS_ISERROR(status))
- {
- UTILS_warn("DEC : IVAHDID : %d ENCLINK:ERROR in "
- "DecLink_SubmitBatch.Status[%d]", tskId, status);
- }
- else
- {
- /*Log Batch size statistics*/
- pObj->batchStatistics[tskId].numBatchesSubmitted++;
- pObj->batchStatistics[tskId].currentBatchSize = pObj->
- reqObjBatch[tskId].numReqObjsInBatch;
- if (pObj->batchStatistics[tskId].maxAchievedBatchSize <
- pObj->batchStatistics[tskId].currentBatchSize)
- {
- pObj->batchStatistics[tskId].maxAchievedBatchSize =
- pObj->batchStatistics[tskId].currentBatchSize;
- }
- pObj->batchStatistics[tskId].aggregateBatchSize =
- pObj->batchStatistics[tskId].aggregateBatchSize +
- pObj->batchStatistics[tskId].currentBatchSize;
- pObj->batchStatistics[tskId].averageBatchSize =
- pObj->batchStatistics[tskId].aggregateBatchSize /
- pObj->batchStatistics[tskId].numBatchesSubmitted;
- }
- }
- freeFrameList.numFrames = 0;
- if (pObj->reqObjBatch[tskId].numReqObjsInBatch)
- {
- /*Its made sure that for every batch created all ReqObj have the same
- codec. And every Request Batch has atleast one ReqObj */
- chId = pObj->reqObjBatch[tskId].pReqObj[0]->InBuf->channelNum;
- pChObj = &pObj->chObj[chId];
- switch (pChObj->algObj.algCreateParams.format)
- {
- case IVIDEO_H264BP:
- case IVIDEO_H264MP:
- case IVIDEO_H264HP:
- status =
- Declink_h264DecodeFrameBatch(pObj,
- &pObj->reqObjBatch[tskId],
- &freeFrameList, tskId);
- if (UTILS_ISERROR(status))
- {
- #ifndef DEC_LINK_SUPRESS_ERROR_AND_RESET
- /*
- UTILS_warn("DECLINK:ERROR in "
- "Declink_h264DecodeFrameBatch.Status[%d]", status);
- */
- #endif
- }
- break;
- case IVIDEO_MPEG4SP:
- case IVIDEO_MPEG4ASP:
- status = Declink_mpeg4DecodeFrameBatch(pObj,
- &pObj->reqObjBatch[tskId],
- &freeFrameList);
- if (UTILS_ISERROR(status))
- {
- #ifndef DEC_LINK_SUPRESS_ERROR_AND_RESET
- UTILS_warn("DECLINK:ERROR in "
- "Declink_mpeg4DecodeFrameBatch.Status[%d]", status);
- #endif
- }
- break;
- case IVIDEO_MJPEG:
- //调用该函数进行解码
- status =
- Declink_jpegDecodeFrameBatch(pObj,
- &pObj->reqObjBatch[tskId],
- &freeFrameList);
- if (UTILS_ISERROR(status))
- {
- UTILS_warn("DECLINK:ERROR in "
- "Declink_jpegDecodeFrameBatch.Status[%d]", status);
- }
- break;
- default:
- UTILS_assert(FALSE);
- }
- }
- for (i = 0; i < pObj->reqObjBatch[tskId].numReqObjsInBatch; i++)
- {
- pReqObj = pObj->reqObjBatch[tskId].pReqObj[i];
- for (j = 0; j < pReqObj->OutFrameList.numFrames; j++)
- {
- FVID2_Frame *displayFrame;
- DecLink_codecGetDisplayFrame(pObj,
- pReqObj->OutFrameList.frames[j],
- &freeFrameList, &displayFrame);
- pReqObj->OutFrameList.frames[j] = displayFrame;
- }
- //将解码后的数据插入到队列,主函数会调用DecLink_codecGetProcessedDataMsgHandler函数对数据进行处理,发给下一个link;
- status = Utils_quePut(&pObj->processDoneQue, pReqObj,
- BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- }
- DecLink_codecFreeProcessedFrames(pObj, &freeFrameList);
- }
- return;
- }
- 4.8)jpeg解码函数(Declink_jpegDecodeFrameBatch)如下:
- Int32 Declink_jpegDecodeFrameBatch(DecLink_Obj * pObj,
- DecLink_ReqBatch * pReqObjBatch,
- FVID2_FrameList * freeFrameList)
- {
- int error = XDM_EFAIL, reqObjIdx, chId;
- Int32 i, freeBufIdx, prosIdx;
- IJPEGVDEC_InArgs *inArgs;
- IJPEGVDEC_OutArgs *outArgs;
- XDM2_BufDesc *inputBufDesc;
- XDM2_BufDesc *outputBufDesc;
- IJPEGVDEC_Handle handle;
- IALG_Fxns *fxns = NULL;
- FVID2_Frame *outFrame = NULL;
- IVIDEO2_BufDesc *displayBufs = NULL;
- UInt32 bytesConsumed;
- DecLink_ReqObj *pReqObj;
- DecLink_ChObj *pChObj;
- System_FrameInfo *pFrameInfo;
- /*Make sure that the Req Object is not empty*/
- UTILS_assert (pReqObjBatch->numReqObjsInBatch > 0);
- for (reqObjIdx = 0; reqObjIdx < pReqObjBatch->numReqObjsInBatch; reqObjIdx++)
- {
- pReqObj = pReqObjBatch->pReqObj[reqObjIdx];
- chId = pReqObj->InBuf->channelNum;
- pChObj = &pObj->chObj[chId];
- inArgs = &pChObj->algObj.u.jpegAlgIfObj.inArgs;
- outArgs = &pChObj->algObj.u.jpegAlgIfObj.outArgs;
- inputBufDesc = &pChObj->algObj.u.jpegAlgIfObj.inBufs;
- outputBufDesc = &pChObj->algObj.u.jpegAlgIfObj.outBufs;
- handle = pChObj->algObj.u.jpegAlgIfObj.algHandle;
- UTILS_assert(handle != NULL);
- fxns = (IALG_Fxns *) handle->fxns;
- //IRESMAN_HDVICP2_EarlyAcquire((IALG_Handle) handle,
- // pChObj->algObj.u.jpegAlgIfObj.ivaChID);
- bytesConsumed = 0;
- for (prosIdx=0; prosIdx< pReqObj->OutFrameList.numFrames; prosIdx++)
- {
- /*----------------------------------------------------------------*/
- /* Initialize the input ID in input arguments to the bufferid of */
- /* buffer element returned from getfreebuffer() function. */
- /*----------------------------------------------------------------*/
- /* inputID & numBytes need to update before every decode call */
- if (FALSE == outArgs->viddecOutArgs.outBufsInUseFlag)
- {
- outFrame = pReqObj->OutFrameList.frames[prosIdx];
- }
- else
- {
- UTILS_assert(NULL != pChObj->algObj.prevOutFrame);
- /* Previous buffer was in use. Free the current outBuf */
- outFrame = pChObj->algObj.prevOutFrame;
- freeFrameList->frames[freeFrameList->numFrames] =
- pReqObj->OutFrameList.frames[prosIdx];
- pChObj->numBufsInCodec--;
- freeFrameList->numFrames++;
- }
- inArgs->viddecInArgs.inputID = (UInt32) outFrame;
- inArgs->viddecInArgs.numBytes = pReqObj->InBuf->fillLength -
- bytesConsumed;
- for (i = 0; i < inputBufDesc->numBufs; i++)
- {
- /* Set proper buffer addresses for bitstreamn data */
- /*---------------------------------------------------------------*/
- inputBufDesc->descs[i].buf = (XDAS_Int8 *) pReqObj->InBuf->addr
- + bytesConsumed;
- inputBufDesc->descs[i].bufSize.bytes = pReqObj->InBuf->bufSize;
- }
- for (i = 0; i < outputBufDesc->numBufs; i++)
- {
- /* Set proper buffer addresses for Frame data */
- /*------------------------------------------------------------*/
- if (pChObj->algObj.algCreateParams.tilerEnable)
- {
- outputBufDesc->descs[i].buf =
- (Ptr)
- Utils_tilerAddr2CpuAddr((UInt32) (outFrame->addr[0][i]));
- }
- else
- {
- outputBufDesc->descs[i].buf = outFrame->addr[0][i];
- }
- }
- fxns->algActivate((IALG_Handle) handle);
- //调用visa api进行jpeg解码
- error = handle->fxns->ividdec.process((IVIDDEC3_Handle) handle,
- inputBufDesc,
- outputBufDesc,
- (IVIDDEC3_InArgs *) inArgs,
- (IVIDDEC3_OutArgs *) outArgs);
- fxns->algDeactivate((IALG_Handle) handle);
- bytesConsumed = outArgs->viddecOutArgs.bytesConsumed;
- if (error != XDM_EOK)
- {
- DECLINK_INTERNAL_ERROR_LOG(error, "ALGPROCESS FAILED:STATUS");
- }
- pChObj->algObj.prevOutFrame = outFrame;
- pReqObj->status = error;
- pReqObj->OutFrameList.frames[prosIdx] = NULL;
- UTILS_assert(outArgs->viddecOutArgs.displayBufsMode ==
- IVIDDEC3_DISPLAYBUFS_EMBEDDED);
- displayBufs = &(outArgs->viddecOutArgs.displayBufs.bufDesc[0]);
- if ((outArgs->viddecOutArgs.outputID[0] != 0)
- && (displayBufs->numPlanes))
- {
- XDAS_Int8 *pExpectedBuf;
- pReqObj->OutFrameList.frames[prosIdx] =
- (FVID2_Frame *) outArgs->viddecOutArgs.outputID[0];
- if (pChObj->algObj.algCreateParams.tilerEnable)
- {
- pExpectedBuf = (Ptr) Utils_tilerAddr2CpuAddr(
- (UInt32) pReqObj->OutFrameList.frames[prosIdx]->addr[0][0]);
- }
- else
- {
- pExpectedBuf = pReqObj->OutFrameList.frames[prosIdx]->addr[0][0];
- }
- UTILS_assert(displayBufs->planeDesc[0].buf == pExpectedBuf);
- /* Enable this code once SysTemFrameInfo is updated with support
- * for storing frame resolution info */
- pFrameInfo = (System_FrameInfo *)
- pReqObj->OutFrameList.frames[prosIdx]->appData;
- {
- UTILS_assert(pFrameInfo != NULL);
- pFrameInfo->rtChInfo.width =
- displayBufs->activeFrameRegion.bottomRight.x -
- displayBufs->activeFrameRegion.topLeft.x;
- pFrameInfo->rtChInfo.height =
- displayBufs->activeFrameRegion.bottomRight.y -
- displayBufs->activeFrameRegion.topLeft.y;
- pFrameInfo->rtChInfo.pitch[0] = displayBufs->imagePitch[0];
- pFrameInfo->rtChInfo.pitch[1] = displayBufs->imagePitch[1];
- pFrameInfo->rtChInfoUpdate = TRUE;
- }
- pReqObj->OutFrameList.frames[prosIdx]->fid =
- Utils_encdecMapXDMContentType2FVID2FID(displayBufs->
- contentType);
- }
- freeBufIdx = 0;
- while (outArgs->viddecOutArgs.freeBufID[freeBufIdx] != 0)
- {
- freeFrameList->frames[freeFrameList->numFrames] =
- (FVID2_Frame *) outArgs->viddecOutArgs.freeBufID[freeBufIdx];
- freeFrameList->numFrames++;
- pChObj->numBufsInCodec--;
- freeBufIdx++;
- }
- }
- }
- return (error);
- }
- 4.9)DecLink_codecGetProcessedDataMsgHandler函数功能获取解码后的数据,该函数在DecLink_tskMain中调用;
- Int32 DecLink_codecGetProcessedDataMsgHandler(DecLink_Obj * pObj)
- {
- Int32 status;
- status = DecLink_codecGetProcessedData(pObj);
- UTILS_assert(status == FVID2_SOK);
- return DEC_LINK_S_SUCCESS;
- }
- 4.10)DecLink_codecGetProcessedData 处理解码后的数据,发给下一个link
- static Int32 DecLink_codecGetProcessedData(DecLink_Obj * pObj)
- {
- Bitstream_BufList inBufList;
- FVID2_FrameList outFrameList;
- FVID2_FrameList outFrameSkipList;
- UInt32 chId, sendCmd;
- System_LinkInQueParams *pInQueParams;
- DecLink_ChObj *pChObj;
- DecLink_ReqObj *pReqObj;
- Int32 status, j;
- UInt32 curTime;
- sendCmd = FALSE;
- inBufList.numBufs = 0;
- inBufList.appData = NULL;
- outFrameList.numFrames = 0;
- outFrameSkipList.numFrames = 0;
- curTime = Utils_getCurTimeInMsec();
- while(!Utils_queIsEmpty(&pObj->processDoneQue)
- &&
- (inBufList.numBufs < (VIDBITSTREAM_MAX_BITSTREAM_BUFS - 1))
- &&
- (outFrameList.numFrames < (FVID2_MAX_FVID_FRAME_PTR - 1)))
- {
- //获取解码后的数据
- status = Utils_queGet(&pObj->processDoneQue, (Ptr *) & pReqObj, 1,
- BIOS_NO_WAIT);
- if (status != FVID2_SOK)
- {
- break;
- }
- UTILS_assert(pReqObj->InBuf != NULL);
- chId = pReqObj->InBuf->channelNum;
- pChObj = &pObj->chObj[chId];
- //if (pChObj->totalInFrameCnt > DEC_LINK_STATS_START_THRESHOLD)
- {
- if (curTime > pReqObj->InBuf->timeStamp)
- {
- pChObj->totalProcessTime +=
- (curTime - pReqObj->InBuf->timeStamp);
- }
- }
- pChObj->getProcessedBufCount++;
- pChObj->outFrameCount++;
- inBufList.bufs[inBufList.numBufs] = pReqObj->InBuf;
- inBufList.numBufs++;
- for (j = 0; j < pReqObj->OutFrameList.numFrames; j++)
- {
- if (pReqObj->OutFrameList.frames[j])
- {
- UTILS_assert(pReqObj->InBuf->channelNum ==
- pReqObj->OutFrameList.frames[j]->channelNum);
- UTILS_assert(pChObj->allocPoolID < UTILS_BUF_MAX_ALLOC_POOLS);
- pChObj->trickPlayObj.skipFrame = Utils_doSkipFrame(&(pChObj->trickPlayObj.frameSkipCtx));
- if (pChObj->trickPlayObj.skipFrame == TRUE)
- {
- /* Skip the output frame */
- outFrameSkipList.frames[outFrameSkipList.numFrames] =
- pReqObj->OutFrameList.frames[j];
- outFrameSkipList.numFrames++;
- }
- else
- {
- outFrameList.frames[outFrameList.numFrames] =
- pReqObj->OutFrameList.frames[j];
- outFrameList.numFrames++;
- }
- }
- }
- //归还队列;
- status = Utils_quePut(&pObj->reqQue, pReqObj, BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- pObj->reqQueCount--;
- }
- if (outFrameList.numFrames)
- {
- //解码后的数据,压入到队列,供下一个link使用
- status = Utils_bufPutFullExt(&pObj->outObj.bufOutQue,
- &outFrameList);
- UTILS_assert(status == FVID2_SOK);
- sendCmd = TRUE;
- }
- if (outFrameSkipList.numFrames)
- {
- status = DecLink_codecFreeProcessedFrames(pObj, &outFrameSkipList);
- UTILS_assert(status == DEC_LINK_S_SUCCESS);
- }
- if (inBufList.numBufs)
- {
- /* Free input frames */
- pInQueParams = &pObj->createArgs.inQueParams;
- System_putLinksEmptyBufs(pInQueParams->prevLinkId,
- pInQueParams->prevLinkQueId, &inBufList);
- pObj->inBufPutCount += inBufList.numBufs;
- }
- /* Send-out the output bitbuffer */
- if (sendCmd == TRUE)
- {
- //往下一个link发送消息,告诉下一个link数据已经准备好了
- System_sendLinkCmd(pObj->createArgs.outQueParams.nextLink,
- SYSTEM_CMD_NEW_DATA);
- }
- return FVID2_SOK;
- }
- 4.11)Utils_bufPutFullExt 就是将buff压入到输出full队列,然后提供api供外部的其他link使用;
- Int32 Utils_bufPutFullExt(Utils_BufHndlExt * pHndl,
- FVID2_FrameList * pFrameList)
- {
- UInt32 idx;
- Int32 status;
- UTILS_assert(pHndl != NULL);
- UTILS_assert(pFrameList != NULL);
- UTILS_assert(pFrameList->numFrames <= FVID2_MAX_FVID_FRAME_PTR);
- for (idx = 0; idx < pFrameList->numFrames; idx++)
- {
- status =
- Utils_quePut(&pHndl->fullQue, pFrameList->frames[idx],
- BIOS_NO_WAIT);
- UTILS_assert(status == FVID2_SOK);
- }
- return FVID2_SOK;
- }
- 4.12)DecLink_getFullFrames 函数提供外部调用,获取解码后的帧数据;
- Int32 DecLink_getFullFrames(Utils_TskHndl * pTsk, UInt16 queId,
- FVID2_FrameList * pFrameList)
- {
- DecLink_Obj *pObj = (DecLink_Obj *) pTsk->appData;
- UTILS_assert(queId < DEC_LINK_MAX_OUT_QUE);
- return Utils_bufGetFullExt(&pObj->outObj.bufOutQue, pFrameList,
- BIOS_NO_WAIT);
- }
- 在解码器初始化函数已经注册了该回调函数
- linkObj.linkGetFullFrames = DecLink_getFullFrames;
- 在下一个link调用preLink的该函数获取解码后的数据;
- 5)IpcFrameOutM3
- 5.1)IpcFramesOutLink_tskMain函数中调用 IpcFramesOutLink_processFrameBufs获取解码后的数据;
- Void IpcFramesOutLink_tskMain(struct Utils_TskHndl * pTsk, Utils_MsgHndl * pMsg)
- {
- UInt32 cmd = Utils_msgGetCmd(pMsg);
- Bool ackMsg, done;
- Int32 status;
- IpcFramesOutLink_Obj *pObj = (IpcFramesOutLink_Obj *) pTsk->appData;
- if (cmd != SYSTEM_CMD_CREATE)
- {
- Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);
- return;
- }
- status = IpcFramesOutLink_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);
- IpcFramesOutLink_processFrameBufs(pObj);
- IpcFramesOutLink_releaseFrameBufs(pObj);
- break;
- case IPCFRAMESOUTRTOS_LINK_CMD_SET_FRAME_RATE:
- {
- IpcOutM3Link_ChFpsParams *params;
- params = (IpcOutM3Link_ChFpsParams *) Utils_msgGetPrm(pMsg);
- IpcFramesOutLink_SetFrameRate(pObj, params);
- Utils_tskAckOrFreeMsg(pMsg, status);
- }
- break;
- case IPCFRAMESOUTRTOS_LINK_CMD_PRINT_STATISTICS:
- IpcFramesOutLink_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_FRAMES_OUT : Received Notify !!!\n",
- Utils_getCurTimeInMsec());
- #endif
- IpcFramesOutLink_releaseFrameBufs(pObj);
- break;
- default:
- Utils_tskAckOrFreeMsg(pMsg, status);
- break;
- }
- }
- IpcFramesOutLink_delete(pObj);
- #ifdef SYSTEM_DEBUG_IPC_FRAMES_OUT
- Vps_printf(" %d: IPC_FRAMES_OUT : Delete Done !!!\n", Utils_getCurTimeInMsec());
- #endif
- if (ackMsg && pMsg != NULL)
- Utils_tskAckOrFreeMsg(pMsg, status);
- return;
- }
- 5.2)IpcFramesOutLink_processFrameBufs获取数据;
- Int32 IpcFramesOutLink_processFrameBufs(IpcFramesOutLink_Obj * pObj)
- {
- System_LinkInQueParams *pInQueParams;
- FVID2_FrameList bufList;
- FVID2_Frame *pFrameBuf = NULL;
- SystemIpcFrames_ListElem *pListElem;
- Int32 status;
- Int32 bufId;
- UInt32 curTime;
- FVID2_FrameList freeFrameBufList;
- UInt8 queId;
- UInt32 sendMsgToTsk = 0;
- UInt32 chPerQueue;
- IpcFramesOutLink_ChObj *pChObj;
- pInQueParams = &pObj->createArgs.baseCreateParams.inQueParams;
- bufList.numFrames = 0;
- //下面函数是从解码link获取数据,数据保存在bufList中;
- System_getLinksFullFrames(pInQueParams->prevLinkId,
- pInQueParams->prevLinkQueId, &bufList);
- freeFrameBufList.numFrames = 0;
- curTime = Utils_getCurTimeInMsec();
- if (bufList.numFrames)
- {
- #ifdef SYSTEM_DEBUG_IPC_RT
- Vps_printf(" %d: IPC_FRAMES_OUT : Received %d framebufs !!!\n",
- Utils_getCurTimeInMsec(), bufList.numFrames);
- #endif
- UTILS_assert(bufList.numFrames <= FVID2_MAX_FVID_FRAME_PTR);
- pObj->stats.recvCount += bufList.numFrames;
- sendMsgToTsk = 0;
- chPerQueue =
- (pObj->numCh / pObj->createArgs.baseCreateParams.numOutQue);
- #ifdef IPC_FRAMES_IN_ENABLE_PROFILE
- Utils_prfTsBegin(pObj->stats.tsHandle);
- #endif /* IPC_FRAMES_IN_ENABLE_PROFILE
- */
- pObj->totalFrameCount += bufList.numFrames;
- for (bufId = 0; bufId < bufList.numFrames; bufId++)
- {
- Bool doFrameDrop;
- pFrameBuf = bufList.frames[bufId];
- UTILS_assert(pFrameBuf != NULL);
- pChObj = &pObj->chObj[pFrameBuf->channelNum];
- pChObj->inFrameRecvCount++;
- doFrameDrop = Utils_doSkipFrame(&(pChObj->frameSkipCtx));
- /* frame skipped due to user setting */
- if(doFrameDrop)
- {
- pChObj->inFrameUserSkipCount++;
- UTILS_assert(freeFrameBufList.numFrames <
- FVID2_MAX_FVID_FRAME_PTR);
- freeFrameBufList.frames[freeFrameBufList.numFrames] =
- pFrameBuf;
- freeFrameBufList.numFrames++;
- pObj->stats.droppedCount++;
- continue;
- }
- queId = (pFrameBuf->channelNum / chPerQueue);
- //从队列中取一个buff,赋值给pListElem
- status =
- Utils_queGet(&pObj->listElemQue, (Ptr *) & pListElem, 1,
- BIOS_NO_WAIT);
- UTILS_assert(!UTILS_ISERROR(status));
- if (status != FVID2_SOK)
- {
- /* normally this condition should not happen, if it happens
- * return the framebuf back to its generator */
- #if 0
- Vps_printf(" IPC_OUT: Dropping framebuf\n");
- #endif
- UTILS_assert(freeFrameBufList.numFrames <
- FVID2_MAX_FVID_FRAME_PTR);
- freeFrameBufList.frames[freeFrameBufList.numFrames] =
- pFrameBuf;
- freeFrameBufList.numFrames++;
- pObj->stats.droppedCount++;
- pChObj->inFrameUserSkipCount++;
- continue;
- }
- UTILS_assert(SYSTEM_IPC_FRAMES_GET_BUFSTATE(pListElem->bufState)
- == IPC_FRAMEBUF_STATE_FREE);
- UTILS_assert(SYSTEM_IPC_FRAMES_GET_BUFOWNERPROCID(pListElem->bufState)
- == System_getSelfProcId());
- SYSTEM_IPC_FRAMES_SET_BUFSTATE(pListElem->bufState,
- IPC_FRAMEBUF_STATE_ALLOCED);
- IpcFramesOutLink_copyFrameBufInfo2ListElem(pObj, pListElem, pFrameBuf);
- pFrameBuf->timeStamp = curTime;
- SYSTEM_IPC_FRAMES_SET_BUFSTATE(pListElem->bufState,
- IPC_FRAMEBUF_STATE_OUTQUE);
- sendMsgToTsk |= (1 << queId);
- //压入到ListMP,提供给IpcFrameInLink(A8)调用;
- status =
- ListMP_putTail(pObj->listMPOutHndl, (ListMP_Elem *) pListElem);
- UTILS_assert(status == ListMP_S_SUCCESS);
- pChObj->inFrameProcessCount++;
- }
- #ifdef IPC_FRAMES_IN_ENABLE_PROFILE
- Utils_prfTsEnd(pObj->stats.tsHandle, bufList.numFrames);
- #endif /* IPC_FRAMES_IN_ENABLE_PROFILE
- */
- if (freeFrameBufList.numFrames)
- {
- System_putLinksEmptyFrames(pInQueParams->prevLinkId,
- pInQueParams->prevLinkQueId,
- &freeFrameBufList);
- }
- /* ProcessLink enable, send the notification to processLink else send to next Link */
- //发送通知;
- if (pObj->createArgs.baseCreateParams.processLink != SYSTEM_LINK_ID_INVALID)
- {
- if (pObj->createArgs.baseCreateParams.notifyProcessLink)
- {
- System_ipcSendNotify(pObj->createArgs.baseCreateParams.processLink);
- }
- }
- else
- {
- for (queId = 0; queId < pObj->createArgs.baseCreateParams.numOutQue; queId++)
- {
- if ((pObj->createArgs.baseCreateParams.notifyNextLink) && (sendMsgToTsk & 0x1))
- {
- System_ipcSendNotify(pObj->createArgs.baseCreateParams.outQueParams[queId].
- nextLink);
- }
- sendMsgToTsk >>= 1;
- if (sendMsgToTsk == 0)
- break;
- }
- }
- if (pObj->createArgs.baseCreateParams.noNotifyMode)
- {
- if (FALSE == pObj->prd.clkStarted)
- {
- IpcFramesOutLink_startPrdObj(pObj,
- IPC_FRAMESOUT_LINK_DONE_PERIOD_MS,
- FALSE);
- }
- }
- }
- return FVID2_SOK;
- }
- 7)IpcFrameInHost(A8)
- A8如何获取到数据;
- 7.1)IpcFramesInLink_tskMain 函数
- static
- Int IpcFramesInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,
- Uint32 curState)
- {
- UInt32 cmd = OSA_msgGetCmd(pMsg);
- Bool ackMsg, done;
- Int status = IPC_FRAMES_IN_LINK_S_SUCCESS;
- IpcFramesInLink_Obj *pObj = (IpcFramesInLink_Obj *) pTsk->appData;
- OSA_printf("%s:Entered", __func__);
- if (cmd != SYSTEM_CMD_CREATE)
- {
- OSA_tskAckOrFreeMsg(pMsg, OSA_EFAIL);
- return status;
- }
- status = IpcFramesInLink_create(pObj, OSA_msgGetPrm(pMsg));
- OSA_tskAckOrFreeMsg(pMsg, status);
- if (status != OSA_SOK)
- return status;
- done = FALSE;
- ackMsg = FALSE;
- while (!done)
- {
- status = OSA_tskWaitMsg(pTsk, &pMsg);
- if (status != OSA_SOK)
- break;
- cmd = OSA_msgGetCmd(pMsg);
- switch (cmd)
- {
- case SYSTEM_CMD_DELETE:
- done = TRUE;
- ackMsg = TRUE;
- break;
- case SYSTEM_CMD_NEW_DATA:
- OSA_tskAckOrFreeMsg(pMsg, status);
- //OSA_assert(pObj->prd.numPendingCmd > 0);
- OSA_mutexLock(&pObj->prd.mutexPendingCmd);
- pObj->prd.numPendingCmd--;
- OSA_mutexUnlock(&pObj->prd.mutexPendingCmd);
- //从ipcOutLink中获取数据
- IpcFramesInLink_processFrameBufs(pObj);
- break;
- case SYSTEM_CMD_STOP:
- IpcFramesInLink_stop(pObj);
- OSA_tskAckOrFreeMsg(pMsg, status);
- break;
- default:
- OSA_tskAckOrFreeMsg(pMsg, status);
- break;
- }
- }
- IpcFramesInLink_delete(pObj);
- #ifdef SYSTEM_DEBUG_IPC_FRAMES_IN
- OSA_printf(" %d: IPC_FRAMES_IN : Delete Done !!!\n", OSA_getCurTimeInMsec());
- #endif
- if (ackMsg && pMsg != NULL)
- OSA_tskAckOrFreeMsg(pMsg, status);
- return IPC_FRAMES_IN_LINK_S_SUCCESS;
- }
- 7.2)IpcFramesInLink_processFrameBufs 调用ListMP_getHead获取listElem,然后
- static
- Int32 IpcFramesInLink_processFrameBufs(IpcFramesInLink_Obj * pObj)
- {
- VIDFrame_Buf *pFrameBuf;
- SystemIpcFrames_ListElem *pListElem;
- UInt32 numFrameBufs;
- Int32 status;
- UInt32 curTime;
- numFrameBufs = 0;
- curTime = OSA_getCurTimeInMsec();
- while (1)
- {
- pListElem = ListMP_getHead(pObj->listMPOutHndl);
- if (pListElem == NULL)
- break;
- IpcFramesInLink_getFrameBuf(pObj, pListElem, &pFrameBuf);
- OSA_assert(SYSTEM_IPC_FRAMES_GET_BUFSTATE(pListElem->bufState)
- == IPC_FRAMEBUF_STATE_OUTQUE);
- pListElem->timeStamp = curTime;
- pListElem->frameBuf.linkPrivate = (Ptr)pListElem;
- SYSTEM_IPC_FRAMES_SET_BUFOWNERPROCID(pListElem->bufState);
- SYSTEM_IPC_FRAMES_SET_BUFSTATE(pListElem->bufState,
- IPC_FRAMEBUF_STATE_DEQUEUED);
- pObj->stats.recvCount++;
- //压入队列
- status = OSA_quePut(&pObj->outFrameBufQue,
- (Int32)pFrameBuf, OSA_TIMEOUT_NONE);
- OSA_assert(status == OSA_SOK);
- numFrameBufs++;
- }
- #ifdef SYSTEM_DEBUG_IPC_RT
- OSA_printf(" %d: IPC_FRAMES_IN : Recevived %d framebufs !!!\n",
- OSA_getCurTimeInMsec(), numFrameBufs);
- #endif
- if (numFrameBufs)
- {
- if (pObj->createArgs.cbFxn)
- {
- pObj->createArgs.cbFxn(pObj->createArgs.cbCtx);
- }
- }
- return IPC_FRAMES_IN_LINK_S_SUCCESS;
- }
- 7.3)IpcFramesInLink_getFullFrames提供给外部api使用(IpcFramesInLink_getFullVideoFrames函数)
- static
- Int32 IpcFramesInLink_getFullFrames(IpcFramesInLink_Obj * pObj,
- VIDFrame_BufList * pFrameBufList)
- {
- UInt32 idx;
- Int32 status;
- VIDFrame_Buf *pFrame;
- for (idx = 0; idx < VIDFRAME_MAX_FRAME_BUFS; idx++)
- {
- status =
- OSA_queGet(&pObj->outFrameBufQue, (Int32 *) & pFrame,
- OSA_TIMEOUT_NONE);
- if (status != OSA_SOK)
- break;
- pFrameBufList->frames[idx] = *pFrame;
- }
- pFrameBufList->numFrames = idx;
- return IPC_FRAMES_IN_LINK_S_SUCCESS;
- }