dm8148 videoM3 link源码解析

例子:从A8送一帧jpeg图片到videoM3解码,然后在将解码的数据传递到A8, 这个流程涉及的link源码如下:

[cpp]  view plain  copy
  1. dm8148 link之间数据传递  
  2.   
  3. 1)在A8上调用IpcBitsOutLink_getEmptyVideoBitStreamBufs从IpcBitsOutLink获取buff;然后调用IpcBitsOutLink_putFullVideoBitStreamBufs将数据送入到IpcBitsOutLink;  
  4.   
  5. 1.1)IpcBitsOutLink  
  6. A8调用IpcBitsOutLink将压缩数据(jpeg,mpeg4,h264)送入到videoM3;首先在/src_linux\links\system的system_common.c中调用IpcBitsOutLink_init函数;  
  7. //system_init函数在app初始化时调用;  
  8. Int32 System_init()  
  9. {  
  10.     Int32         status;  
  11.   
  12.     #ifdef SYSTEM_DEBUG  
  13.     OSA_printf ( " %u: SYSTEM: System Common Init in progress !!!\n", OSA_getCurTimeInMsec());  
  14.     #endif  
  15.   
  16.     memset(&gSystem_objCommon, 0, sizeof(gSystem_objCommon));  
  17.   
  18.     System_ipcInit();  
  19.   
  20.     IpcBitsInLink_init();  
  21.     IpcBitsOutLink_init();  
  22.     IpcFramesInLink_init();  
  23.     IpcFramesOutLink_init();  
  24.   
  25.     ...........  
  26.     status = OSA_mbxCreate(&gSystem_objCommon.mbx);  
  27.     UTILS_assert(  status==OSA_SOK);  
  28.   
  29.     SystemLink_init();  
  30.   
  31.     #ifdef SYSTEM_DEBUG  
  32.     OSA_printf ( " %u: SYSTEM: System Common Init Done !!!\n", OSA_getCurTimeInMsec());  
  33.     #endif  
  34.   
  35.     return status;  
  36. }  
  37.   
  38. 1.2)IpcBitsOutLink_init函数  
  39. Int32 IpcBitsOutLink_init()  
  40. {  
  41.     Int32 status;  
  42.     System_LinkObj linkObj;  
  43.     UInt32 ipcBitsOutId;  
  44.     IpcBitsOutLink_Obj *pObj;  
  45.     char tskName[32];  
  46.     UInt32 procId = System_getSelfProcId();  
  47.   
  48.     OSA_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) == 0);  
  49.     OSA_COMPILETIME_ASSERT(offsetof(Bitstream_Buf, reserved) == 0);  
  50.     OSA_COMPILETIME_ASSERT(sizeof(((Bitstream_Buf *) 0)->reserved) ==  
  51.                            sizeof(ListMP_Elem));  
  52.     for (ipcBitsOutId = 0; ipcBitsOutId < IPC_BITS_OUT_LINK_OBJ_MAX;  
  53.          ipcBitsOutId++)  
  54.     {  
  55.         pObj = &gIpcBitsOutLink_obj[ipcBitsOutId];  
  56.   
  57.         memset(pObj, 0, sizeof(*pObj));  
  58.   
  59.         pObj->tskId =  
  60.             SYSTEM_MAKE_LINK_ID(procId,  
  61.                                 SYSTEM_LINK_ID_IPC_BITS_OUT_0) + ipcBitsOutId;  
  62.   
  63.         linkObj.pTsk = &pObj->tsk;  
  64.         linkObj.getLinkInfo = IpcBitsOutLink_getLinkInfo;  
  65.   
  66.         System_registerLink(pObj->tskId, &linkObj);  
  67.   
  68.         OSA_SNPRINTF(tskName, "IPC_BITS_OUT%d", ipcBitsOutId);  
  69.           
  70.     //注册通知  
  71.         System_ipcRegisterNotifyCb(pObj->tskId, IpcBitsOutLink_notifyCb);  
  72.       
  73.     //初始化ListMP  
  74.         IpcBitsOutLink_initListMP(pObj);  
  75.   
  76.         status = OSA_tskCreate(&pObj->tsk,  
  77.                                IpcBitsOutLink_tskMain,  
  78.                                IPC_LINK_TSK_PRI,  
  79.                                IPC_LINK_TSK_STACK_SIZE, 0, pObj);  
  80.         OSA_assert(status == OSA_SOK);  
  81.     }  
  82.   
  83.     return status;  
  84. }  
  85.   
  86.   
  87. 1.3)IpcBitsOutLink_tskMain函数  
  88. Int IpcBitsOutLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,  
  89.                            Uint32 curState)  
  90. {  
  91.     UInt32 cmd = OSA_msgGetCmd(pMsg);  
  92.     Bool ackMsg, done;  
  93.     Int32 status = IPC_BITSOUT_LINK_S_SUCCESS;  
  94.     //appData中保存的是和link相关的参数  
  95.     IpcBitsOutLink_Obj *pObj = (IpcBitsOutLink_Obj *) pTsk->appData;  
  96.       
  97.     //SYSTEM_CMD_CREATE为System_linkCreate函数的命令号,如果cmd!=SYSTEM_CMD_CREATE,主函数退出???  
  98.     if (cmd != SYSTEM_CMD_CREATE)  
  99.     {  
  100.         OSA_tskAckOrFreeMsg(pMsg, OSA_EFAIL);  
  101.         return status;  
  102.     }  
  103.   
  104.     status = IpcBitsOutLink_create(pObj, OSA_msgGetPrm(pMsg));  
  105.   
  106.     OSA_tskAckOrFreeMsg(pMsg, status);  
  107.   
  108.     if (status != OSA_SOK)  
  109.         return status;  
  110.   
  111.     done = FALSE;  
  112.     ackMsg = FALSE;  
  113.   
  114.     while (!done)  
  115.     {  
  116.         status = OSA_tskWaitMsg(pTsk, &pMsg);  
  117.         if (status != OSA_SOK)  
  118.             break;  
  119.   
  120.         cmd = OSA_msgGetCmd(pMsg);  
  121.   
  122.         switch (cmd)  
  123.         {  
  124.             case SYSTEM_CMD_DELETE:  
  125.                 done = TRUE;  
  126.                 ackMsg = TRUE;  
  127.                 break;  
  128.   
  129.             case SYSTEM_IPC_CMD_RELEASE_FRAMES:  
  130.                 OSA_tskAckOrFreeMsg(pMsg, status);  
  131.   
  132. #ifdef SYSTEM_DEBUG_IPC_RT  
  133.                 OSA_printf(" %d: IPC_BITS_OUT   : Received Notify !!!\n",  
  134.                            OSA_getCurTimeInMsec());  
  135. #endif  
  136.   
  137.                 IpcBitsOutLink_releaseBitBufs(pObj);  
  138.                 break;  
  139.   
  140.             case SYSTEM_CMD_START:  
  141.         //link start  
  142.                 IpcBitsOutLink_start(pObj);  
  143.                 OSA_tskAckOrFreeMsg(pMsg, status);  
  144.                 break;  
  145.   
  146.             case SYSTEM_CMD_STOP:  
  147.         //link stop  
  148.                 IpcBitsOutLink_stop(pObj);  
  149.                 OSA_tskAckOrFreeMsg(pMsg, status);  
  150.                 break;  
  151.   
  152.             default:  
  153.                 OSA_tskAckOrFreeMsg(pMsg, status);  
  154.                 break;  
  155.         }  
  156.     }  
  157.   
  158.     IpcBitsOutLink_delete(pObj);  
  159.   
  160. #ifdef SYSTEM_DEBUG_IPC_BITS_OUT  
  161.     OSA_printf(" %d: IPC_BITS_OUT   : Delete Done !!!\n",  
  162.                OSA_getCurTimeInMsec());  
  163. #endif  
  164.   
  165.     if (ackMsg && pMsg != NULL)  
  166.         OSA_tskAckOrFreeMsg(pMsg, status);  
  167.   
  168.     return IPC_BITSOUT_LINK_S_SUCCESS;  
  169. }  
  170.   
  171. 1.4)IpcBitsOutLink_create函数  
  172. Int32 IpcBitsOutLink_create(IpcBitsOutLink_Obj * pObj,  
  173.                             IpcBitsOutLinkHLOS_CreateParams * pPrm)  
  174. {  
  175.     Int32 status;  
  176.     UInt32 i;  
  177.   
  178. #ifdef SYSTEM_DEBUG_IPC  
  179.     OSA_printf(" %d: IPC_BITS_OUT   : Create in progress !!!\n",  
  180.                OSA_getCurTimeInMsec());  
  181. #endif  
  182.   
  183.     memcpy(&pObj->createArgs, pPrm, sizeof(pObj->createArgs));  
  184.   
  185.     for (i=0; i<IPC_LINK_BITS_OUT_MAX_NUM_ALLOC_POOLS; i++)  
  186.     {  
  187.         OSA_assert(i < IPC_BITS_OUT_MAX_NUM_ALLOC_POOLS);  
  188.         if(pObj->createArgs.numBufPerCh[i] == 0)  
  189.             pObj->createArgs.numBufPerCh[i] =  
  190.                   IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH;  
  191.   
  192.         if(pObj->createArgs.numBufPerCh[i] >  
  193.                  IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH)  
  194.         {  
  195.             OSA_printf("\n IPCBITSOUTLINK: WARNING: User is asking for %d buffers per CH. But max allowed is %d. \n"  
  196.                 " Over riding user requested with max allowed \n\n",  
  197.                 pObj->createArgs.numBufPerCh[i],  
  198.                 IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH  
  199.                 );  
  200.   
  201.             pObj->createArgs.numBufPerCh[i] =  
  202.                   IPC_BITS_OUT_LINK_MAX_OUT_FRAMES_PER_CH;  
  203.   
  204.         }  
  205.     }  
  206.   
  207.     //listMP 队列清空  
  208.     status = System_ipcListMPReset(pObj->listMPOutHndl, pObj->listMPInHndl);  
  209.     OSA_assert(status == OSA_SOK);  
  210.   
  211.     //分配link的内存  
  212.     IpcBitsOutLink_createOutObj(pObj);  
  213.   
  214.     IpcBitsOutLink_initStats(pObj);  
  215.   
  216.     pObj->startProcessing = FALSE;  
  217.   
  218. #ifdef SYSTEM_DEBUG_IPC  
  219.     OSA_printf(" %d: IPC_BITS_OUT   : Create Done !!!\n",  
  220.                OSA_getCurTimeInMsec());  
  221. #endif  
  222.   
  223.     return IPC_BITSOUT_LINK_S_SUCCESS;  
  224. }  
  225.   
  226. 1.5)IpcBitsOutLink_createOutObj函数分配该link需要多少内存,link的内存由link自己管理,在建立link时,告诉该link 内存池的个数,每个池中的buff的个数,link自己决定分配多少内存;  
  227.   
  228. static Int IpcBitsOutLink_createOutObj(IpcBitsOutLink_Obj * pObj)  
  229. {  
  230.     Int status = OSA_SOK;  
  231.     Int32 poolId, elemId, bufId;  
  232.     IHeap_Handle srBitBufHeapHandle;  
  233.     UInt32 bufSize, numBufs, totBufSize, cacheLineSize;  
  234.     const UInt32 srIndex = SYSTEM_IPC_SR_CACHED;  
  235.     Ptr   phyAddr;  
  236.   
  237.     ipcbitsoutlink_populate_outbuf_pool_size_info(&pObj->createArgs,  
  238.                                                   &pObj->createArgs.inQueInfo,  
  239.                                                   &pObj->outQueInfo);  
  240.     elemId = 0;  
  241.     srBitBufHeapHandle = SharedRegion_getHeap(srIndex);  
  242.     OSA_assert(srBitBufHeapHandle != NULL);  
  243.     cacheLineSize = SharedRegion_getCacheLineSize(srIndex);  
  244.     for (poolId = 0; poolId < pObj->outQueInfo.allocPoolInfo.numPools; poolId++)  
  245.     {  
  246.         status = OSA_queCreate(&pObj->listElemQue[poolId],  
  247.                                SYSTEM_IPC_BITS_MAX_LIST_ELEM);  
  248.         OSA_assert(status == OSA_SOK);  
  249.         bufSize =  
  250.             OSA_align(pObj->outQueInfo.allocPoolInfo.bufPoolInfo[poolId].  
  251.                       bufSize, cacheLineSize);  
  252.         numBufs = pObj->outQueInfo.allocPoolInfo.bufPoolInfo[poolId].numBufs;  
  253.       
  254.         //总共需要分配的内存大小  
  255.         totBufSize = bufSize * numBufs;  
  256.         OSA_printf ("###Bit buff of size from the SR # %d : %d\n", srIndex, totBufSize);  
  257.         pObj->bitBufPoolPtr[poolId] =  
  258.             Memory_alloc(srBitBufHeapHandle, totBufSize, cacheLineSize, NULL);  
  259.         OSA_assert(pObj->bitBufPoolPtr[poolId] != NULL);  
  260.         OSA_printf("IPC_BITSOUT:BitBuffer Alloc.PoolID:%d,Size:0x%X",  
  261.                     poolId,totBufSize);  
  262.         phyAddr = IpcBitsOutLink_MapUsrVirt2Phy(pObj->bitBufPoolPtr[poolId]);  
  263.         pObj->bitBufPoolSize[poolId] = totBufSize;  
  264.         for (bufId = 0; bufId < numBufs; bufId++)  
  265.         {  
  266.             SystemIpcBits_ListElem *listElem;  
  267.   
  268.             OSA_assert(elemId < SYSTEM_IPC_BITS_MAX_LIST_ELEM);  
  269.             listElem = pObj->listElem[elemId];  
  270.             elemId++;  
  271.             SYSTEM_IPC_BITS_SET_BUFOWNERPROCID(listElem->bufState);  
  272.             SYSTEM_IPC_BITS_SET_BUFSTATE(listElem->bufState,  
  273.                                          IPC_BITBUF_STATE_FREE);  
  274.             listElem->bitBuf.addr =  
  275.                 (Ptr) (((UInt32) (pObj->bitBufPoolPtr[poolId])) +  
  276.                        (bufSize * bufId));  
  277.             if (phyAddr)  
  278.             {  
  279.                 listElem->bitBuf.phyAddr =  
  280.                     (UInt32) ((UInt32) (phyAddr) +  (bufSize * bufId));  
  281.             }  
  282.             listElem->bitBuf.allocPoolID = poolId;  
  283.             listElem->bitBuf.bufSize = bufSize;  
  284.             listElem->bitBuf.fillLength = 0;  
  285.             listElem->bitBuf.mvDataFilledSize = 0;  
  286.             listElem->bitBuf.startOffset = 0;  
  287.             listElem->bitBuf.bottomFieldBitBufSize = 0;  
  288.             listElem->bitBuf.doNotDisplay = FALSE;  
  289.             //获取Buf的指针  
  290.             listElem->srBufPtr = SharedRegion_getSRPtr(listElem->bitBuf.addr,  
  291.                                                        srIndex);  
  292.             OSA_assert(listElem->srBufPtr != IPC_LINK_INVALID_SRPTR);  
  293.             //将分配的buff挂在插入list队列,使用时,从队列中取empty buff,比如在A8需要将bit数据拷贝传递到IpcBitsOutLink,调用IpcBitsOutLink_getEmptyVideoBitStreamBufs  
  294.   
  295. (IpcBitsOutLink_getEmptyBufs)从队列中取buff;  
  296.             status =  
  297.                 OSA_quePut(&pObj->listElemQue[poolId], (Int32) listElem,  
  298.                            OSA_TIMEOUT_NONE);  
  299.             OSA_assert(status == OSA_SOK);  
  300.         }  
  301.     }  
  302.     return status;  
  303. }  
  304.   
  305. 1.6)A8中调用该函数将buff传递IpcBitsOutLink  
  306. Int32 IpcBitsOutLink_putFullVideoBitStreamBufs(UInt32 linkId,  
  307.                                                Bitstream_BufList *bufList)  
  308. {  
  309.     OSA_TskHndl * pTsk;  
  310.     IpcBitsOutLink_Obj * pObj;  
  311.     Int status;  
  312.   
  313.     OSA_assert(bufList != NULL);  
  314.     if (!((linkId  >= SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0)  
  315.           &&  
  316.           (linkId  < (SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0 + IPC_BITS_OUT_LINK_OBJ_MAX))))  
  317.     {  
  318.         return IPC_BITSOUT_LINK_E_INVALIDLINKID;  
  319.     }  
  320.     pTsk = System_getLinkTskHndl(linkId);  
  321.     pObj = pTsk->appData;  
  322.       
  323.     //将buff传递到下一个link  
  324.     status = IpcBitsOutLink_putFullBufs(pObj,bufList);  
  325.     return status;  
  326. }  
  327.   
  328. 1.7)IpcBitsOutLink_putFullBufs 将buff传递到下一个link,注意IpcBitsOutLink_listMPPut,将buff压入到输出队列,然后发送System_ipcSendNotify 发送通知,通知下一个link来取数据;  
  329. static  
  330. Int32 IpcBitsOutLink_putFullBufs(IpcBitsOutLink_Obj *pObj,  
  331.                                  Bitstream_BufList *pBufList)  
  332. {  
  333.     SystemIpcBits_ListElem *pListElem;  
  334.     Bitstream_Buf *pBitBuf;  
  335.     Bitstream_BufList freeBitBufList;  
  336.     Bool putDone = FALSE;  
  337.     Int32 bufId;  
  338.     UInt32 curTime;  
  339.   
  340.     freeBitBufList.numBufs = 0;  
  341.     curTime = OSA_getCurTimeInMsec();  
  342.     for (bufId = 0; bufId < pBufList->numBufs; bufId++)  
  343.     {  
  344.         pBitBuf = pBufList->bufs[bufId];  
  345.         curTime = pBitBuf->timeStamp = Get_timeStamp(pBitBuf->channelNum);   
[cpp]  view plain  copy
  1.         pListElem = (SystemIpcBits_ListElem *)pBitBuf;  
  2.         OSA_assert(SharedRegion_getPtr(pListElem->srBufPtr) ==  
  3.                    pBitBuf->addr);  
  4.         if (0 == pBitBuf->fillLength)  
  5.         {  
  6.             /* filled length of 0 indicates application 
  7.              * did not fill any data in this buffer. 
  8.              * Free it immediately */  
  9. #ifdef SYSTEM_DEBUG_IPC_RT  
  10.                 OSA_printf(" IPC_OUT: Dropping bitbuf\n");  
  11. #endif  
  12.   
  13.             OSA_assert(freeBitBufList.numBufs <  
  14.                        VIDBITSTREAM_MAX_BITSTREAM_BUFS);  
  15.             freeBitBufList.bufs[freeBitBufList.numBufs] = pBitBuf;  
  16.             freeBitBufList.numBufs++;  
  17.             pObj->stats.droppedCount++;  
  18.             continue;  
  19.         }  
  20.         else  
  21.         {  
  22.             pObj->stats.recvCount++;  
  23.             OSA_assert(SYSTEM_IPC_BITS_GET_BUFSTATE(pListElem->bufState)  
  24.                        == IPC_BITBUF_STATE_FREE);  
  25.             OSA_assert(SYSTEM_IPC_BITS_GET_BUFOWNERPROCID(pListElem->bufState)  
  26.                        == System_getSelfProcId());  
  27.             pListElem->ipcPrivData = (Ptr) curTime;  
  28.             SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,  
  29.                                          IPC_BITBUF_STATE_ALLOCED);  
  30.             //压入到输出队列  
  31.             IpcBitsOutLink_listMPPut(pObj, pListElem);  
  32.             putDone = TRUE;  
  33.         }  
  34.     }  
  35.     if (freeBitBufList.numBufs)  
  36.     {  
  37.         IpcBitsOutLink_putEmptyBufs(pObj, &freeBitBufList);  
  38.     }  
  39.   
  40.     if (putDone && (pObj->createArgs.baseCreateParams.notifyNextLink))  
  41.     {  
  42.         //通知下一个link,调用Notify_sendEvent函数  
  43.         System_ipcSendNotify(pObj->createArgs.baseCreateParams.outQueParams[0].  
  44.                              nextLink);  
  45.     }  
  46.     if (!putDone)  
  47.     {  
  48.         pObj->stats.numNoFullBufCount++;  
  49.         if ((pObj->stats.numNoFullBufCount % IPC_BITSOUT_STATS_WARN_INTERVAL) == 0)  
  50.         {  
  51.             #ifdef DEBUG_IPC_BITS  
  52.             OSA_printf("IPCBITSOUT:!!!WARNING.!!! NO FULL BUF AVAILABLE. OCCURENCE COUNT:[%d]",  
  53.                        pObj->stats.numNoFullBufCount);  
  54.             #endif  
  55.         }  
  56.     }  
  57.     return IPC_BITSOUT_LINK_S_SUCCESS;  
  58. }  
  59.   
  60. 1.8)IpcBitsOutLink_listMPPut 函数  
  61. static  
  62. Int32 IpcBitsOutLink_listMPPut(IpcBitsOutLink_Obj * pObj,  
  63.                                SystemIpcBits_ListElem * pListElem)  
  64. {  
  65.     Int32 status = IPC_BITSOUT_LINK_S_SUCCESS;  
  66.   
  67.     SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState, IPC_BITBUF_STATE_OUTQUE);  
  68.     //cache 多核之间数据拷贝,传递到ipcbitsIn(videoM3) link  
  69.   
  70.     IpcBitsOutLink_doPrePutCacheOp(pObj, pListElem);  
  71.     status = ListMP_putTail(pObj->listMPOutHndl, (ListMP_Elem *) pListElem);  
  72.     OSA_assert(status == ListMP_S_SUCCESS);  
  73.     return IPC_BITSOUT_LINK_S_SUCCESS;  
  74. }  
  75.   
  76.   
  77. 1.9)IpcBitsOutLink_doPrePutCacheOp 函数;  
  78. static  
  79. Int32 IpcBitsOutLink_doPrePutCacheOp(IpcBitsOutLink_Obj * pObj,  
  80.                                      SystemIpcBits_ListElem * pListElem)  
  81. {  
  82.     if (pListElem->bitBuf.fillLength)  
  83.     {  
  84.         Cache_wbInv(pListElem->bitBuf.addr,  
  85.                     pListElem->bitBuf.fillLength, Cache_Type_ALL, TRUE);  
  86.     }  
  87.     /* No cache ops done since pListElem is allocated from non-cached memory */  
  88.     UTILS_assert(SharedRegion_isCacheEnabled(SharedRegion_getId(pListElem)) ==  
  89.                  FALSE);  
  90.     return IPC_BITSOUT_LINK_S_SUCCESS;  
  91. }  
  92.   
  93. ListMP_putTail 和ListMP_getHead 作用,多核之间用吗?相邻2个核之间的link公用一个ListMp队列吗?ipcBitsOutLink(A8)发送通知Notify_sendEvent告诉ipcBitsInLink(videoM3),在  
  94.   
  95. ListMP队列已经存在数据;  
  96.   
  97. ListMP实现了多宿主双向循环链表,即该双向循环链表为多个处理器共同拥有,可以由多个处理器共同维护,共同使用。  
  98. ListMP的实现区别于一般的双向循环链表,因此它不仅具有双向循环链表的特性外,还增添了其他的特性,比如以下几点:  
  99. 1.实现了简单的多宿主协议,支持多个读写者(multi-reader、multi-writee);  
  100. 2.使用Gate作为内部保护机制,防止多个宿主处理器同时访问该链表;  
  101. ListMP的实现并未加入通知机制,如果需要的话,可以在外部封装是引入Notify机制来实现;使用ListMP机制来管理的buffers都需要从共享内存区分配,包括从堆内存分配的buffers以及动  
  102.   
  103. 态分配的内存。  
  104.   
  105.   
  106. 2)videoM3 systemLink 多核之间数据传递要用到systemlink,以下是videoM3中systemLink的初始化函数;主要有IpcOutM3Link_init()函数和IpcInM3Link_init()函数;  
  107. mcfw/src_bios6/links_m3video/system ;system_m3video.c  
  108.   
  109. Int32 System_init()  
  110. {  
  111.     Int32 status = FVID2_SOK;  
  112.   
  113. #ifdef SYSTEM_DEBUG  
  114.     Vps_printf(" %d: SYSTEM  : System Video Init in progress !!!\n",  
  115.                Utils_getCurTimeInMsec());  
  116. #endif  
  117.   
  118. #ifdef SYSTEM_DEBUG  
  119.     Vps_printf(" %d: SYSTEM  : System Video Init Done !!!\n", Utils_getCurTimeInMsec());  
  120. #endif  
  121.     IpcOutM3Link_init();  
  122.     IpcInM3Link_init();  
  123.   
  124.     IpcBitsInLink_init();  
  125.     IpcBitsOutLink_init();  
  126.     IpcFramesInLink_init();  
  127.     IpcFramesOutLink_init();  
  128.       
  129.     Utils_encdecInit();  
  130.       
  131.     //编解码link初始化  
  132.     System_initLinks();  
  133.       
  134.     return status;  
  135. }  
  136.   
  137. 3)IpcBitsInLink(mcfw_bios6)  
  138.   
  139.   
  140. 3.1)初始化函数  
  141. Int32 IpcBitsInLink_init()  
  142. {  
  143.     Int32 status;  
  144.     System_LinkObj linkObj;  
  145.     UInt32 ipcBitsInId;  
  146.     IpcBitsInLink_Obj *pObj;  
  147.     char tskName[32];  
  148.     UInt32 procId = System_getSelfProcId();  
  149.   
  150.     UTILS_COMPILETIME_ASSERT(offsetof(SystemIpcBits_ListElem, bitBuf) == 0);  
  151.     UTILS_COMPILETIME_ASSERT(offsetof(Bitstream_Buf, reserved) == 0);  
  152.     UTILS_COMPILETIME_ASSERT(sizeof(((Bitstream_Buf *) 0)->reserved) ==  
  153.                              sizeof(ListMP_Elem));  
  154.   
  155.     for (ipcBitsInId = 0; ipcBitsInId < IPC_BITS_IN_LINK_OBJ_MAX; ipcBitsInId++)  
  156.     {  
  157.         pObj = &gIpcBitsInLink_obj[ipcBitsInId];  
  158.   
  159.         memset(pObj, 0, sizeof(*pObj));  
  160.   
  161.         pObj->tskId =  
  162.             SYSTEM_MAKE_LINK_ID(procId,  
  163.                                 SYSTEM_LINK_ID_IPC_BITS_IN_0) + ipcBitsInId;  
  164.   
  165.         pObj->state = IPC_BITS_IN_LINK_STATE_INACTIVE;  
  166.         linkObj.pTsk = &pObj->tsk;  
  167.         linkObj.linkGetFullFrames = NULL;  
  168.         linkObj.linkPutEmptyFrames = NULL;  
  169.         linkObj.linkGetFullBitBufs = IpcBitsInLink_getFullBitBufs;  
  170.         linkObj.linkPutEmptyBitBufs = IpcBitsInLink_putEmptyBitBufs;  
  171.         linkObj.getLinkInfo = IpcBitsInLink_getLinkInfo;  
  172.   
  173.         System_registerLink(pObj->tskId, &linkObj);  
  174.   
  175.         UTILS_SNPRINTF(tskName, "IPC_BITS_IN%d", ipcBitsInId);  
  176.   
  177.         System_ipcRegisterNotifyCb(pObj->tskId, IpcBitsInLink_notifyCb);  
  178.   
  179.         status = Utils_tskCreate(&pObj->tsk,  
  180.                                  IpcBitsInLink_tskMain,  
  181.                                  IPC_LINK_TSK_PRI,  
  182.                                  gIpcBitsInLink_tskStack[ipcBitsInId],  
  183.                                  IPC_LINK_TSK_STACK_SIZE, pObj, tskName);  
  184.         UTILS_assert(status == FVID2_SOK);  
  185.     }  
  186.   
  187.     return status;  
  188. }  
  189.   
  190. 3.2)IpcBitsInLink_tskMain 主函数  
  191. Void IpcBitsInLink_tskMain(struct Utils_TskHndl * pTsk, Utils_MsgHndl * pMsg)  
  192. {  
  193.     UInt32 cmd = Utils_msgGetCmd(pMsg);  
  194.     Bool ackMsg, done;  
  195.     Int32 status;  
  196.     IpcBitsInLink_Obj *pObj = (IpcBitsInLink_Obj *) pTsk->appData;  
  197.   
  198.     if (cmd != SYSTEM_CMD_CREATE)  
  199.     {  
  200.         Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);  
  201.         return;  
  202.     }  
  203.   
  204.     //ListMP 和队列资源初始化  
  205.     status = IpcBitsInLink_create(pObj, Utils_msgGetPrm(pMsg));  
  206.   
  207.     Utils_tskAckOrFreeMsg(pMsg, status);  
  208.   
  209.     if (status != FVID2_SOK)  
  210.         return;  
  211.   
  212.     done = FALSE;  
  213.     ackMsg = FALSE;  
  214.   
  215.     while (!done)  
  216.     {  
  217.     //接收消息,是接收从ipcbitsOutlink(A8)  
  218.         status = Utils_tskRecvMsg(pTsk, &pMsg, BIOS_WAIT_FOREVER);  
  219.         if (status != FVID2_SOK)  
  220.             break;  
  221.   
  222.         cmd = Utils_msgGetCmd(pMsg);  
  223.   
  224.         switch (cmd)  
  225.         {  
  226.             case SYSTEM_CMD_DELETE:  
  227.                 done = TRUE;  
  228.                 ackMsg = TRUE;  
  229.                 break;  
  230.             case SYSTEM_CMD_NEW_DATA:  
  231.         //从IpcInM3 Link获取消息  
  232.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  233.   
  234.                 IpcBitsInLink_processBitBufs(pObj);  
  235.                 break;  
  236.             case SYSTEM_CMD_STOP:  
  237.                 IpcBitsInLink_stop(pObj);  
  238.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  239.                 break;  
  240.             default:  
  241.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  242.                 break;  
  243.         }  
  244.     }  
  245.   
  246.     IpcBitsInLink_delete(pObj);  
  247.   
  248. #ifdef SYSTEM_DEBUG_IPC_BITS_IN  
  249.     Vps_printf(" %d: IPC_BITS_IN   : Delete Done !!!\n", Utils_getCurTimeInMsec());  
  250. #endif  
  251.   
  252.     if (ackMsg && pMsg != NULL)  
  253.         Utils_tskAckOrFreeMsg(pMsg, status);  
  254.   
  255.     return;  
  256. }  
  257.   
  258.   
  259. 3.3)IpcBitsInLink_processBitBufs函数  
  260. Int32 IpcBitsInLink_processBitBufs(IpcBitsInLink_Obj * pObj)  
  261. {  
  262.     Bitstream_Buf *pBitBuf;  
  263.     SystemIpcBits_ListElem *pListElem;  
  264.     UInt32 numBitBufs;  
  265.     Int32 status;  
  266.     UInt32 curTime;  
  267.   
  268.     numBitBufs = 0;  
  269.     curTime = Utils_getCurTimeInMsec();  
  270.     while (1)  
  271.     {  
  272.     //获取listElem,多核之间获取数据;  
  273.         pListElem = ListMP_getHead(pObj->listMPOutHndl);  
  274.         if (pListElem == NULL)  
  275.             break;  
  276.       
  277.     //转化为bitbuff  
  278.         IpcBitsInLink_getBitBuf(pObj, pListElem, &pBitBuf);  
  279.         UTILS_assert(SYSTEM_IPC_BITS_GET_BUFSTATE(pListElem->bufState)  
  280.                      == IPC_BITBUF_STATE_OUTQUE);  
  281.         pBitBuf->reserved[0] = curTime;  
  282.         SYSTEM_IPC_BITS_SET_BUFOWNERPROCID(pListElem->bufState);  
  283.         SYSTEM_IPC_BITS_SET_BUFSTATE(pListElem->bufState,  
  284.                                      IPC_BITBUF_STATE_DEQUEUED);  
  285.         pObj->stats.recvCount++;  
  286.     //压入到输出队列;  
  287.         status = Utils_quePut(&pObj->outBitBufQue, pBitBuf, BIOS_NO_WAIT);  
  288.         UTILS_assert(status == FVID2_SOK);  
  289.   
  290.         numBitBufs++;  
  291.     }  
  292.   
  293. #ifdef SYSTEM_DEBUG_IPC_RT  
  294.     Vps_printf(" %d: IPC_BITS_IN   : Recevived %d bitbufs !!!\n",  
  295.                Utils_getCurTimeInMsec(), numBitBufs);  
  296. #endif  
  297.   
  298.     //给下一个link发送消息  
  299.     if (numBitBufs && pObj->createArgs.baseCreateParams.notifyNextLink)  
  300.     {  
  301.         UTILS_assert(pObj->createArgs.baseCreateParams.numOutQue == 1);  
  302.         System_sendLinkCmd(pObj->createArgs.baseCreateParams.outQueParams[0].  
  303.                            nextLink, SYSTEM_CMD_NEW_DATA);  
  304.     }  
  305.   
  306.     return IPC_BITS_IN_LINK_S_SUCCESS;  
  307. }  
  308.   
  309. 4)VideoM3 declink  
  310.   
  311. 4.1)解码link初始化函数  
  312. Int32 DecLink_init()  
  313. {  
  314.     Int32 status;  
  315.     System_LinkObj linkObj;  
  316.     DecLink_Obj *pObj;  
  317.     char name[32];  
  318.     UInt32 objId;  
  319.   
  320.     for (objId = 0; objId < DEC_LINK_OBJ_MAX; objId++)  
  321.     {  
  322.         pObj = &gDecLink_obj[objId];  
  323.   
  324.         memset(pObj, 0, sizeof(*pObj));  
  325.         pObj->linkId = SYSTEM_LINK_ID_VDEC_0 + objId;  
  326.   
  327.         linkObj.pTsk = &pObj->tsk;  
  328.         linkObj.linkGetFullFrames = DecLink_getFullFrames;  
  329.         linkObj.linkPutEmptyFrames = DecLink_putEmptyFrames;  
  330.         linkObj.linkGetFullBitBufs = NULL;  
  331.         linkObj.linkPutEmptyBitBufs = NULL;  
  332.         linkObj.getLinkInfo = DecLink_getInfo;  
  333.   
  334.         UTILS_SNPRINTF(name, "DEC%d   ", objId);  
  335.   
  336.         System_registerLink(pObj->linkId, &linkObj);  
  337.   
  338.         status = Utils_tskCreate(&pObj->tsk,  
  339.                                  DecLink_tskMain,  
  340.                                  DEC_LINK_TSK_PRI,  
  341.                                  gDecLink_tskStack[objId],  
  342.                                  DEC_LINK_TSK_STACK_SIZE, pObj, name);  
  343.         UTILS_assert(status == FVID2_SOK);  
  344.     }  
  345.   
  346.     return status;  
  347. }  
  348.   
  349.   
  350. 4.2)DecLink_tskMain 主函数  
  351. Void DecLink_tskMain(struct Utils_TskHndl *pTsk, Utils_MsgHndl * pMsg)  
  352. {  
  353.     UInt32 cmd = Utils_msgGetCmd(pMsg);  
  354.     Bool ackMsg, done;  
  355.     Int32 status;  
  356.     DecLink_Obj *pObj;  
  357.     UInt32 flushCmds[2];  
  358.   
  359.     pObj = (DecLink_Obj *) pTsk->appData;  
  360.   
  361.     if (cmd != SYSTEM_CMD_CREATE)  
  362.     {  
  363.         #ifndef DEC_LINK_SUPRESS_ERROR_AND_RESET  
  364.         DECLINK_INTERNAL_ERROR_LOG(DEC_LINK_E_INVALIDCMD,  
  365.                                    "Link create should be first cmd."  
  366.                                    "Received Cmd:%d", cmd);  
  367.         #endif  
  368.         Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);  
  369.         return;  
  370.     }  
  371.   
  372.     //分配link的内存等资源,创建解码线程(调用该函数DecLink_codecCreateProcessTsk(pObj, tskId);)  
  373.     status = DecLink_codecCreate(pObj, Utils_msgGetPrm(pMsg));  
  374.   
  375.     Utils_tskAckOrFreeMsg(pMsg, status);  
  376.   
  377.     if (status != FVID2_SOK)  
  378.         return;  
  379.   
  380.     Utils_encdecHdvicpPrfInit();  
  381.     done = FALSE;  
  382.     ackMsg = FALSE;  
  383.   
  384.     while (!done)  
  385.     {  
  386.         status = Utils_tskRecvMsg(pTsk, &pMsg, BIOS_WAIT_FOREVER);  
  387.         if (status != FVID2_SOK)  
  388.             break;  
  389.   
  390.         cmd = Utils_msgGetCmd(pMsg);  
  391.   
  392.         switch (cmd)  
  393.         {  
  394.             case SYSTEM_CMD_NEW_DATA:  
  395.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  396.   
  397.                 flushCmds[0] = SYSTEM_CMD_NEW_DATA;  
  398.                 Utils_tskFlushMsg(pTsk, flushCmds, 1);  
  399.         //link收到数据,调用该函数进行解码  
  400.                 DecLink_codecProcessData(pObj);  
  401.                 break;  
  402.   
  403.             case DEC_LINK_CMD_GET_PROCESSED_DATA:  
  404.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  405.   
  406.                 flushCmds[0] = DEC_LINK_CMD_GET_PROCESSED_DATA;  
  407.                 Utils_tskFlushMsg(pTsk, flushCmds, 1);  
  408.   
  409.                 DecLink_codecGetProcessedDataMsgHandler(pObj);  
  410.                 break;  
  411.   
  412.             case DEC_LINK_CMD_PRINT_IVAHD_STATISTICS:  
  413.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  414.   
  415.                 Utils_encdecHdvicpPrfPrint();  
  416.                 break;  
  417.   
  418.             case DEC_LINK_CMD_PRINT_STATISTICS:  
  419.                 DecLink_printStatistics(pObj, TRUE);  
  420.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  421.                 break;  
  422.   
  423.             case DEC_LINK_CMD_PRINT_BUFFER_STATISTICS:  
  424.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  425.                 DecLink_printBufferStatus(pObj);  
  426.                 break;  
  427.   
  428.             case DEC_LINK_CMD_DISABLE_CHANNEL:  
  429.                 {  
  430.                     DecLink_ChannelInfo *params;  
  431.   
  432.                     params = (DecLink_ChannelInfo *) Utils_msgGetPrm(pMsg);  
  433.                     DecLink_codecDisableChannel(pObj, params);  
  434.                     Utils_tskAckOrFreeMsg(pMsg, status);  
  435.                 }  
  436.                 break;  
  437.             case DEC_LINK_CMD_ENABLE_CHANNEL:  
  438.                 {  
  439.                     DecLink_ChannelInfo *params;  
  440.   
  441.                     params = (DecLink_ChannelInfo *) Utils_msgGetPrm(pMsg);  
  442.                     DecLink_codecEnableChannel(pObj, params);  
  443.                     Utils_tskAckOrFreeMsg(pMsg, status);  
  444.                 }  
  445.                 break;  
  446.   
  447.             case DEC_LINK_CMD_SET_TRICKPLAYCONFIG:  
  448.                 {  
  449.                     DecLink_TPlayConfig * params;  
  450.                     params = (DecLink_TPlayConfig *) Utils_msgGetPrm(pMsg);  
  451.                     DecLink_setTPlayConfig(pObj, params);  
  452.                     Utils_tskAckOrFreeMsg(pMsg, status);  
  453.                 }  
  454.                 break;  
  455.             case SYSTEM_CMD_STOP:  
  456.                 DecLink_codecStop(pObj);  
  457.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  458.                 break;  
  459.   
  460.             case SYSTEM_CMD_DELETE:  
  461.                 DecLink_codecStop(pObj);  
  462.                 done = TRUE;  
  463.                 ackMsg = TRUE;  
  464.                 break;  
  465.   
  466.             default:  
  467.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  468.                 break;  
  469.         }  
  470.     }  
  471.   
  472.     DecLink_codecDelete(pObj);  
  473.   
  474.     if (ackMsg && pMsg != NULL)  
  475.         Utils_tskAckOrFreeMsg(pMsg, status);  
  476.   
  477.     return;  
  478. }  
  479.   
  480. 4.3)DecLink_codecProcessData函数从上一个link中获取bit数据,调用videoM3的解码器进行解码;  
  481. Int32 DecLink_codecProcessData(DecLink_Obj * pObj)  
  482. {  
  483.     Int32 status;  
  484.   
  485.     pObj->newDataProcessOnFrameFree = FALSE;  
  486.     DecLink_codecQueueBufsToChQue(pObj);  
  487.   
  488.     do  
  489.     {  
  490.         status = DecLink_codecSubmitData(pObj);  
  491.     } while (status == FVID2_SOK);  
  492.   
  493.     return FVID2_SOK;  
  494. }  
  495.   
  496.   
  497. 4.4)DecLink_codecQueueBufsToChQue调用System_getLinksFullBufs从prelink中获取bit数据,保存在BitStream_Buf结构中;  
  498. static Int32 DecLink_codecQueueBufsToChQue(DecLink_Obj * pObj)  
  499. {  
  500.     UInt32 bufId, freeBufNum;  
  501.     Bitstream_Buf *pBuf;  
  502.     System_LinkInQueParams *pInQueParams;  
  503.     Bitstream_BufList bufList;  
  504.     DecLink_ChObj *pChObj;  
  505.     Int32 status;  
  506.     UInt32 curTime;  
  507.   
  508.     pInQueParams = &pObj->createArgs.inQueParams;  
  509.   
  510.     System_getLinksFullBufs(pInQueParams->prevLinkId,  
  511.                             pInQueParams->prevLinkQueId, &bufList);  
  512.   
  513.     if (bufList.numBufs)  
  514.     {  
  515.         pObj->inBufGetCount += bufList.numBufs;  
  516.   
  517.         freeBufNum = 0;  
  518.         curTime = Utils_getCurTimeInMsec();  
  519.   
  520.         for (bufId = 0; bufId < bufList.numBufs; bufId++)  
  521.         {  
  522.             pBuf = bufList.bufs[bufId];  
  523.   
  524.             pChObj = &pObj->chObj[pBuf->channelNum];  
  525.   
  526.             pChObj->inFrameRecvCount++;  
  527.   
  528.             // pBuf->fid = pChObj->nextFid;  
  529.             if(pChObj->disableChn && pChObj->skipFrame == FALSE)  
  530.             {  
  531.                 pChObj->skipFrame = TRUE;  
  532.             }  
  533.             else if((pChObj->disableChn == FALSE) && pChObj->skipFrame)  
  534.             {  
  535.                 if(pBuf->isKeyFrame == TRUE)  
  536.                 {  
  537.                     pChObj->skipFrame = FALSE;  
  538.                 }  
  539.             }  
  540.   
  541.             if (((pChObj->IFrameOnlyDecode) &&  
  542.                 (!pBuf->isKeyFrame)) || pChObj->skipFrame)  
  543.             {  
  544.                 pChObj->inBufSkipCount++;  
  545.   
  546.                 pChObj->inFrameUserSkipCount++;  
  547.   
  548.                 // Drop if not a I frame  
  549.                 bufList.bufs[freeBufNum] = pBuf;  
  550.                 freeBufNum++;  
  551.             }  
  552.             else  
  553.             {  
  554.                 pChObj->totalInFrameCnt++;  
  555.                 if (pChObj->totalInFrameCnt > DEC_LINK_STATS_START_THRESHOLD)  
  556.                 {  
  557.                     pChObj->totalFrameIntervalTime +=  
  558.                         (curTime - pChObj->prevFrmRecvTime);  
  559.                 }  
  560.                 else  
  561.                 {  
  562.                     pChObj->totalFrameIntervalTime = 0;  
  563.                     pChObj->totalProcessTime = 0;  
  564.   
  565.                     DecLink_resetStatistics(pObj);  
  566.                 }  
  567.                 pChObj->prevFrmRecvTime = curTime;  
  568.           
  569.         //将buff压入队列提供解码器  
  570.                 status = Utils_quePut(&pChObj->inQue, pBuf, BIOS_NO_WAIT);  
  571.                 UTILS_assert(status == FVID2_SOK);  
  572.   
  573.                 pChObj->inBufQueCount++;  
  574.             }  
  575.         }  
  576.   
  577.         if (freeBufNum)  
  578.         {  
  579.             bufList.numBufs = freeBufNum;  
  580.             System_putLinksEmptyBufs(pInQueParams->prevLinkId,  
  581.                                      pInQueParams->prevLinkQueId, &bufList);  
  582.             pObj->inBufPutCount += freeBufNum;  
  583.         }  
  584.     }  
  585.   
  586.     return FVID2_SOK;  
  587. }  
  588.   
  589. 4.5)System_getLinksFullBufs函数调用systemLink api(pTsk->linkGetFullBitBufs函数)从上一个link获取bit码流数据  
  590. Int32 System_getLinksFullBufs(UInt32 linkId, UInt16 queId,  
  591.                               Bitstream_BufList * pBufList)  
  592. {  
  593.     System_LinkObj *pTsk;  
  594.   
  595.     linkId = SYSTEM_GET_LINK_ID(linkId);  
  596.   
  597.     UTILS_assert(linkId < SYSTEM_LINK_ID_MAX);  
  598.   
  599.     pTsk = &gSystem_objCommon.linkObj[linkId];  
  600.   
  601.     if (pTsk->linkGetFullBitBufs != NULL)  
  602.         return pTsk->linkGetFullBitBufs(pTsk->pTsk, queId, pBufList);  
  603.   
  604.     return FVID2_EFAIL;  
  605. }  
  606.   
  607.   
  608. 4.6)DecLink_codecSubmitData对bit数据进行解码  
  609. static Int32 DecLink_codecSubmitData(DecLink_Obj * pObj)  
  610. {  
  611.     DecLink_ReqObj *pReqObj;  
  612.     DecLink_ChObj *pChObj;  
  613.     UInt32 chCount,chIdIndex, numProcessCh;  
  614.     Bitstream_Buf *pInBuf;  
  615.     FVID2_Frame *pOutFrame;  
  616.     Int32 status = FVID2_EFAIL, numReqObjPerProcess;  
  617.     UInt32 tskId, i;  
  618.     static UInt32 startChID = 0;  
  619.   
  620.     System_FrameInfo *pOutFrameInfo;  
  621.     UInt32 curTime = Utils_getCurTimeInMsec();  
  622.   
  623.     numProcessCh = 0;  
  624.     chIdIndex    = startChID;  
  625.     for (chCount = 0; chCount < pObj->inQueInfo.numCh; chCount++,chIdIndex++)  
  626.     {  
  627.       numReqObjPerProcess = 0;  
  628.       if (chIdIndex >= pObj->inQueInfo.numCh)  
  629.           chIdIndex = 0;  
  630.       pChObj = &pObj->chObj[chIdIndex];  
  631.       if (Utils_queIsEmpty(&pObj->outObj.bufOutQue.  
  632.                            emptyQue[pChObj->allocPoolID]))  
  633.       {  
  634.           pObj->newDataProcessOnFrameFree = TRUE;  
  635.       }  
  636.   
  637.       while(numReqObjPerProcess < pChObj->numReqObjPerProcess) {  
  638.         numReqObjPerProcess++;  
  639.         status =  
  640.             Utils_queGet(&pObj->reqQue, (Ptr *) & pReqObj, 1,  
  641.                          BIOS_NO_WAIT);  
  642.   
  643.         if (UTILS_ISERROR(status)) {  
  644.             break;  
  645.         }  
  646.         pObj->reqQueCount++;  
  647.         UTILS_assert(DEC_LINK_MAX_REQ >= pObj->reqQueCount);  
  648.   
  649.         tskId = pObj->ch2ProcessTskId[chIdIndex];  
  650.           
  651.         if (pChObj->algObj.algCreateParams.fieldMergeDecodeEnable)  
  652.         {  
  653.            /* pReqObj->OutFrameList.numFrames should be set to 2 once         */  
  654.            /*  codec has support to consume 2 output pointers rather than     */  
  655.            /*  just one pointer with 2 contigous fields in field merged       */  
  656.            /*  interlaced decode use case.                                    */  
  657.             pReqObj->OutFrameList.numFrames = 1;  
  658.         }  
  659.         else  
  660.         {  
  661.             pReqObj->OutFrameList.numFrames = 1;  
  662.         }  
  663.         if ((status == FVID2_SOK) &&  
  664.             (pChObj->inBufQueCount) &&  
  665.             (Utils_queGetQueuedCount(&pObj->outObj.bufOutQue.emptyQue[pChObj->  
  666.                    allocPoolID]) >= pReqObj->OutFrameList.numFrames) &&  
  667.             !(Utils_queIsFull(&pObj->decProcessTsk[tskId].processQue)))  
  668.         {  
  669.             for (i=0; i<pReqObj->OutFrameList.numFrames; i++)  
  670.             {  
  671.                 pOutFrame = NULL;  
  672.                 status =  
  673.                     Utils_bufGetEmptyFrameExt(&pObj->outObj.bufOutQue,  
  674.                                               &pOutFrame,  
  675.                                               pObj->outObj.ch2poolMap[chIdIndex],  
  676.                                               BIOS_NO_WAIT);  
  677.                 if (pOutFrame)  
  678.                 {  
  679.                     declink_codec_init_outframe(pObj, chIdIndex, pOutFrame);  
  680.                     pReqObj->OutFrameList.frames[i] = pOutFrame;  
  681.                 }  
  682.                 else  
  683.                 {  
  684.                     break;  
  685.                 }  
  686.             }  
  687.             if ((status == FVID2_SOK) && (pOutFrame))  
  688.             {  
  689.                 //获取待解码的数据  
  690.                 Utils_queGet(&pChObj->inQue, (Ptr *) & pInBuf, 1, BIOS_NO_WAIT);  
  691.                 UTILS_assert(status == FVID2_SOK);  
  692.                 pReqObj->InBuf = pInBuf;  
  693.                 pChObj->inBufQueCount--;  
  694.   
  695.                 for (i=0; i<pReqObj->OutFrameList.numFrames; i++)  
  696.                 {  
  697.                     pReqObj->OutFrameList.frames[i]->channelNum =  
  698.                                                      pInBuf->channelNum;  
  699.                     //pInBuf->timeStamp  = curTime;  
  700.                     pReqObj->OutFrameList.frames[i]->timeStamp=  
  701.                                pInBuf->timeStamp;  
  702.   
  703.   
  704.                     pOutFrameInfo = (System_FrameInfo *) pReqObj->OutFrameList.frames[i]->appData;  
  705.                     pOutFrameInfo->ts64  = (UInt32)pInBuf->upperTimeStamp;  
  706.                     pOutFrameInfo->ts64 <<= 32;  
  707.                     pOutFrameInfo->ts64  = pOutFrameInfo->ts64 | ((UInt32)pInBuf->lowerTimeStamp);  
  708.                 }  
  709.                 numProcessCh++;  
  710.           
  711.         //插入到解码处理队列  
  712.                 status =  
  713.                     Utils_quePut(&pObj->decProcessTsk[tskId].processQue,  
  714.                                  pReqObj, BIOS_NO_WAIT);  
  715.                 UTILS_assert(status == FVID2_SOK);  
  716.                 pChObj->processReqestCount++;  
  717.             }  
  718.             else  
  719.             {  
  720.                 status = Utils_quePut(&pObj->reqQue, pReqObj, BIOS_NO_WAIT);  
  721.                 startChID = chIdIndex;  
  722.                 UTILS_assert(status == FVID2_SOK);  
  723.                 pObj->reqQueCount--;  
  724.                 status = FVID2_EFAIL;  
  725.                 continue;  
  726.             }  
  727.         }  
  728.         else  
  729.         {  
  730.             status = Utils_quePut(&pObj->reqQue, pReqObj, BIOS_NO_WAIT);  
  731.             UTILS_assert(status == FVID2_SOK);  
  732.             pObj->reqQueCount--;  
  733.             startChID = chIdIndex;  
  734.             status = FVID2_EFAIL;  
  735.             if (Utils_queIsEmpty(&pObj->outObj.bufOutQue.  
  736.                                  emptyQue[pChObj->allocPoolID]))  
  737.             {  
  738.                 pObj->newDataProcessOnFrameFree = TRUE;  
  739.             }  
  740.         }  
  741.       }  
  742.     }  
  743.   
  744.     return status;  
  745. }  
  746.   
  747. 4.7)DecLink_codecCreateProcessTsk函数  
  748. 该函数为解码任务函数;从pObj->decProcessTsk[tskId].processQue队列中获取数据,然后进行解码;  
  749. static Void DecLink_codecProcessTskFxn(UArg arg1, UArg arg2)  
  750. {  
  751.     Int32 status, chId, i, j;  
  752.     DecLink_Obj *pObj;  
  753.     DecLink_ChObj *pChObj;  
  754.     DecLink_ReqObj *pReqObj;  
  755.     FVID2_FrameList freeFrameList;  
  756.     UInt32 tskId;  
  757.   
  758.     pObj = (DecLink_Obj *) arg1;  
  759.     tskId = (UInt32) arg2;  
  760.   
  761.     while (pObj->state != SYSTEM_LINK_STATE_STOP)  
  762.     {  
  763.         pObj->reqObjBatch[tskId].numReqObjsInBatch = 0;  
  764.         status = DEC_LINK_S_SUCCESS;  
  765.       
  766.         //从队列中获取待解码的数据  
  767.         status = Utils_queGet(&pObj->decProcessTsk[tskId].processQue,  
  768.                               (Ptr *) & pReqObj, 1, BIOS_WAIT_FOREVER);  
  769.         if (!UTILS_ISERROR(status))  
  770.         {  
  771.             status = DecLink_PrepareBatch (pObj, tskId, pReqObj,   
  772.                                   &pObj->reqObjBatch[tskId]);  
  773.               
  774.           if (UTILS_ISERROR(status))  
  775.           {  
  776.               UTILS_warn("DEC : IVAHDID : %d ENCLINK:ERROR in "  
  777.                          "DecLink_SubmitBatch.Status[%d]", tskId, status);  
  778.           }  
  779.           else   
  780.           {  
  781.               /*Log Batch size statistics*/  
  782.               pObj->batchStatistics[tskId].numBatchesSubmitted++;  
  783.                 
  784.               pObj->batchStatistics[tskId].currentBatchSize = pObj->  
  785.                 reqObjBatch[tskId].numReqObjsInBatch;  
  786.                 
  787.               if (pObj->batchStatistics[tskId].maxAchievedBatchSize <  
  788.                   pObj->batchStatistics[tskId].currentBatchSize)  
  789.               {  
  790.                 pObj->batchStatistics[tskId].maxAchievedBatchSize =  
  791.                   pObj->batchStatistics[tskId].currentBatchSize;  
  792.               }  
  793.                               
  794.               pObj->batchStatistics[tskId].aggregateBatchSize =   
  795.                 pObj->batchStatistics[tskId].aggregateBatchSize +   
  796.                 pObj->batchStatistics[tskId].currentBatchSize;  
  797.                  
  798.               pObj->batchStatistics[tskId].averageBatchSize =   
  799.                 pObj->batchStatistics[tskId].aggregateBatchSize /  
  800.                 pObj->batchStatistics[tskId].numBatchesSubmitted;  
  801.           }              
  802.         }  
  803.         freeFrameList.numFrames = 0;  
  804.         if (pObj->reqObjBatch[tskId].numReqObjsInBatch)  
  805.         {  
  806.             /*Its made sure that for every batch created all ReqObj have the same 
  807.             codec. And every Request Batch has atleast one ReqObj */  
  808.             chId = pObj->reqObjBatch[tskId].pReqObj[0]->InBuf->channelNum;  
  809.             pChObj = &pObj->chObj[chId];  
  810.             switch (pChObj->algObj.algCreateParams.format)  
  811.             {  
  812.                 case IVIDEO_H264BP:  
  813.                 case IVIDEO_H264MP:  
  814.                 case IVIDEO_H264HP:  
  815.                     status =   
  816.                         Declink_h264DecodeFrameBatch(pObj,   
  817.                                                      &pObj->reqObjBatch[tskId],  
  818.                                                      &freeFrameList, tskId);  
  819.                     if (UTILS_ISERROR(status))  
  820.                     {  
  821.                          #ifndef DEC_LINK_SUPRESS_ERROR_AND_RESET  
  822.                          /* 
  823.                          UTILS_warn("DECLINK:ERROR in " 
  824.                               "Declink_h264DecodeFrameBatch.Status[%d]", status);  
  825.                          */  
  826.                          #endif     
  827.                     }  
  828.                break;  
  829.            
  830.                case IVIDEO_MPEG4SP:  
  831.                case IVIDEO_MPEG4ASP:  
  832.                 status = Declink_mpeg4DecodeFrameBatch(pObj,   
  833.                                                             &pObj->reqObjBatch[tskId],  
  834.                                                             &freeFrameList);  
  835.                 if (UTILS_ISERROR(status))  
  836.                 {  
  837.                   #ifndef DEC_LINK_SUPRESS_ERROR_AND_RESET  
  838.                    UTILS_warn("DECLINK:ERROR in "  
  839.                       "Declink_mpeg4DecodeFrameBatch.Status[%d]", status);  
  840.                   #endif  
  841.   
  842.                 }  
  843.                break;  
  844.   
  845.                 case IVIDEO_MJPEG:  
  846.            //调用该函数进行解码  
  847.                    status =   
  848.                       Declink_jpegDecodeFrameBatch(pObj,   
  849.                                                    &pObj->reqObjBatch[tskId],  
  850.                                                    &freeFrameList);  
  851.                    if (UTILS_ISERROR(status))  
  852.                    {  
  853.                        UTILS_warn("DECLINK:ERROR in "  
  854.                              "Declink_jpegDecodeFrameBatch.Status[%d]", status);  
  855.                    }  
  856.                      
  857.                  break;  
  858.   
  859.                 default:  
  860.                     UTILS_assert(FALSE);  
  861.             }  
  862.         }  
  863.         for (i = 0; i < pObj->reqObjBatch[tskId].numReqObjsInBatch; i++)  
  864.         {  
  865.             pReqObj = pObj->reqObjBatch[tskId].pReqObj[i];  
  866.   
  867.             for (j = 0; j < pReqObj->OutFrameList.numFrames; j++)  
  868.             {  
  869.                 FVID2_Frame *displayFrame;  
  870.   
  871.                     DecLink_codecGetDisplayFrame(pObj,  
  872.                                              pReqObj->OutFrameList.frames[j],  
  873.                                              &freeFrameList, &displayFrame);  
  874.                     pReqObj->OutFrameList.frames[j] = displayFrame;  
  875.   
  876.             }  
  877.           
  878.         //将解码后的数据插入到队列,主函数会调用DecLink_codecGetProcessedDataMsgHandler函数对数据进行处理,发给下一个link;  
  879.             status = Utils_quePut(&pObj->processDoneQue, pReqObj,  
  880.                                   BIOS_NO_WAIT);  
  881.             UTILS_assert(status == FVID2_SOK);  
  882.         }  
  883.           
  884.         DecLink_codecFreeProcessedFrames(pObj, &freeFrameList);  
  885.     }  
  886.   
  887.     return;  
  888. }  
  889.   
  890.   
  891. 4.8)jpeg解码函数(Declink_jpegDecodeFrameBatch)如下:  
  892. Int32 Declink_jpegDecodeFrameBatch(DecLink_Obj * pObj,  
  893.                                    DecLink_ReqBatch * pReqObjBatch,  
  894.                                    FVID2_FrameList * freeFrameList)  
  895. {  
  896.     int error = XDM_EFAIL, reqObjIdx, chId;  
  897.     Int32 i, freeBufIdx, prosIdx;  
  898.     IJPEGVDEC_InArgs *inArgs;  
  899.     IJPEGVDEC_OutArgs *outArgs;  
  900.     XDM2_BufDesc *inputBufDesc;  
  901.     XDM2_BufDesc *outputBufDesc;  
  902.     IJPEGVDEC_Handle handle;  
  903.     IALG_Fxns *fxns = NULL;  
  904.     FVID2_Frame *outFrame = NULL;  
  905.     IVIDEO2_BufDesc *displayBufs = NULL;  
  906.     UInt32 bytesConsumed;  
  907.     DecLink_ReqObj *pReqObj;  
  908.     DecLink_ChObj *pChObj;  
  909.     System_FrameInfo *pFrameInfo;  
  910.   
  911.     /*Make sure that the Req Object is not empty*/  
  912.     UTILS_assert (pReqObjBatch->numReqObjsInBatch > 0);  
  913.       
  914.     for (reqObjIdx = 0; reqObjIdx < pReqObjBatch->numReqObjsInBatch; reqObjIdx++)  
  915.     {  
  916.         pReqObj = pReqObjBatch->pReqObj[reqObjIdx];  
  917.         chId = pReqObj->InBuf->channelNum;  
  918.         pChObj = &pObj->chObj[chId];  
  919.           
  920.         inArgs = &pChObj->algObj.u.jpegAlgIfObj.inArgs;  
  921.         outArgs = &pChObj->algObj.u.jpegAlgIfObj.outArgs;  
  922.         inputBufDesc = &pChObj->algObj.u.jpegAlgIfObj.inBufs;  
  923.         outputBufDesc = &pChObj->algObj.u.jpegAlgIfObj.outBufs;  
  924.         handle = pChObj->algObj.u.jpegAlgIfObj.algHandle;  
  925.           
  926.         UTILS_assert(handle != NULL);  
  927.           
  928.         fxns = (IALG_Fxns *) handle->fxns;  
  929.   
  930.   
  931.         //IRESMAN_HDVICP2_EarlyAcquire((IALG_Handle) handle,  
  932.         //                             pChObj->algObj.u.jpegAlgIfObj.ivaChID);  
  933.   
  934.         bytesConsumed = 0;  
  935.   
  936.         for (prosIdx=0; prosIdx< pReqObj->OutFrameList.numFrames; prosIdx++)  
  937.         {  
  938.             /*----------------------------------------------------------------*/  
  939.             /* Initialize the input ID in input arguments to the bufferid of  */  
  940.             /* buffer element returned from getfreebuffer() function.         */  
  941.             /*----------------------------------------------------------------*/  
  942.             /* inputID & numBytes need to update before every decode call */  
  943.   
  944.             if (FALSE == outArgs->viddecOutArgs.outBufsInUseFlag)  
  945.             {  
  946.                 outFrame = pReqObj->OutFrameList.frames[prosIdx];  
  947.             }  
  948.             else  
  949.             {  
  950.                 UTILS_assert(NULL != pChObj->algObj.prevOutFrame);  
  951.                 /* Previous buffer was in use. Free the current outBuf */  
  952.                 outFrame = pChObj->algObj.prevOutFrame;  
  953.                 freeFrameList->frames[freeFrameList->numFrames] =   
  954.                                 pReqObj->OutFrameList.frames[prosIdx];  
  955.                 pChObj->numBufsInCodec--;  
  956.                 freeFrameList->numFrames++;  
  957.             }  
  958.   
  959.             inArgs->viddecInArgs.inputID = (UInt32) outFrame;  
  960.             inArgs->viddecInArgs.numBytes = pReqObj->InBuf->fillLength -   
  961.                                                             bytesConsumed;  
  962.   
  963.             for (i = 0; i < inputBufDesc->numBufs; i++)  
  964.             {  
  965.                 /* Set proper buffer addresses for bitstreamn data */  
  966.                 /*---------------------------------------------------------------*/  
  967.                 inputBufDesc->descs[i].buf = (XDAS_Int8 *) pReqObj->InBuf->addr   
  968.                                                            +  bytesConsumed;  
  969.                 inputBufDesc->descs[i].bufSize.bytes = pReqObj->InBuf->bufSize;  
  970.             }  
  971.   
  972.             for (i = 0; i < outputBufDesc->numBufs; i++)  
  973.             {  
  974.                 /* Set proper buffer addresses for Frame data */  
  975.                 /*------------------------------------------------------------*/  
  976.                 if (pChObj->algObj.algCreateParams.tilerEnable)  
  977.                 {  
  978.                     outputBufDesc->descs[i].buf =  
  979.                         (Ptr)  
  980.                         Utils_tilerAddr2CpuAddr((UInt32) (outFrame->addr[0][i]));  
  981.                 }  
  982.                 else  
  983.                 {  
  984.                     outputBufDesc->descs[i].buf = outFrame->addr[0][i];  
  985.                 }  
  986.             }  
  987.             
  988.             fxns->algActivate((IALG_Handle) handle);  
  989.   
  990.         //调用visa api进行jpeg解码  
  991.             error = handle->fxns->ividdec.process((IVIDDEC3_Handle) handle,  
  992.                                                   inputBufDesc,  
  993.                                                   outputBufDesc,  
  994.                                                   (IVIDDEC3_InArgs *) inArgs,  
  995.                                                   (IVIDDEC3_OutArgs *) outArgs);  
  996.             fxns->algDeactivate((IALG_Handle) handle);  
  997.             bytesConsumed = outArgs->viddecOutArgs.bytesConsumed;  
  998.             if (error != XDM_EOK)  
  999.             {  
  1000.                 DECLINK_INTERNAL_ERROR_LOG(error, "ALGPROCESS FAILED:STATUS");  
  1001.             }  
  1002.             pChObj->algObj.prevOutFrame = outFrame;  
  1003.             pReqObj->status = error;  
  1004.             pReqObj->OutFrameList.frames[prosIdx] = NULL;  
  1005.             UTILS_assert(outArgs->viddecOutArgs.displayBufsMode ==  
  1006.                          IVIDDEC3_DISPLAYBUFS_EMBEDDED);  
  1007.             displayBufs = &(outArgs->viddecOutArgs.displayBufs.bufDesc[0]);  
  1008.             if ((outArgs->viddecOutArgs.outputID[0] != 0)  
  1009.                 && (displayBufs->numPlanes))  
  1010.             {  
  1011.                 XDAS_Int8 *pExpectedBuf;  
  1012.   
  1013.                 pReqObj->OutFrameList.frames[prosIdx] =  
  1014.                   (FVID2_Frame *) outArgs->viddecOutArgs.outputID[0];  
  1015.                 if (pChObj->algObj.algCreateParams.tilerEnable)  
  1016.                 {  
  1017.                     pExpectedBuf = (Ptr) Utils_tilerAddr2CpuAddr(  
  1018.                         (UInt32) pReqObj->OutFrameList.frames[prosIdx]->addr[0][0]);  
  1019.                 }  
  1020.                 else  
  1021.                 {  
  1022.                     pExpectedBuf = pReqObj->OutFrameList.frames[prosIdx]->addr[0][0];  
  1023.                 }  
  1024.                 UTILS_assert(displayBufs->planeDesc[0].buf == pExpectedBuf);  
  1025.                 /* Enable this code once SysTemFrameInfo is updated with support 
  1026.                  * for storing frame resolution info */  
  1027.                 pFrameInfo = (System_FrameInfo *)   
  1028.                              pReqObj->OutFrameList.frames[prosIdx]->appData;  
  1029.                 {  
  1030.                     UTILS_assert(pFrameInfo != NULL);  
  1031.                     pFrameInfo->rtChInfo.width =  
  1032.                         displayBufs->activeFrameRegion.bottomRight.x -  
  1033.                         displayBufs->activeFrameRegion.topLeft.x;  
  1034.                     pFrameInfo->rtChInfo.height =  
  1035.                         displayBufs->activeFrameRegion.bottomRight.y -  
  1036.                         displayBufs->activeFrameRegion.topLeft.y;  
  1037.                     pFrameInfo->rtChInfo.pitch[0] = displayBufs->imagePitch[0];  
  1038.                     pFrameInfo->rtChInfo.pitch[1] = displayBufs->imagePitch[1];  
  1039.                     pFrameInfo->rtChInfoUpdate = TRUE;  
  1040.                 }  
  1041.                 pReqObj->OutFrameList.frames[prosIdx]->fid =  
  1042.                     Utils_encdecMapXDMContentType2FVID2FID(displayBufs->  
  1043.                                                            contentType);  
  1044.             }  
  1045.             freeBufIdx = 0;  
  1046.             while (outArgs->viddecOutArgs.freeBufID[freeBufIdx] != 0)  
  1047.             {  
  1048.                 freeFrameList->frames[freeFrameList->numFrames] =  
  1049.                   (FVID2_Frame *) outArgs->viddecOutArgs.freeBufID[freeBufIdx];  
  1050.                 freeFrameList->numFrames++;  
  1051.                 pChObj->numBufsInCodec--;  
  1052.                 freeBufIdx++;  
  1053.             }  
  1054.         }  
  1055.       
  1056.     }  
  1057.   
  1058.     return (error);  
  1059. }  
  1060.   
  1061. 4.9)DecLink_codecGetProcessedDataMsgHandler函数功能获取解码后的数据,该函数在DecLink_tskMain中调用;  
  1062. Int32 DecLink_codecGetProcessedDataMsgHandler(DecLink_Obj * pObj)  
  1063. {  
  1064.     Int32 status;  
  1065.   
  1066.     status = DecLink_codecGetProcessedData(pObj);  
  1067.     UTILS_assert(status == FVID2_SOK);  
  1068.   
  1069.     return DEC_LINK_S_SUCCESS;  
  1070.   
  1071. }  
  1072.   
  1073. 4.10)DecLink_codecGetProcessedData 处理解码后的数据,发给下一个link  
  1074.   
  1075.   
  1076. static Int32 DecLink_codecGetProcessedData(DecLink_Obj * pObj)  
  1077. {  
  1078.     Bitstream_BufList inBufList;  
  1079.     FVID2_FrameList outFrameList;  
  1080.     FVID2_FrameList outFrameSkipList;  
  1081.     UInt32 chId, sendCmd;  
  1082.     System_LinkInQueParams *pInQueParams;  
  1083.     DecLink_ChObj *pChObj;  
  1084.     DecLink_ReqObj *pReqObj;  
  1085.     Int32 status, j;  
  1086.     UInt32 curTime;  
  1087.   
  1088.     sendCmd = FALSE;  
  1089.     inBufList.numBufs = 0;  
  1090.     inBufList.appData = NULL;  
  1091.     outFrameList.numFrames = 0;  
  1092.     outFrameSkipList.numFrames = 0;  
  1093.     curTime = Utils_getCurTimeInMsec();  
  1094.   
  1095.     while(!Utils_queIsEmpty(&pObj->processDoneQue)  
  1096.           &&  
  1097.           (inBufList.numBufs < (VIDBITSTREAM_MAX_BITSTREAM_BUFS - 1))  
  1098.           &&  
  1099.           (outFrameList.numFrames < (FVID2_MAX_FVID_FRAME_PTR - 1)))  
  1100.     {  
  1101.     //获取解码后的数据  
  1102.         status = Utils_queGet(&pObj->processDoneQue, (Ptr *) & pReqObj, 1,  
  1103.                               BIOS_NO_WAIT);  
  1104.         if (status != FVID2_SOK)  
  1105.         {  
  1106.             break;  
  1107.         }  
  1108.   
  1109.         UTILS_assert(pReqObj->InBuf != NULL);  
  1110.         chId = pReqObj->InBuf->channelNum;  
  1111.         pChObj = &pObj->chObj[chId];  
  1112.   
  1113.         //if (pChObj->totalInFrameCnt > DEC_LINK_STATS_START_THRESHOLD)  
  1114.         {  
  1115.             if (curTime > pReqObj->InBuf->timeStamp)  
  1116.             {  
  1117.                 pChObj->totalProcessTime +=  
  1118.                      (curTime - pReqObj->InBuf->timeStamp);  
  1119.             }  
  1120.         }  
  1121.   
  1122.         pChObj->getProcessedBufCount++;  
  1123.   
  1124.         pChObj->outFrameCount++;  
  1125.   
  1126.         inBufList.bufs[inBufList.numBufs] = pReqObj->InBuf;  
  1127.         inBufList.numBufs++;  
  1128.   
  1129.         for (j = 0; j < pReqObj->OutFrameList.numFrames; j++)  
  1130.         {  
  1131.             if (pReqObj->OutFrameList.frames[j])  
  1132.             {  
  1133.                 UTILS_assert(pReqObj->InBuf->channelNum ==  
  1134.                              pReqObj->OutFrameList.frames[j]->channelNum);  
  1135.                 UTILS_assert(pChObj->allocPoolID < UTILS_BUF_MAX_ALLOC_POOLS);  
  1136.   
  1137.   
  1138.                 pChObj->trickPlayObj.skipFrame = Utils_doSkipFrame(&(pChObj->trickPlayObj.frameSkipCtx));  
  1139.   
  1140.                 if (pChObj->trickPlayObj.skipFrame == TRUE)  
  1141.                 {  
  1142.                     /* Skip the output frame */  
  1143.                     outFrameSkipList.frames[outFrameSkipList.numFrames] =  
  1144.                                         pReqObj->OutFrameList.frames[j];  
  1145.                     outFrameSkipList.numFrames++;  
  1146.                 }  
  1147.                 else  
  1148.                 {  
  1149.                     outFrameList.frames[outFrameList.numFrames] =  
  1150.                                         pReqObj->OutFrameList.frames[j];  
  1151.                     outFrameList.numFrames++;  
  1152.                 }  
  1153.             }  
  1154.         }  
  1155.     //归还队列;  
  1156.         status = Utils_quePut(&pObj->reqQue, pReqObj, BIOS_NO_WAIT);  
  1157.         UTILS_assert(status == FVID2_SOK);  
  1158.         pObj->reqQueCount--;  
  1159.     }  
  1160.   
  1161.     if (outFrameList.numFrames)  
  1162.     {  
  1163.     //解码后的数据,压入到队列,供下一个link使用  
  1164.         status = Utils_bufPutFullExt(&pObj->outObj.bufOutQue,  
  1165.                                      &outFrameList);  
  1166.         UTILS_assert(status == FVID2_SOK);  
  1167.         sendCmd = TRUE;  
  1168.     }  
  1169.   
  1170.     if (outFrameSkipList.numFrames)  
  1171.     {  
  1172.         status = DecLink_codecFreeProcessedFrames(pObj, &outFrameSkipList);  
  1173.         UTILS_assert(status == DEC_LINK_S_SUCCESS);  
  1174.     }  
  1175.   
  1176.     if (inBufList.numBufs)  
  1177.     {  
  1178.         /* Free input frames */  
  1179.         pInQueParams = &pObj->createArgs.inQueParams;  
  1180.         System_putLinksEmptyBufs(pInQueParams->prevLinkId,  
  1181.                                  pInQueParams->prevLinkQueId, &inBufList);  
  1182.         pObj->inBufPutCount += inBufList.numBufs;  
  1183.     }  
  1184.   
  1185.     /* Send-out the output bitbuffer */  
  1186.     if (sendCmd == TRUE)  
  1187.     {  
  1188.     //往下一个link发送消息,告诉下一个link数据已经准备好了  
  1189.         System_sendLinkCmd(pObj->createArgs.outQueParams.nextLink,  
  1190.                            SYSTEM_CMD_NEW_DATA);  
  1191.     }  
  1192.   
  1193.     return FVID2_SOK;  
  1194. }  
  1195.   
  1196.   
  1197. 4.11)Utils_bufPutFullExt 就是将buff压入到输出full队列,然后提供api供外部的其他link使用;  
  1198. Int32 Utils_bufPutFullExt(Utils_BufHndlExt * pHndl,   
  1199.                           FVID2_FrameList * pFrameList)  
  1200. {  
  1201.     UInt32 idx;  
  1202.     Int32 status;  
  1203.   
  1204.     UTILS_assert(pHndl != NULL);  
  1205.     UTILS_assert(pFrameList != NULL);  
  1206.     UTILS_assert(pFrameList->numFrames <= FVID2_MAX_FVID_FRAME_PTR);  
  1207.   
  1208.     for (idx = 0; idx < pFrameList->numFrames; idx++)  
  1209.     {  
  1210.         status =  
  1211.             Utils_quePut(&pHndl->fullQue, pFrameList->frames[idx],  
  1212.                          BIOS_NO_WAIT);  
  1213.         UTILS_assert(status == FVID2_SOK);  
  1214.     }  
  1215.   
  1216.     return FVID2_SOK;  
  1217. }  
  1218.   
  1219. 4.12)DecLink_getFullFrames 函数提供外部调用,获取解码后的帧数据;  
  1220.   
  1221. Int32 DecLink_getFullFrames(Utils_TskHndl * pTsk, UInt16 queId,  
  1222.                             FVID2_FrameList * pFrameList)  
  1223. {  
  1224.     DecLink_Obj *pObj = (DecLink_Obj *) pTsk->appData;  
  1225.   
  1226.     UTILS_assert(queId < DEC_LINK_MAX_OUT_QUE);  
  1227.   
  1228.     return Utils_bufGetFullExt(&pObj->outObj.bufOutQue, pFrameList,  
  1229.                                BIOS_NO_WAIT);  
  1230. }  
  1231.   
  1232. 在解码器初始化函数已经注册了该回调函数  
  1233.      linkObj.linkGetFullFrames = DecLink_getFullFrames;  
  1234.   
  1235. 在下一个link调用preLink的该函数获取解码后的数据;  
  1236.   
  1237.   
  1238. 5)IpcFrameOutM3  
  1239. 5.1)IpcFramesOutLink_tskMain函数中调用 IpcFramesOutLink_processFrameBufs获取解码后的数据;  
  1240. Void IpcFramesOutLink_tskMain(struct Utils_TskHndl * pTsk, Utils_MsgHndl * pMsg)  
  1241. {  
  1242.     UInt32 cmd = Utils_msgGetCmd(pMsg);  
  1243.     Bool ackMsg, done;  
  1244.     Int32 status;  
  1245.     IpcFramesOutLink_Obj *pObj = (IpcFramesOutLink_Obj *) pTsk->appData;  
  1246.   
  1247.     if (cmd != SYSTEM_CMD_CREATE)  
  1248.     {  
  1249.         Utils_tskAckOrFreeMsg(pMsg, FVID2_EFAIL);  
  1250.         return;  
  1251.     }  
  1252.   
  1253.     status = IpcFramesOutLink_create(pObj, Utils_msgGetPrm(pMsg));  
  1254.   
  1255.     Utils_tskAckOrFreeMsg(pMsg, status);  
  1256.   
  1257.     if (status != FVID2_SOK)  
  1258.         return;  
  1259.   
  1260.     done = FALSE;  
  1261.     ackMsg = FALSE;  
  1262.   
  1263.     while (!done)  
  1264.     {  
  1265.         status = Utils_tskRecvMsg(pTsk, &pMsg, BIOS_WAIT_FOREVER);  
  1266.         if (status != FVID2_SOK)  
  1267.             break;  
  1268.   
  1269.         cmd = Utils_msgGetCmd(pMsg);  
  1270.   
  1271.         switch (cmd)  
  1272.         {  
  1273.             case SYSTEM_CMD_DELETE:  
  1274.                 done = TRUE;  
  1275.                 ackMsg = TRUE;  
  1276.                 break;  
  1277.             case SYSTEM_CMD_NEW_DATA:  
  1278.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  1279.   
  1280.                 IpcFramesOutLink_processFrameBufs(pObj);  
  1281.                 IpcFramesOutLink_releaseFrameBufs(pObj);  
  1282.                 break;  
  1283.   
  1284.             case IPCFRAMESOUTRTOS_LINK_CMD_SET_FRAME_RATE:  
  1285.                 {  
  1286.                     IpcOutM3Link_ChFpsParams *params;  
  1287.   
  1288.                     params = (IpcOutM3Link_ChFpsParams *) Utils_msgGetPrm(pMsg);  
  1289.                     IpcFramesOutLink_SetFrameRate(pObj, params);  
  1290.                     Utils_tskAckOrFreeMsg(pMsg, status);  
  1291.                 }  
  1292.                 break;  
  1293.   
  1294.             case IPCFRAMESOUTRTOS_LINK_CMD_PRINT_STATISTICS:  
  1295.                 IpcFramesOutLink_printStatistics(pObj, TRUE);  
  1296.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  1297.                 break;  
  1298.   
  1299.   
  1300.             case SYSTEM_IPC_CMD_RELEASE_FRAMES:  
  1301.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  1302.   
  1303. #ifdef SYSTEM_DEBUG_IPC_RT  
  1304.                 Vps_printf(" %d: IPC_FRAMES_OUT   : Received Notify !!!\n",  
  1305.                            Utils_getCurTimeInMsec());  
  1306. #endif  
  1307.   
  1308.                 IpcFramesOutLink_releaseFrameBufs(pObj);  
  1309.                 break;  
  1310.   
  1311.             default:  
  1312.                 Utils_tskAckOrFreeMsg(pMsg, status);  
  1313.                 break;  
  1314.         }  
  1315.     }  
  1316.   
  1317.     IpcFramesOutLink_delete(pObj);  
  1318.   
  1319. #ifdef SYSTEM_DEBUG_IPC_FRAMES_OUT  
  1320.     Vps_printf(" %d: IPC_FRAMES_OUT   : Delete Done !!!\n", Utils_getCurTimeInMsec());  
  1321. #endif  
  1322.   
  1323.     if (ackMsg && pMsg != NULL)  
  1324.         Utils_tskAckOrFreeMsg(pMsg, status);  
  1325.   
  1326.     return;  
  1327. }  
  1328.   
  1329.   
  1330. 5.2)IpcFramesOutLink_processFrameBufs获取数据;  
  1331.   
  1332.   
  1333. Int32 IpcFramesOutLink_processFrameBufs(IpcFramesOutLink_Obj * pObj)  
  1334. {  
  1335.     System_LinkInQueParams *pInQueParams;  
  1336.     FVID2_FrameList bufList;  
  1337.     FVID2_Frame *pFrameBuf = NULL;  
  1338.     SystemIpcFrames_ListElem *pListElem;  
  1339.     Int32 status;  
  1340.     Int32 bufId;  
  1341.     UInt32 curTime;  
  1342.     FVID2_FrameList freeFrameBufList;  
  1343.     UInt8 queId;  
  1344.     UInt32 sendMsgToTsk = 0;  
  1345.     UInt32 chPerQueue;  
  1346.     IpcFramesOutLink_ChObj *pChObj;  
  1347.   
  1348.     pInQueParams = &pObj->createArgs.baseCreateParams.inQueParams;  
  1349.   
  1350.     bufList.numFrames = 0;  
  1351.   
  1352.     //下面函数是从解码link获取数据,数据保存在bufList中;  
  1353.     System_getLinksFullFrames(pInQueParams->prevLinkId,  
  1354.                             pInQueParams->prevLinkQueId, &bufList);  
  1355.   
  1356.     freeFrameBufList.numFrames = 0;  
  1357.     curTime = Utils_getCurTimeInMsec();  
  1358.     if (bufList.numFrames)  
  1359.     {  
  1360. #ifdef SYSTEM_DEBUG_IPC_RT  
  1361.         Vps_printf(" %d: IPC_FRAMES_OUT   : Received %d framebufs !!!\n",  
  1362.                    Utils_getCurTimeInMsec(), bufList.numFrames);  
  1363. #endif  
  1364.   
  1365.         UTILS_assert(bufList.numFrames <= FVID2_MAX_FVID_FRAME_PTR);  
  1366.         pObj->stats.recvCount += bufList.numFrames;  
  1367.         sendMsgToTsk = 0;  
  1368.         chPerQueue =  
  1369.             (pObj->numCh / pObj->createArgs.baseCreateParams.numOutQue);  
  1370.   
  1371. #ifdef IPC_FRAMES_IN_ENABLE_PROFILE  
  1372.         Utils_prfTsBegin(pObj->stats.tsHandle);  
  1373. #endif                                                     /* IPC_FRAMES_IN_ENABLE_PROFILE  
  1374.                                                             */  
  1375.         pObj->totalFrameCount += bufList.numFrames;  
  1376.         for (bufId = 0; bufId < bufList.numFrames; bufId++)  
  1377.         {  
  1378.             Bool          doFrameDrop;  
  1379.   
  1380.             pFrameBuf = bufList.frames[bufId];  
  1381.             UTILS_assert(pFrameBuf != NULL);  
  1382.   
  1383.             pChObj = &pObj->chObj[pFrameBuf->channelNum];  
  1384.             pChObj->inFrameRecvCount++;  
  1385.             doFrameDrop = Utils_doSkipFrame(&(pChObj->frameSkipCtx));  
  1386.   
  1387.             /* frame skipped due to user setting */  
  1388.             if(doFrameDrop)  
  1389.             {  
  1390.                 pChObj->inFrameUserSkipCount++;  
  1391.                 UTILS_assert(freeFrameBufList.numFrames <  
  1392.                              FVID2_MAX_FVID_FRAME_PTR);  
  1393.                 freeFrameBufList.frames[freeFrameBufList.numFrames] =  
  1394.                     pFrameBuf;  
  1395.                 freeFrameBufList.numFrames++;  
  1396.                 pObj->stats.droppedCount++;  
  1397.                 continue;  
  1398.             }  
  1399.   
  1400.             queId = (pFrameBuf->channelNum / chPerQueue);  
  1401.         //从队列中取一个buff,赋值给pListElem  
  1402.             status =  
  1403.                 Utils_queGet(&pObj->listElemQue, (Ptr *) & pListElem, 1,  
  1404.                              BIOS_NO_WAIT);  
  1405.             UTILS_assert(!UTILS_ISERROR(status));  
  1406.             if (status != FVID2_SOK)  
  1407.             {  
  1408.                 /* normally this condition should not happen, if it happens 
  1409.                  * return the framebuf back to its generator */  
  1410. #if 0  
  1411.                 Vps_printf(" IPC_OUT: Dropping framebuf\n");  
  1412. #endif  
  1413.   
  1414.                 UTILS_assert(freeFrameBufList.numFrames <  
  1415.                              FVID2_MAX_FVID_FRAME_PTR);  
  1416.                 freeFrameBufList.frames[freeFrameBufList.numFrames] =  
  1417.                     pFrameBuf;  
  1418.                 freeFrameBufList.numFrames++;  
  1419.                 pObj->stats.droppedCount++;  
  1420.                 pChObj->inFrameUserSkipCount++;  
  1421.                 continue;  
  1422.             }  
  1423.             UTILS_assert(SYSTEM_IPC_FRAMES_GET_BUFSTATE(pListElem->bufState)  
  1424.                          == IPC_FRAMEBUF_STATE_FREE);  
  1425.             UTILS_assert(SYSTEM_IPC_FRAMES_GET_BUFOWNERPROCID(pListElem->bufState)  
  1426.                          == System_getSelfProcId());  
  1427.             SYSTEM_IPC_FRAMES_SET_BUFSTATE(pListElem->bufState,  
  1428.                                          IPC_FRAMEBUF_STATE_ALLOCED);  
  1429.             IpcFramesOutLink_copyFrameBufInfo2ListElem(pObj, pListElem, pFrameBuf);  
  1430.             pFrameBuf->timeStamp = curTime;  
  1431.             SYSTEM_IPC_FRAMES_SET_BUFSTATE(pListElem->bufState,  
  1432.                                          IPC_FRAMEBUF_STATE_OUTQUE);  
  1433.             sendMsgToTsk |= (1 << queId);  
  1434.           
  1435.         //压入到ListMP,提供给IpcFrameInLink(A8)调用;  
  1436.             status =  
  1437.                 ListMP_putTail(pObj->listMPOutHndl, (ListMP_Elem *) pListElem);  
  1438.             UTILS_assert(status == ListMP_S_SUCCESS);  
  1439.             pChObj->inFrameProcessCount++;  
  1440.         }  
  1441.   
  1442. #ifdef IPC_FRAMES_IN_ENABLE_PROFILE  
  1443.         Utils_prfTsEnd(pObj->stats.tsHandle, bufList.numFrames);  
  1444. #endif                                                     /* IPC_FRAMES_IN_ENABLE_PROFILE  
  1445.                                                             */  
  1446.   
  1447.         if (freeFrameBufList.numFrames)  
  1448.         {  
  1449.             System_putLinksEmptyFrames(pInQueParams->prevLinkId,  
  1450.                                      pInQueParams->prevLinkQueId,  
  1451.                                      &freeFrameBufList);  
  1452.         }  
  1453.   
  1454.         /* ProcessLink enable, send the notification to processLink else send to next Link */  
  1455.         //发送通知;  
  1456.       
  1457.         if (pObj->createArgs.baseCreateParams.processLink != SYSTEM_LINK_ID_INVALID)  
  1458.         {  
  1459.             if (pObj->createArgs.baseCreateParams.notifyProcessLink)  
  1460.             {  
  1461.                 System_ipcSendNotify(pObj->createArgs.baseCreateParams.processLink);  
  1462.             }  
  1463.         }  
  1464.         else  
  1465.         {  
  1466.             for (queId = 0; queId < pObj->createArgs.baseCreateParams.numOutQue; queId++)  
  1467.             {  
  1468.                 if ((pObj->createArgs.baseCreateParams.notifyNextLink) && (sendMsgToTsk & 0x1))  
  1469.                 {  
  1470.                     System_ipcSendNotify(pObj->createArgs.baseCreateParams.outQueParams[queId].  
  1471.                         nextLink);  
  1472.                 }  
  1473.                 sendMsgToTsk >>= 1;  
  1474.                 if (sendMsgToTsk == 0)  
  1475.                     break;  
  1476.             }  
  1477.         }  
  1478.   
  1479.         if (pObj->createArgs.baseCreateParams.noNotifyMode)  
  1480.         {  
  1481.             if (FALSE == pObj->prd.clkStarted)  
  1482.             {  
  1483.                 IpcFramesOutLink_startPrdObj(pObj,  
  1484.                                            IPC_FRAMESOUT_LINK_DONE_PERIOD_MS,  
  1485.                                            FALSE);  
  1486.             }  
  1487.         }  
  1488.     }  
  1489.   
  1490.     return FVID2_SOK;  
  1491. }  
  1492.   
  1493.   
  1494. 7)IpcFrameInHost(A8)  
  1495. A8如何获取到数据;  
  1496.   
  1497. 7.1)IpcFramesInLink_tskMain 函数  
  1498. static  
  1499. Int IpcFramesInLink_tskMain(struct OSA_TskHndl * pTsk, OSA_MsgHndl * pMsg,  
  1500.                             Uint32 curState)  
  1501. {  
  1502.     UInt32 cmd = OSA_msgGetCmd(pMsg);  
  1503.     Bool ackMsg, done;  
  1504.     Int status = IPC_FRAMES_IN_LINK_S_SUCCESS;  
  1505.     IpcFramesInLink_Obj *pObj = (IpcFramesInLink_Obj *) pTsk->appData;  
  1506.   
  1507.     OSA_printf("%s:Entered", __func__);  
  1508.   
  1509.     if (cmd != SYSTEM_CMD_CREATE)  
  1510.     {  
  1511.         OSA_tskAckOrFreeMsg(pMsg, OSA_EFAIL);  
  1512.         return status;  
  1513.     }  
  1514.   
  1515.     status = IpcFramesInLink_create(pObj, OSA_msgGetPrm(pMsg));  
  1516.   
  1517.     OSA_tskAckOrFreeMsg(pMsg, status);  
  1518.   
  1519.     if (status != OSA_SOK)  
  1520.         return status;  
  1521.   
  1522.     done = FALSE;  
  1523.     ackMsg = FALSE;  
  1524.   
  1525.     while (!done)  
  1526.     {  
  1527.         status = OSA_tskWaitMsg(pTsk, &pMsg);  
  1528.         if (status != OSA_SOK)  
  1529.             break;  
  1530.   
  1531.         cmd = OSA_msgGetCmd(pMsg);  
  1532.   
  1533.         switch (cmd)  
  1534.         {  
  1535.             case SYSTEM_CMD_DELETE:  
  1536.                 done = TRUE;  
  1537.                 ackMsg = TRUE;  
  1538.                 break;  
  1539.             case SYSTEM_CMD_NEW_DATA:  
  1540.                 OSA_tskAckOrFreeMsg(pMsg, status);  
  1541.                 //OSA_assert(pObj->prd.numPendingCmd > 0);  
  1542.                 OSA_mutexLock(&pObj->prd.mutexPendingCmd);  
  1543.                 pObj->prd.numPendingCmd--;  
  1544.                 OSA_mutexUnlock(&pObj->prd.mutexPendingCmd);  
  1545.                 //从ipcOutLink中获取数据  
  1546.                 IpcFramesInLink_processFrameBufs(pObj);  
  1547.                 break;  
  1548.             case SYSTEM_CMD_STOP:  
  1549.                 IpcFramesInLink_stop(pObj);  
  1550.                 OSA_tskAckOrFreeMsg(pMsg, status);  
  1551.                 break;  
  1552.             default:  
  1553.                 OSA_tskAckOrFreeMsg(pMsg, status);  
  1554.                 break;  
  1555.         }  
  1556.     }  
  1557.   
  1558.     IpcFramesInLink_delete(pObj);  
  1559.   
  1560. #ifdef SYSTEM_DEBUG_IPC_FRAMES_IN  
  1561.     OSA_printf(" %d: IPC_FRAMES_IN   : Delete Done !!!\n", OSA_getCurTimeInMsec());  
  1562. #endif  
  1563.   
  1564.     if (ackMsg && pMsg != NULL)  
  1565.         OSA_tskAckOrFreeMsg(pMsg, status);  
  1566.   
  1567.     return IPC_FRAMES_IN_LINK_S_SUCCESS;  
  1568. }  
  1569.   
  1570. 7.2)IpcFramesInLink_processFrameBufs 调用ListMP_getHead获取listElem,然后  
  1571. static  
  1572. Int32 IpcFramesInLink_processFrameBufs(IpcFramesInLink_Obj * pObj)  
  1573. {  
  1574.     VIDFrame_Buf *pFrameBuf;  
  1575.     SystemIpcFrames_ListElem *pListElem;  
  1576.     UInt32 numFrameBufs;  
  1577.     Int32 status;  
  1578.     UInt32 curTime;  
  1579.   
  1580.     numFrameBufs = 0;  
  1581.     curTime = OSA_getCurTimeInMsec();  
  1582.     while (1)  
  1583.     {  
  1584.         pListElem = ListMP_getHead(pObj->listMPOutHndl);  
  1585.         if (pListElem == NULL)  
  1586.             break;  
  1587.   
  1588.         IpcFramesInLink_getFrameBuf(pObj, pListElem, &pFrameBuf);  
  1589.         OSA_assert(SYSTEM_IPC_FRAMES_GET_BUFSTATE(pListElem->bufState)  
  1590.                      == IPC_FRAMEBUF_STATE_OUTQUE);  
  1591.         pListElem->timeStamp = curTime;  
  1592.         pListElem->frameBuf.linkPrivate = (Ptr)pListElem;  
  1593.         SYSTEM_IPC_FRAMES_SET_BUFOWNERPROCID(pListElem->bufState);  
  1594.         SYSTEM_IPC_FRAMES_SET_BUFSTATE(pListElem->bufState,  
  1595.                                      IPC_FRAMEBUF_STATE_DEQUEUED);  
  1596.         pObj->stats.recvCount++;  
  1597.     //压入队列  
  1598.         status = OSA_quePut(&pObj->outFrameBufQue,  
  1599.                             (Int32)pFrameBuf, OSA_TIMEOUT_NONE);  
  1600.         OSA_assert(status == OSA_SOK);  
  1601.   
  1602.         numFrameBufs++;  
  1603.     }  
  1604.   
  1605. #ifdef SYSTEM_DEBUG_IPC_RT  
  1606.     OSA_printf(" %d: IPC_FRAMES_IN   : Recevived %d framebufs !!!\n",  
  1607.                OSA_getCurTimeInMsec(), numFrameBufs);  
  1608. #endif  
  1609.   
  1610.     if (numFrameBufs)  
  1611.     {  
  1612.         if (pObj->createArgs.cbFxn)  
  1613.         {  
  1614.             pObj->createArgs.cbFxn(pObj->createArgs.cbCtx);  
  1615.         }  
  1616.     }  
  1617.   
  1618.     return IPC_FRAMES_IN_LINK_S_SUCCESS;  
  1619. }  
  1620.   
  1621. 7.3)IpcFramesInLink_getFullFrames提供给外部api使用(IpcFramesInLink_getFullVideoFrames函数)  
  1622. static  
  1623. Int32 IpcFramesInLink_getFullFrames(IpcFramesInLink_Obj * pObj,  
  1624.                                     VIDFrame_BufList * pFrameBufList)  
  1625. {  
  1626.     UInt32 idx;  
  1627.     Int32 status;  
  1628.     VIDFrame_Buf *pFrame;  
  1629.   
  1630.     for (idx = 0; idx < VIDFRAME_MAX_FRAME_BUFS; idx++)  
  1631.     {  
  1632.         status =  
  1633.             OSA_queGet(&pObj->outFrameBufQue, (Int32 *) & pFrame,  
  1634.                        OSA_TIMEOUT_NONE);  
  1635.         if (status != OSA_SOK)  
  1636.             break;  
  1637.         pFrameBufList->frames[idx] = *pFrame;  
  1638.     }  
  1639.   
  1640.     pFrameBufList->numFrames = idx;  
  1641.   
  1642.     return IPC_FRAMES_IN_LINK_S_SUCCESS;  
  1643. }  

猜你喜欢

转载自blog.csdn.net/u012635648/article/details/78749938