ti8148 dvrrdk开发小结

来源:互联网 发布:服务器与域名的关系 编辑:程序博客网 时间:2024/06/05 03:23

从接触这个平台到现在已接近一年时间,之前很多时间虽然一直在这个平台做应用还有部分的驱动,但是一直没真正理解这个平台到底真正的优势和技术难点在哪里,其实也就是最近搞这个平台的SWMS时才有了更进一步的认识,从底层的硬件到上层的dvrrdk的学习,学习了这个四核视频协处理平台的软件框架。

一、下面我就从TI提供的DM81xx DVR_RDK Overview来引入一些概念:

介绍

DVR RDK是一个为ti816x,ti814x,ti810x平台设计的多处理器的软件开发框架,专门优化了多路视频主要应用在DVR, NVR, Hybrid-DVR, HD-DVR 。在DVR RDK软件框架允许用户创建不同的多路视频数据流包括:视频采集、视频处理(DEI、缩放、噪声滤波、软件拼接,SWMS, OSD,运动检测等),视频编码(H264,MJPEG)、视频解码(H264、MPEG4、mpjeg)和视频显示(HDMI,hddac,CVBS等)。

DVR RDK的用户接口或API叫做McFW(多通道框架)。软件本身是建立在一个称为“Links and chains”的多处理器框架。该框架优化的多通道视频,因而成千上万的视频帧需要在不同的视频处理任务交换的应用程序。这个框架的内部接口被称为““Link API”。

DVR RDK组件

DVR RDK关键部件的总结:


软件框架

软件组件分布在四个处理器之间去共享处理:

• VPSS M3 - is used for Video capture, display, scaling, de-interlacing
• Video M3 - is used H264, MPEG4, MJPEG encode/decode
• DSP - is used for additional SW based video processing and video analytics
• A8 - is used for system control, GUI, SATA, Ethernet, USB and other IO





编程接口



McFW API

这个接口将视频系统分为四个主要子系统:

视频采集、显示、编码、解码




Link API

(1)、link api的概念

link在上图中的视频数据流中是最基本的单元模块,每个link中包含了一个基于BIOS6/Linux的任务、线程、消息盒(使用操作系统的信号量实现)。由于每个link运行一个独立的现成,因此link之间可以并行运行。消息盒是关联用户指定的link,让link之间有个互相对话的机制,用来传递信令。而对于视频流数据、帧数据的传递link实现了专门的接口来实现,只传递指针,而不是数据。
在实现上节所介绍的数据流可以通过将多个link连接来实现chain,link API允许用户Create、Start、Stop、Delete、Control各个link。在Rdk中TI基于link API进行再次封装,用于特定的应用场合,其各种参数均是为特定的产品定制,可以是相关业务的开发更迅速。

(2)、link内部结构


(3)、link的特性

视频处理的工作量可以均衡到每个核心上去执行,如下表:


-每个link都有自己独立的任务/线程用于完成视频采集或播放等处理;
-每个link都可以处理来自多个通道的视频帧数据,每个通道的视频宽高和数据格式都可以不同;
-A8作为HOST可以用来连接多个link形成数据流的链并对其进行控制;
-数据链被建立并启动时,数据链中的每个link将和它的下游link进行帧数据的交互;
-links之间的帧数据交互可以在多个核心之间进行,并且并不需要A8 HOST的干涉,从而降低A8的开销;
-在数据链运行过程中用户可以发送控制信令给任意link来动态设置相关的link参数;

(4)、link接口

link接口可以分成以下几类:
-link API——被用户调用来配置和控制link的接口;
-Inter link API——被其他links调用来交换帧数据的接口;
-link output queue——被其他links通过Inter Link API接口实用的帧buffer队列;

(5)、link间的消息传递

每个Link通过一个32位的该LinkId来识别,ID高4位标识了这个Link是在哪个核上运行,低24位标识了该Link的名称:


每个Link API都需要这个LinkID参数来发送消息,当用户发送消息到一个Link时,根据这ID函数内部判断这个消息是发给本地的Link还是远端核心的Link;如果是本地的直接调用BIOS/LINUX API函数,否则就通过Syslink模块的MessageQ发送这个消息到指定的核心,让对端的核心调用对应的函数处理。

(6)、link API


(7)、Inter link API


在每个link中必须实现一些函数并在初始化时注册这些函数指针给link管理的核心模块,用于帧数据的获取、释放、dump相关状态等。
对于任一个link想从它的上游link获取帧数据都需要调用link管理核心函数System_getLinksFullFrames(),该函数内部会发送消息到对应的上游link,触发该link向管理模块注册的回调函数System_LinkGetOutputFramesCb()将帧数据传递给该link;
同样的,在当一个link想释放处理完毕的帧buffer给上游link时需要调用link管理核心函数System_putLinksEmptyFrames(),该函数内部会发送消息到对应的上游link,触发它注册的回调函数System_LinkPutEmptyFramesCb()将帧buffer回收,用于后续的数据处理;
建立chain时,你肯定还会关注一个信息,那就是上游link的相关参数如何传递给下游的link,从源程序仔细琢磨琢磨就可以看出来,和上面的处理类似,所有有下游link的link都会注册一个System_GetLinkInfoCb()的回调函数,在下游link的driver中会在创建driver时调用System_linkGetInfo()函数来获取上游link的相关参数。
通过上述的方法,对于一个link来说就不需要关心和它交互的是哪一个link,所有的寻址都通过linkID来自动查找,并且同一个link实现可以和不同的link交互,而不需要改变函数的实现。

(8)、Link Output Queues 的管理

一个Link可以有一个或多个输出队列用来存放采集到的或处理完毕的帧数据,每个Link的输出队列内存由自己分配;
大多数Links只有一个输出队列,但是有些link有多个,从而可以实现多路不同的输出数据流满足不同的应用需求,例如,Noise filter Link可以输出16路帧数据到2个输出队列,每个输出队列输出8路通道数据跟别给2个DEI Links模块处理。
一个输出队列中可以有多个视频channels的数据,每个channel可以有不同的大小和数据格式;
数据结构 FVID2_Frame是在VPSS驱动中定义的,Links之间就通过该结构参数传递帧数据的信息,如帧数据的Buf指针,而帧数据本身并不会被拷贝,从而节省内存开销;
当一个Link采集完或处理完一帧数据后会发送一个消息“SYSTEM_CMD_NEW_DATA”给下游的Link,从而通知它有数据可取;当下游Link收到该消息后会调用System_getLinksFullFrames()函数来获取对用的帧数据,处理完后再调用System_putLinksEmptyFrames()函数来归还给上游Link继续使用。
因此一个Link需要知道:
--上游Link的LinkID和QueID,从而从该队列里面获取帧数据
--下游LinkID,从而在有新数据产生时通知下游Link来取
上游Link的LinkID和QueID 以及下游LinkID 都是在System_linkCreate()时由A8 HOST端来指定的。

(9)、IPC link核间帧数据交互

IPC Link,是用来多核之间的帧数据传递的。
如VPSS上的采集Link想把帧数据发送给Video Link处理,先将帧数据传递给本地的IPC Link,然后IPC Link再通过Syslink/IPC发送到Video Link上的IPC Link,然后再转发给Video Link,这样的话对于采集Link的实现来说就非常清晰简单,它的实现都是发送给本地的另一个Link;
IPC Link的实现有点复杂,因为它涉及的帧数据传递是在多个核之间,这里面就牵扯到cache的一致性问题,考虑到每个核的特性以及高效性,总共设计了3个内部Links用于帧数据的传递机制:
Intra-processor links
即同一核心内部的link,如采集与降噪之间的帧数据传递,这种内部的link间传递帧数据都是在VPSS M3内部完成,因此采用简单且高效的队列机制实现。
Inter M3 (Video / VPSS) links
即M3内部核心之间的link,由于Video和Vpss所在的2个M3核心是同属于一个双核M3处理器,它们的cache是共享的;如降噪模块(VPSS NF)到编码模块(VIDEO Enc)之间传递帧数据,带有Notify的IPC ListMP机制被用来在这2个M3核心之间传递帧信息(FVID2_Frame),该过程中不需要任何cache操作和地址转换。
Inter processor (M3 to A8 or DSP)
即处理器内部核心之间,如编码(VideoM3)到BitStream In(HostA8)之间传递帧数据,同样使用带Notify的IPC ListMP机制在2个核心之间传递帧信息(FVID2_Frame),但该过程中需要做cache同步和地址转换操作。

(10)、chain数据链路的建立

一个Chain是由多个links按照一定的应用需求按顺序连接成一条视频处理的数据流。
一个Chain可以销毁后重新按照新的需求组成新的Chain,不需要重启系统。
Chain创建是特别需要相关link的顺序
-通过System_linkCreate()函数按照由source>>sink 的顺序创建需要的Links,Source Link即没有上游Link的Link,如:视频采集;Sink Link是没有下游Link的Link,如:视频播放;这个创建顺序是非常重要的,因为一个Link创建时它会查询上游Link的一些信息,如上游Link需要的channel的个数和属性,从而按照这些参数配置自己。
-下一步调用System_linkStart()函数启动每个Link,启动顺序一般从Sink Link往前到Sorce Link,当然你也可以不按照这个顺序,不过不推荐,因为这样可以保证每个Link在它的上游Link启动前准备好接收数据,避免过多的缓冲引入额外的时延。
-当一个Chain运行后控制命令就可以发送到各个Links来控制它,如调用System_linkControl()函数发送改变画面合成风格的命令给相应的Link,具体的命令定义由每个Link的功能实现来决定;
-注意:一般来说System_linkControl()函数是在System_linkCreate()创建了Link之后才能调用,不过有些控制命令可以在System_linkCreate()调用之前调用,以完成Link创建之前必须的一些初始化,如复位;
-当Chain工作完成或销毁时可以调用System_linkStop()函数先停止每个Link,注意:停止的顺序必须从Source开始依次到Sink结束;因为一个Link可能阻塞着等待下游Link释放当前Link的输出Buffer,如果下游Link先停止的话当前Link可能会出于wait for ever的状态而永久退不出来,因此上游Link必须先停止,之后才能停止下游Link;
-最后等所有Link全部停止后,可以调用System_linkDelete()函数删除所有Links,删除顺序没有要求;
-当Chain销毁后就可以按照之前的顺序重新创建一个新的Chain来完成另一个工作了。


关键术语




二、实例

基于rdk框架的一个四库输入两路输出的一个实例:

/******************************************************************************* *                                                                             * * Copyright (c) 2009 Texas Instruments Incorporated - http://www.ti.com/      * *                        ALL RIGHTS RESERVED                                  * *                                                                             * ******************************************************************************//* This usecase assumes that all 3 outputs - D1 <h.264> + CIF <h.264> + D1 <MJPEG> are enabled *//*------------------------------ D1 <h.264> + CIF <h.264> + D1 <MJPEG> -------------------------------------                  Capture (YUV422I) 4CH D1 60fps                              |                              |                              |                              |                              DEI                              |+------------------------------------------------------------------------                              |                                            |                           |                       (DEI-SC YUV422I)                              (VIP-SC YUV420 )            (VIP-SC1 YUV420 )                              D1                                        D1 |                        CIF|                              |                                            |                           |                              |                                            |                           |                              |                                            |                           |                        -----------------                                  |                           |                         D1_DUP_LINK_IDX                                   |                           |                        -----------------                                  |                           |                              |     |                                      |                           |                              |     |                                      |                           |                              |     |                                      |                           |                              |    NSF                                     |                           |                              |  (YUV420)                                  |                           |                              |     |                                      |                           |                              |     |                                      |          |-----------------                              |     |-----------------------------         |          |                              |                                  |         |          |                              |                      <D1-MJPEG> 2|         |0         | 1                              |                                  |         |<D1-H.264>| <CIF-H.264>                              |                                  |         |          |                              |                                  |         |          |                              |                            ---------------------------------                              |                                   D1_CIF_MERGE_LINK_IDX                              |                            ---------------------------------                              |                                            |                              |                                            |                              |                                            |                              |                                     FRAMESOUT(VPSS)---------------<<<processLink>>>----FramesInDSP--------ALG_LINK <OSD, SCD Algs>                              |                                            |                              |                                            |                              |                                            |                              |                                            |                              |                                       IPCM3OUT(VPSS)------IPCM3IN(VID)----ENC-----IPCBITS_RTOSOUT(VID)-----IPCBITS_HLOSIN(HOST)-----FILEOUT                              |                                                                                                                                  |                              |                                                                                                                                  |                              |                                                                                                                                  |                              |                                                                                                                                  |                              |+--------------------------IPCM3IN(VPSS)---------IPCM3OUT(VID)---------DEC---------------IPCBITS_RTOSIN(VID)-----------IPCBITS_HLOSOUT(HOST)                              |                              |                      LIVE_DECODE_MERGE_LINK_IDX                              |                              |                              |                        LIVE_DECODE_DUP_LINK_IDX                             |||                             |||                             |||             +---------------+|+----------------+             |                                  |             |                                  |          SW Mosaic 1                       SW Mosaic 0         (SC2 YUV422I)                     (SC5 YUV422I)             |                                  |             |                                  |             |                                  |             |                                  |             |                                  |             |                                  |       -------------                       -------------          DISPLAY 1                           DISPLAY 0       -------------                       -------------   <tied>          <SDTV>                          <On-Chip HDMI> --------- <Off-Chip HDMI>         PAL/NTSC                            1080p60                 1080p60*/#include "mcfw/src_linux/mcfw_api/usecases/multich_common.h"#include "mcfw/src_linux/mcfw_api/usecases/multich_ipcbits.h"// Keeping TILER disabled for 4D1 usecase#define TILER_ENABLE    FALSE/* ============================================================================= * Use case code * ============================================================================= */static SystemVideo_Ivahd2ChMap_Tbl systemVid_encDecIvaChMapTbl ={    .isPopulated = 1,    .ivaMap[0] =    {        .EncNumCh  = 16,        .EncChList = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 , 14, 15},        .DecNumCh  = 16,        .DecChList = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 , 14, 15},    },};// #define     ADD_NSF_AFTER_CAPTURE#define     NUM_MERGE_LINK                          2#define     D1_CIF_MERGE_LINK_IDX                  0#define     LIVE_DECODE_MERGE_LINK_IDX             1#define     NUM_DUP_LINK                            2#define     D1_DUP_LINK_IDX                         0#define     LIVE_DECODE_DUP_LINK_IDX                1#if(defined(TI_814X_BUILD) || defined(DDR_MEM_256M))#define     NUM_CAPTURE_BUFFERS          8#define     NUM_NSF_BUFFERS              4#define     NUM_ENCODE_D1_BUFFERS       4#define     NUM_ENCODE_CIF_BUFFERS       4#define     NUM_DECODE_BUFFERS           4#define     NUM_SWMS_MAX_BUFFERS         8#define     BIT_BUF_LENGTH_LIMIT_FACTOR_SD    4#else#define     NUM_CAPTURE_BUFFERS          8#define     NUM_NSF_BUFFERS              6#define     NUM_ENCODE_D1_BUFFERS       6#define     NUM_ENCODE_CIF_BUFFERS       6#define     NUM_DECODE_BUFFERS           6#define     NUM_SWMS_MAX_BUFFERS         8#define     BIT_BUF_LENGTH_LIMIT_FACTOR_SD    6#endif#define     MAX_BUFFERING_QUEUE_LEN_PER_CH    (50)#define     NUM_CAPTURE_DEVICES          1/* This usecase assumes CIF <secondary out>, MJPEG are enabled */Void MultiCh_createProgressive4D1VcapVencVdecVdis(){    CaptureLink_CreateParams    capturePrm;    NsfLink_CreateParams        nsfPrm;    DeiLink_CreateParams        deiPrm;    MergeLink_CreateParams      mergePrm[NUM_MERGE_LINK];    DupLink_CreateParams        dupPrm[NUM_DUP_LINK];    static SwMsLink_CreateParams       swMsPrm[VDIS_DEV_MAX];    DisplayLink_CreateParams    displayPrm[VDIS_DEV_MAX];    IpcLink_CreateParams        ipcOutVpssPrm;    IpcLink_CreateParams        ipcInVpssPrm;    IpcLink_CreateParams        ipcOutVideoPrm;    IpcLink_CreateParams        ipcInVideoPrm;    EncLink_CreateParams        encPrm;    DecLink_CreateParams        decPrm;    IpcBitsOutLinkHLOS_CreateParams   ipcBitsOutHostPrm;    IpcBitsOutLinkRTOS_CreateParams   ipcBitsOutVideoPrm;    IpcBitsInLinkHLOS_CreateParams    ipcBitsInHostPrm[2];    IpcBitsInLinkRTOS_CreateParams    ipcBitsInVideoPrm;    CaptureLink_VipInstParams         *pCaptureInstPrm;    CaptureLink_OutParams             *pCaptureOutPrm;    IpcFramesInLinkRTOS_CreateParams  ipcFramesInDspPrm;    IpcFramesOutLinkRTOS_CreateParams ipcFramesOutVpssPrm;    AlgLink_CreateParams              dspAlgPrm;    System_LinkInfo                   bitsProducerLinkInfo;    UInt32 mergeId[NUM_MERGE_LINK];    UInt32 dupId[NUM_DUP_LINK];    UInt32 ipcOutVpssId, ipcInVpssId;    UInt32 ipcOutVideoId, ipcInVideoId;    IpcBitsOutLinkRTOS_CreateParams   ipcBitsOutDspPrm;    VCAP_DEVICE_CREATE_PARAM_S        vidDecVideoModeArgs[NUM_CAPTURE_DEVICES];    UInt32 vipInstId;    UInt32 i, j;    Bool   enableAlgLink;    Bool   enableScd     = gVsysModuleContext.vsysConfig.enableScd;    Bool   enableOsd     = gVsysModuleContext.vsysConfig.enableOsd;    UInt32 chId; #ifdef     ADD_NSF_AFTER_CAPTURE    NsfLink_CreateParams        nsfPrm2;#endif    enableScd = TRUE;    enableAlgLink = FALSE;    if(enableOsd||enableScd)        enableAlgLink = TRUE;    MULTICH_INIT_STRUCT(IpcLink_CreateParams,ipcOutVpssPrm);    MULTICH_INIT_STRUCT(IpcLink_CreateParams,ipcInVpssPrm);    MULTICH_INIT_STRUCT(IpcLink_CreateParams,ipcOutVideoPrm);    MULTICH_INIT_STRUCT(IpcLink_CreateParams,ipcInVideoPrm);    MULTICH_INIT_STRUCT(IpcBitsOutLinkHLOS_CreateParams,ipcBitsOutHostPrm);    MULTICH_INIT_STRUCT(IpcBitsOutLinkRTOS_CreateParams,ipcBitsOutVideoPrm);    MULTICH_INIT_STRUCT(IpcBitsOutLinkRTOS_CreateParams,ipcBitsOutDspPrm);    MULTICH_INIT_STRUCT(IpcBitsInLinkHLOS_CreateParams,ipcBitsInHostPrm[0]);    MULTICH_INIT_STRUCT(IpcBitsInLinkHLOS_CreateParams,ipcBitsInHostPrm[1]);    MULTICH_INIT_STRUCT(IpcBitsInLinkRTOS_CreateParams,ipcBitsInVideoPrm);    MULTICH_INIT_STRUCT(DecLink_CreateParams, decPrm);    MULTICH_INIT_STRUCT(IpcFramesInLinkRTOS_CreateParams,ipcFramesInDspPrm);    MULTICH_INIT_STRUCT(IpcFramesOutLinkRTOS_CreateParams,ipcFramesOutVpssPrm);    MULTICH_INIT_STRUCT(EncLink_CreateParams, encPrm);    MULTICH_INIT_STRUCT(AlgLink_CreateParams, dspAlgPrm);    for (i = 0; i < VDIS_DEV_MAX;i++)    {        MULTICH_INIT_STRUCT(DisplayLink_CreateParams,                            displayPrm[i]);        MULTICH_INIT_STRUCT(SwMsLink_CreateParams ,swMsPrm[i]);    }    MULTICH_INIT_STRUCT(NsfLink_CreateParams, nsfPrm);    MULTICH_INIT_STRUCT(DeiLink_CreateParams, deiPrm);    printf("\n********* Entered usecase 4CH <814x> Enc/Dec OSD %s SCD %s \n\n",            enableOsd == TRUE ? "Enabled" : "Disabled",            enableScd == TRUE ? "Enabled" : "Disabled"            );    MultiCh_detectBoard();    System_linkControl(        SYSTEM_LINK_ID_M3VPSS,        SYSTEM_M3VPSS_CMD_RESET_VIDEO_DEVICES,        NULL,        0,        TRUE        );    System_linkControl(        SYSTEM_LINK_ID_M3VIDEO,        SYSTEM_COMMON_CMD_SET_CH2IVAHD_MAP_TBL,        &systemVid_encDecIvaChMapTbl,        sizeof(SystemVideo_Ivahd2ChMap_Tbl),        TRUE    );    vipInstId = 0;    gVcapModuleContext.captureId    = SYSTEM_LINK_ID_CAPTURE;    if(enableAlgLink)    {        gVcapModuleContext.dspAlgId[0] = SYSTEM_LINK_ID_VIDEO_ALG_0  ;    }    gVcapModuleContext.nsfId[0]     = SYSTEM_LINK_ID_NSF_0;#ifdef     ADD_NSF_AFTER_CAPTURE    gVcapModuleContext.nsfId[1]     =SYSTEM_LINK_ID_NSF_1;#endif    gVcapModuleContext.deiId[0]     = SYSTEM_LINK_ID_DEI_0;    gVencModuleContext.encId        = SYSTEM_LINK_ID_VENC_0;    gVdecModuleContext.decId        = SYSTEM_LINK_ID_VDEC_0;    gVdisModuleContext.swMsId[0]      = SYSTEM_LINK_ID_SW_MS_MULTI_INST_0;    gVdisModuleContext.swMsId[1]      = SYSTEM_LINK_ID_SW_MS_MULTI_INST_1;    swMsPrm[0].numSwMsInst = 1;    swMsPrm[1].numSwMsInst = 1;    /* use AUX scaler (SC2), since SC1 is used for DEI */    swMsPrm[0].swMsInstId[0] = SYSTEM_SW_MS_SC_INST_DEI_SC_NO_DEI;    swMsPrm[1].swMsInstId[0] = SYSTEM_SW_MS_SC_INST_SC5;    gVdisModuleContext.displayId[0] = SYSTEM_LINK_ID_DISPLAY_0; /* ON AND OFF CHIP HDMI */    gVdisModuleContext.displayId[1] = SYSTEM_LINK_ID_DISPLAY_2; /* SDTV */    mergeId[LIVE_DECODE_MERGE_LINK_IDX]     = SYSTEM_VPSS_LINK_ID_MERGE_0;    mergeId[D1_CIF_MERGE_LINK_IDX]          = SYSTEM_VPSS_LINK_ID_MERGE_1;    dupId[D1_DUP_LINK_IDX]              = SYSTEM_VPSS_LINK_ID_DUP_0;    dupId[LIVE_DECODE_DUP_LINK_IDX]     = SYSTEM_VPSS_LINK_ID_DUP_1;    ipcOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0;    ipcInVideoId = SYSTEM_VIDEO_LINK_ID_IPC_IN_M3_0;    ipcOutVideoId= SYSTEM_VIDEO_LINK_ID_IPC_OUT_M3_0;    ipcInVpssId  = SYSTEM_VPSS_LINK_ID_IPC_IN_M3_0;    gVencModuleContext.ipcBitsOutRTOSId  = SYSTEM_VIDEO_LINK_ID_IPC_BITS_OUT_0;    gVencModuleContext.ipcBitsInHLOSId   = SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0;    gVdecModuleContext.ipcBitsOutHLOSId  = SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0;    gVdecModuleContext.ipcBitsInRTOSId  = SYSTEM_VIDEO_LINK_ID_IPC_BITS_IN_0;    CaptureLink_CreateParams_Init(&capturePrm);#ifdef     ADD_NSF_AFTER_CAPTURE    capturePrm.outQueParams[0].nextLink   = gVcapModuleContext.nsfId[1];#else    capturePrm.outQueParams[0].nextLink   = gVcapModuleContext.deiId[0];#endif    capturePrm.numVipInst                 = 1;    capturePrm.tilerEnable                = FALSE;    capturePrm.numBufsPerCh               = NUM_CAPTURE_BUFFERS;    capturePrm.maxBlindAreasPerCh         = 4;    pCaptureInstPrm                     = &capturePrm.vipInst[0];    pCaptureInstPrm->vipInstId          = (SYSTEM_CAPTURE_INST_VIP0_PORTA+                                          vipInstId)%SYSTEM_CAPTURE_INST_MAX;    pCaptureInstPrm->videoDecoderId     = SYSTEM_DEVICE_VID_DEC_TVP5158_DRV;    pCaptureInstPrm->inDataFormat       = SYSTEM_DF_YUV422P;    pCaptureInstPrm->standard           = SYSTEM_STD_MUX_4CH_D1;    pCaptureInstPrm->numOutput          = 1;    pCaptureOutPrm                      = &pCaptureInstPrm->outParams[0];    pCaptureOutPrm->dataFormat          = SYSTEM_DF_YUV422I_YUYV;    pCaptureOutPrm->scEnable            = FALSE;    pCaptureOutPrm->scOutWidth          = 0;    pCaptureOutPrm->scOutHeight         = 0;    pCaptureOutPrm->outQueId            = 0;    for(i = 0; i < NUM_CAPTURE_DEVICES; i++)    {        vidDecVideoModeArgs[i].vipInstId        = SYSTEM_CAPTURE_INST_VIP0_PORTA+i;        vidDecVideoModeArgs[i].deviceId         = DEVICE_VID_DEC_TVP5158_DRV;        vidDecVideoModeArgs[i].numChInDevice    = 4;        vidDecVideoModeArgs[i].modeParams.videoIfMode        = DEVICE_CAPT_VIDEO_IF_MODE_8BIT;        vidDecVideoModeArgs[i].modeParams.videoDataFormat    = SYSTEM_DF_YUV422P;        vidDecVideoModeArgs[i].modeParams.standard           = SYSTEM_STD_MUX_4CH_D1;        vidDecVideoModeArgs[i].modeParams.videoCaptureMode   =                    DEVICE_CAPT_VIDEO_CAPTURE_MODE_MULTI_CH_PIXEL_MUX_EMBEDDED_SYNC;        vidDecVideoModeArgs[i].modeParams.videoSystem        =                                      DEVICE_VIDEO_DECODER_VIDEO_SYSTEM_AUTO_DETECT;        vidDecVideoModeArgs[i].modeParams.videoCropEnable    = FALSE;        vidDecVideoModeArgs[i].modeParams.videoAutoDetectTimeout = -1;    }    Vcap_configVideoDecoder(vidDecVideoModeArgs, NUM_CAPTURE_DEVICES);#ifdef     ADD_NSF_AFTER_CAPTURE    nsfPrm2.bypassNsf                          = TRUE;    nsfPrm2.tilerEnable                          = FALSE;    nsfPrm2.inQueParams.prevLinkId          = gVcapModuleContext.captureId;    nsfPrm2.inQueParams.prevLinkQueId     = 0;    nsfPrm2.numOutQue                        = 1;    nsfPrm2.outQueParams[0].nextLink      = gVcapModuleContext.deiId[0];    nsfPrm2.numBufsPerCh                     = NUM_NSF_BUFFERS;    nsfPrm2.inputFrameRate                    = 30;    nsfPrm2.outputFrameRate                  = 30;    deiPrm.inQueParams.prevLinkId = gVcapModuleContext.nsfId[1];#else    deiPrm.inQueParams.prevLinkId = gVcapModuleContext.captureId;#endif    deiPrm.inQueParams.prevLinkQueId  = 0;    /* Set Output Scaling at DEI based on ratio */    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_DEI_SC][0].scaleMode = DEI_SCALE_MODE_RATIO;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_DEI_SC][0].ratio.widthRatio.numerator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_DEI_SC][0].ratio.widthRatio.denominator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_DEI_SC][0].ratio.heightRatio.numerator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_DEI_SC][0].ratio.heightRatio.denominator = 1;    for (i=1; i < DEI_LINK_MAX_CH; i++)        deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_DEI_SC][i] = deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_DEI_SC][0];    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].scaleMode = DEI_SCALE_MODE_RATIO;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.heightRatio.numerator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.heightRatio.denominator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.widthRatio.numerator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0].ratio.widthRatio.denominator = 1;    for (i=1; i < DEI_LINK_MAX_CH; i++)        deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][i] = deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC][0];    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT][0].scaleMode = DEI_SCALE_MODE_RATIO;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT][0].ratio.heightRatio.numerator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT][0].ratio.heightRatio.denominator = 2;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT][0].ratio.widthRatio.numerator = 1;    deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT][0].ratio.widthRatio.denominator = 2;    for (i=1; i < DEI_LINK_MAX_CH; i++)        deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT][i] = deiPrm.outScaleFactor[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT][0];    deiPrm.enableOut[DEI_LINK_OUT_QUE_DEI_SC]                        = TRUE;    deiPrm.enableOut[DEI_LINK_OUT_QUE_VIP_SC]                        = TRUE;    deiPrm.enableOut[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT]          = TRUE;    deiPrm.outQueParams[DEI_LINK_OUT_QUE_DEI_SC].nextLink                   = dupId[D1_DUP_LINK_IDX];    deiPrm.outQueParams[DEI_LINK_OUT_QUE_VIP_SC].nextLink                   = mergeId[D1_CIF_MERGE_LINK_IDX];    deiPrm.outQueParams[DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT].nextLink     = mergeId[D1_CIF_MERGE_LINK_IDX];    deiPrm.tilerEnable[DEI_LINK_OUT_QUE_VIP_SC]          = TILER_ENABLE;    deiPrm.comprEnable                                   = FALSE;    deiPrm.setVipScYuv422Format                          = FALSE;    dupPrm[D1_DUP_LINK_IDX].inQueParams.prevLinkId         = gVcapModuleContext.deiId[0];    dupPrm[D1_DUP_LINK_IDX].inQueParams.prevLinkQueId      = DEI_LINK_OUT_QUE_DEI_SC;    dupPrm[D1_DUP_LINK_IDX].numOutQue                      = 2;    dupPrm[D1_DUP_LINK_IDX].outQueParams[0].nextLink       = mergeId[LIVE_DECODE_MERGE_LINK_IDX];    dupPrm[D1_DUP_LINK_IDX].outQueParams[1].nextLink       = gVcapModuleContext.nsfId[0];    dupPrm[D1_DUP_LINK_IDX].notifyNextLink                 = TRUE;    nsfPrm.bypassNsf                        = TRUE;    nsfPrm.tilerEnable                      = TILER_ENABLE;    nsfPrm.inQueParams.prevLinkId           = dupId[D1_DUP_LINK_IDX];    nsfPrm.inQueParams.prevLinkQueId        = 1;    nsfPrm.numOutQue                        = 1;    nsfPrm.outQueParams[0].nextLink         = mergeId[D1_CIF_MERGE_LINK_IDX];    nsfPrm.numBufsPerCh                     = NUM_NSF_BUFFERS;    nsfPrm.inputFrameRate = 30;    nsfPrm.outputFrameRate = 1;    /* Merge Q0 - D1 <from VIP-SC>, Q1 - CIF <from VIP-SC_SECONDARY>, Q2 -D1 for MJPEG <from DEI-SC>  */    mergePrm[D1_CIF_MERGE_LINK_IDX].inQueParams[0].prevLinkId       = gVcapModuleContext.deiId[0];    mergePrm[D1_CIF_MERGE_LINK_IDX].inQueParams[0].prevLinkQueId    = DEI_LINK_OUT_QUE_VIP_SC;    mergePrm[D1_CIF_MERGE_LINK_IDX].inQueParams[1].prevLinkId       = gVcapModuleContext.deiId[0];    mergePrm[D1_CIF_MERGE_LINK_IDX].inQueParams[1].prevLinkQueId    = DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT;    mergePrm[D1_CIF_MERGE_LINK_IDX].inQueParams[2].prevLinkId       = gVcapModuleContext.nsfId[0];    mergePrm[D1_CIF_MERGE_LINK_IDX].inQueParams[2].prevLinkQueId    = 0;    mergePrm[D1_CIF_MERGE_LINK_IDX].notifyNextLink                  = TRUE;    mergePrm[D1_CIF_MERGE_LINK_IDX].numInQue = 3;    ipcOutVpssPrm.inQueParams.prevLinkQueId    = 0;        mergePrm[D1_CIF_MERGE_LINK_IDX].outQueParams.nextLink  = ipcOutVpssId;        ipcOutVpssPrm.inQueParams.prevLinkId                   = mergeId[D1_CIF_MERGE_LINK_IDX];    ipcOutVpssPrm.numOutQue = 1;    ipcOutVpssPrm.outQueParams[0].nextLink     = ipcInVideoId;    ipcOutVpssPrm.notifyNextLink               = TRUE;    ipcOutVpssPrm.notifyPrevLink               = TRUE;    ipcOutVpssPrm.noNotifyMode                 = FALSE;    ipcInVideoPrm.inQueParams.prevLinkId       = ipcOutVpssId;    ipcInVideoPrm.inQueParams.prevLinkQueId    = 0;    ipcInVideoPrm.numOutQue                    = 1;    if (enableAlgLink)    {ipcInVideoPrm.outQueParams[0].nextLink     = gVcapModuleContext.dspAlgId[0];dspAlgPrm.inQueParams.prevLinkId           = ipcInVideoId;dspAlgPrm.inQueParams.prevLinkQueId        = 0;dspAlgPrm.outQueParams[ALG_LINK_FRAMES_OUT_QUE].nextLink = gVencModuleContext.encId;    }else {ipcInVideoPrm.outQueParams[0].nextLink     = gVencModuleContext.encId;}    ipcInVideoPrm.notifyNextLink               = TRUE;    ipcInVideoPrm.notifyPrevLink               = TRUE;    ipcInVideoPrm.noNotifyMode                 = FALSE;    {        EncLink_ChCreateParams *pLinkChPrm;        EncLink_ChDynamicParams *pLinkDynPrm;        VENC_CHN_DYNAMIC_PARAM_S *pDynPrm;        VENC_CHN_PARAMS_S *pChPrm;        EncLink_CreateParams_Init(&encPrm);        encPrm.numBufPerCh[0] = NUM_ENCODE_D1_BUFFERS;        encPrm.numBufPerCh[1] = NUM_ENCODE_CIF_BUFFERS;        /* Primary Stream Params - D1 */        for (i=0; i<gVencModuleContext.vencConfig.numPrimaryChn; i++)        {            pLinkChPrm  = &encPrm.chCreateParams[i];            pLinkDynPrm = &pLinkChPrm->defaultDynamicParams;            pChPrm      = &gVencModuleContext.vencConfig.encChannelParams[i];            pDynPrm     = &pChPrm->dynamicParam;            pLinkChPrm->format                  = IVIDEO_H264HP;            pLinkChPrm->profile                 = gVencModuleContext.vencConfig.h264Profile[i];            pLinkChPrm->dataLayout              = VCODEC_FIELD_SEPARATED;            pLinkChPrm->fieldMergeEncodeEnable  = FALSE;            pLinkChPrm->enableAnalyticinfo      = pChPrm->enableAnalyticinfo;            pLinkChPrm->enableWaterMarking      = pChPrm->enableWaterMarking;            pLinkChPrm->maxBitRate              = pChPrm->maxBitRate;            pLinkChPrm->encodingPreset          = pChPrm->encodingPreset;            pLinkChPrm->rateControlPreset       = pChPrm->rcType;            pLinkChPrm->enableSVCExtensionFlag  = pChPrm->enableSVCExtensionFlag;            pLinkChPrm->numTemporalLayer        = pChPrm->numTemporalLayer;            pLinkDynPrm->intraFrameInterval     = pDynPrm->intraFrameInterval;            pLinkDynPrm->targetBitRate          = pDynPrm->targetBitRate;            pLinkDynPrm->interFrameInterval     = 1;            pLinkDynPrm->mvAccuracy             = IVIDENC2_MOTIONVECTOR_QUARTERPEL;            pLinkDynPrm->inputFrameRate         = pDynPrm->inputFrameRate;            pLinkDynPrm->rcAlg                  = pDynPrm->rcAlg;            pLinkDynPrm->qpMin                  = pDynPrm->qpMin;            pLinkDynPrm->qpMax                  = pDynPrm->qpMax;            pLinkDynPrm->qpInit                 = pDynPrm->qpInit;            pLinkDynPrm->vbrDuration            = pDynPrm->vbrDuration;            pLinkDynPrm->vbrSensitivity         = pDynPrm->vbrSensitivity;        }        /* Secondary Out <CIF> Params */        for (i=gVencModuleContext.vencConfig.numPrimaryChn, j=VENC_PRIMARY_CHANNELS;              i<(gVencModuleContext.vencConfig.numPrimaryChn                       + gVencModuleContext.vencConfig.numSecondaryChn);                i++, j++)        {            pLinkChPrm  = &encPrm.chCreateParams[i];            pLinkDynPrm = &pLinkChPrm->defaultDynamicParams;            pChPrm      = &gVencModuleContext.vencConfig.encChannelParams[j];            pDynPrm     = &pChPrm->dynamicParam;            pLinkChPrm->format                  = IVIDEO_H264HP;            pLinkChPrm->profile                 = gVencModuleContext.vencConfig.h264Profile[i];            pLinkChPrm->dataLayout              = VCODEC_FIELD_SEPARATED;            pLinkChPrm->fieldMergeEncodeEnable  = FALSE;            pLinkChPrm->enableAnalyticinfo      = pChPrm->enableAnalyticinfo;            pLinkChPrm->enableWaterMarking      = pChPrm->enableWaterMarking;            pLinkChPrm->maxBitRate              = pChPrm->maxBitRate;            pLinkChPrm->encodingPreset          = pChPrm->encodingPreset;            pLinkChPrm->rateControlPreset       = pChPrm->rcType;            pLinkChPrm->enableSVCExtensionFlag  = pChPrm->enableSVCExtensionFlag;            pLinkChPrm->numTemporalLayer        = pChPrm->numTemporalLayer;            pLinkDynPrm->intraFrameInterval     = pDynPrm->intraFrameInterval;            pLinkDynPrm->targetBitRate          = pDynPrm->targetBitRate;            pLinkDynPrm->interFrameInterval     = 1;            pLinkDynPrm->mvAccuracy             = IVIDENC2_MOTIONVECTOR_QUARTERPEL;            pLinkDynPrm->inputFrameRate         = pDynPrm->inputFrameRate;            pLinkDynPrm->qpMin                  = pDynPrm->qpMin;            pLinkDynPrm->qpMax                  = pDynPrm->qpMax;            pLinkDynPrm->qpInit                 = pDynPrm->qpInit;            pLinkDynPrm->vbrDuration            = pDynPrm->vbrDuration;            pLinkDynPrm->vbrSensitivity         = pDynPrm->vbrSensitivity;        }        /* MJPEG  Params */        for (i=gVencModuleContext.vencConfig.numPrimaryChn + gVencModuleContext.vencConfig.numSecondaryChn;                  i<(VENC_CHN_MAX); i++)        {             pLinkChPrm  = &encPrm.chCreateParams[i];             pLinkDynPrm = &pLinkChPrm->defaultDynamicParams;             pChPrm      = &gVencModuleContext.vencConfig.encChannelParams[i];             pDynPrm     = &pChPrm->dynamicParam;             pLinkChPrm->format                 = IVIDEO_MJPEG;             pLinkChPrm->profile                = 0;             pLinkChPrm->dataLayout             = VCODEC_FIELD_SEPARATED;             pLinkChPrm->fieldMergeEncodeEnable = FALSE;             pLinkChPrm->enableAnalyticinfo     = 0;             pLinkChPrm->enableWaterMarking     = 0;             pLinkChPrm->maxBitRate             = 0;             pLinkChPrm->encodingPreset         = 0;             pLinkChPrm->rateControlPreset      = 0;             pLinkChPrm->enableSVCExtensionFlag = 0;             pLinkChPrm->numTemporalLayer       = 0;             pLinkDynPrm->intraFrameInterval    = 0;             pLinkDynPrm->targetBitRate         = 100*1000;             pLinkDynPrm->interFrameInterval    = 0;             pLinkDynPrm->mvAccuracy            = 0;             pLinkDynPrm->inputFrameRate        = pDynPrm->inputFrameRate;             pLinkDynPrm->qpMin                 = 0;             pLinkDynPrm->qpMax                 = 0;             pLinkDynPrm->qpInit                = -1;             pLinkDynPrm->vbrDuration           = 0;             pLinkDynPrm->vbrSensitivity        = 0;        }    if (enableAlgLink)    {encPrm.inQueParams.prevLinkId    = gVcapModuleContext.dspAlgId[0];encPrm.inQueParams.prevLinkQueId = ALG_LINK_FRAMES_OUT_QUE;    }else {encPrm.inQueParams.prevLinkId    = ipcInVideoId;encPrm.inQueParams.prevLinkQueId = 0;}        encPrm.outQueParams.nextLink     = gVencModuleContext.ipcBitsOutRTOSId;    }    ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkId = gVencModuleContext.encId;    ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkQueId = 0;    ipcBitsOutVideoPrm.baseCreateParams.numOutQue                 = 1;    ipcBitsOutVideoPrm.baseCreateParams.outQueParams[0].nextLink = gVencModuleContext.ipcBitsInHLOSId;    MultiCh_ipcBitsInitCreateParams_BitsOutRTOS(&ipcBitsOutVideoPrm,                                               TRUE);    ipcBitsInHostPrm[0].baseCreateParams.inQueParams.prevLinkId = gVencModuleContext.ipcBitsOutRTOSId;    ipcBitsInHostPrm[0].baseCreateParams.inQueParams.prevLinkQueId = 0;    MultiCh_ipcBitsInitCreateParams_BitsInHLOS(&ipcBitsInHostPrm[0]);    dspAlgPrm.enableOSDAlg = enableOsd;    if(enableOsd)    {        int chId;        for(chId = 0; chId < ALG_LINK_OSD_MAX_CH; chId++)        {            AlgLink_OsdChWinParams * chWinPrm = &dspAlgPrm.osdChCreateParams[chId].chDefaultParams;            /* set osd window max width and height */            dspAlgPrm.osdChCreateParams[chId].maxWidth  = EXAMPLE_OSD_WIN_MAX_WIDTH;            dspAlgPrm.osdChCreateParams[chId].maxHeight = EXAMPLE_OSD_WIN_MAX_HEIGHT;            chWinPrm->chId = chId;            chWinPrm->numWindows = 0;        }    }    dspAlgPrm.enableSCDAlg              = enableScd;    dspAlgPrm.outQueParams[ALG_LINK_SCD_OUT_QUE].nextLink     = SYSTEM_LINK_ID_INVALID;    if (enableScd)    {        UInt32 i, startChId;        AlgLink_ScdCreateParams *pScdCreatePrm;        AlgLink_ScdChParams *pScdChPrm;        pScdCreatePrm = &dspAlgPrm.scdCreateParams;        pScdCreatePrm->maxWidth               = 352;        pScdCreatePrm->maxHeight              = 288;        pScdCreatePrm->maxStride              = 352;        pScdCreatePrm->numValidChForSCD       = 4;        pScdCreatePrm->numSecs2WaitB4Init     = 3;        pScdCreatePrm->numSecs2WaitB4FrmAlert = 1;        pScdCreatePrm->inputFrameRate         = 30;        pScdCreatePrm->outputFrameRate        = 5;        pScdCreatePrm->numSecs2WaitAfterFrmAlert = 1;        pScdCreatePrm->enableTamperNotify = FALSE;        /* enable SCD only for CIF CHs */        startChId = 4;        for(i=0; i<pScdCreatePrm->numValidChForSCD; i++)        {            pScdChPrm = &pScdCreatePrm->chDefaultParams[i];            pScdChPrm->chId = startChId;            pScdChPrm->mode                = ALG_LINK_SCD_DETECTMODE_MONITOR_FULL_FRAME;            pScdChPrm->frmIgnoreLightsON   = FALSE;            pScdChPrm->frmIgnoreLightsOFF  = FALSE;            pScdChPrm->frmSensitivity      = ALG_LINK_SCD_SENSITIVITY_VERYHIGH;            pScdChPrm->frmEdgeThreshold    = 0;            pScdChPrm->blkNumBlksInFrame   = 0;            startChId++;        }    }    capturePrm.isPalMode = Vcap_isPalMode();    System_linkCreate (gVcapModuleContext.captureId, &capturePrm, sizeof(capturePrm));#ifdef     ADD_NSF_AFTER_CAPTURE    System_linkCreate(gVcapModuleContext.nsfId[1], &nsfPrm2, sizeof(nsfPrm2));#endif    System_linkCreate(gVcapModuleContext.deiId[0], &deiPrm, sizeof(deiPrm));    System_linkCreate(dupId[D1_DUP_LINK_IDX], &dupPrm[D1_DUP_LINK_IDX], sizeof(dupPrm[D1_DUP_LINK_IDX]));    System_linkCreate(gVcapModuleContext.nsfId[0] , &nsfPrm, sizeof(nsfPrm));    System_linkCreate(mergeId[D1_CIF_MERGE_LINK_IDX], &mergePrm[D1_CIF_MERGE_LINK_IDX], sizeof(mergePrm[D1_CIF_MERGE_LINK_IDX]));    System_linkCreate(ipcOutVpssId , &ipcOutVpssPrm , sizeof(ipcOutVpssPrm) );    System_linkCreate(ipcInVideoId , &ipcInVideoPrm , sizeof(ipcInVideoPrm) );    if(enableAlgLink)    {        /* only create OSD alg */        System_linkCreate(gVcapModuleContext.dspAlgId[0] , &dspAlgPrm, sizeof(dspAlgPrm));    }    System_linkCreate(gVencModuleContext.encId, &encPrm, sizeof(encPrm));    System_linkCreate(gVencModuleContext.ipcBitsOutRTOSId, &ipcBitsOutVideoPrm, sizeof(ipcBitsOutVideoPrm));    System_linkCreate(gVencModuleContext.ipcBitsInHLOSId, &ipcBitsInHostPrm[0], sizeof(ipcBitsInHostPrm[0]));    System_linkGetInfo(gVencModuleContext.ipcBitsInHLOSId,&bitsProducerLinkInfo);    OSA_assert(bitsProducerLinkInfo.numQue == 1);    ipcBitsOutHostPrm.baseCreateParams.outQueParams[0].nextLink = gVdecModuleContext.ipcBitsInRTOSId;    printf ("\n\n========bitsProducerLinkInfo============\n");    printf ("numQ %d, numCh %d\n",                    bitsProducerLinkInfo.numQue,                    bitsProducerLinkInfo.queInfo[0].numCh);    {        int i;        for (i=0; i<bitsProducerLinkInfo.queInfo[0].numCh; i++)        {            printf ("Ch [%d] Width %d, Height %d\n",                i,                bitsProducerLinkInfo.queInfo[0].chInfo[i].width,                bitsProducerLinkInfo.queInfo[0].chInfo[i].height                );        }    }    printf ("\n====================\n\n");    if (bitsProducerLinkInfo.queInfo[0].numCh > gVencModuleContext.vencConfig.numPrimaryChn)        bitsProducerLinkInfo.queInfo[0].numCh = gVencModuleContext.vencConfig.numPrimaryChn;    printf ("Reducing bitsProducerLinkInfo.numCh to %d\n", bitsProducerLinkInfo.queInfo[0].numCh);    MultiCh_ipcBitsInitCreateParams_BitsOutHLOS(&ipcBitsOutHostPrm,                                               &bitsProducerLinkInfo.queInfo[0]);    if(gVdecModuleContext.vdecConfig.forceUseDecChannelParams)    {        /* use channel info provided by user instead of from encoder */        System_LinkChInfo *pChInfo;        ipcBitsOutHostPrm.inQueInfo.numCh = gVdecModuleContext.vdecConfig.numChn;        for(chId=0; chId<ipcBitsOutHostPrm.inQueInfo.numCh; chId++)        {            pChInfo = &ipcBitsOutHostPrm.inQueInfo.chInfo[chId];            /* Not Used - Start */            pChInfo->bufType        = 0;            pChInfo->codingformat   = 0;            pChInfo->dataFormat     = 0;            pChInfo->memType        = 0;            pChInfo->startX         = 0;            pChInfo->startY         = 0;            pChInfo->pitch[0]       = 0;            pChInfo->pitch[1]       = 0;            pChInfo->pitch[2]       = 0;            /* Not Used - End */            pChInfo->width          = gVdecModuleContext.vdecConfig.decChannelParams[chId].maxVideoWidth;            pChInfo->height         = gVdecModuleContext.vdecConfig.decChannelParams[chId].maxVideoHeight;            pChInfo->scanFormat     = SYSTEM_SF_PROGRESSIVE;        }    }    /* ipcBitsOut params - num of buffers, bitstream buffer size */    for (chId=0; chId<ipcBitsOutHostPrm.inQueInfo.numCh; chId++)    {        ipcBitsOutHostPrm.maxQueueDepth[chId] = MAX_BUFFERING_QUEUE_LEN_PER_CH    ;        ipcBitsOutHostPrm.chMaxReqBufSize[chId] = IPC_BITBUF_SIZE(                                        ipcBitsOutHostPrm.inQueInfo.chInfo[chId].width,                                        ipcBitsOutHostPrm.inQueInfo.chInfo[chId].height                                         );        ipcBitsOutHostPrm.totalBitStreamBufferSize [chId] =                (ipcBitsOutHostPrm.chMaxReqBufSize[chId] * BIT_BUF_LENGTH_LIMIT_FACTOR_SD );    }    ipcBitsInVideoPrm.baseCreateParams.inQueParams.prevLinkId       = gVdecModuleContext.ipcBitsOutHLOSId;    ipcBitsInVideoPrm.baseCreateParams.inQueParams.prevLinkQueId    = 0;    ipcBitsInVideoPrm.baseCreateParams.numOutQue                    = 1;    ipcBitsInVideoPrm.baseCreateParams.outQueParams[0].nextLink     = gVdecModuleContext.decId;    MultiCh_ipcBitsInitCreateParams_BitsInRTOS(&ipcBitsInVideoPrm, TRUE);    for (i=0; i<gVdecModuleContext.vdecConfig.numChn; i++) {        decPrm.chCreateParams[i].format                 = IVIDEO_H264HP;        decPrm.chCreateParams[i].profile                = IH264VDEC_PROFILE_ANY;        decPrm.chCreateParams[i].processCallLevel       = VDEC_FRAMELEVELPROCESSCALL;        decPrm.chCreateParams[i].targetMaxWidth         = ipcBitsOutHostPrm.inQueInfo.chInfo[i].width;        decPrm.chCreateParams[i].targetMaxHeight        = ipcBitsOutHostPrm.inQueInfo.chInfo[i].height;        decPrm.chCreateParams[i].defaultDynamicParams.targetFrameRate = gVdecModuleContext.vdecConfig.decChannelParams[i].dynamicParam.frameRate;        decPrm.chCreateParams[i].defaultDynamicParams.targetBitRate   = gVdecModuleContext.vdecConfig.decChannelParams[i].dynamicParam.targetBitRate;        /* Max ref frames is only 2 as this is closed loop decoder */        decPrm.chCreateParams[i].dpbBufSizeInFrames                   = 2;        decPrm.chCreateParams[i].numBufPerCh = NUM_DECODE_BUFFERS;        decPrm.chCreateParams[i].tilerEnable = TILER_ENABLE;        decPrm.chCreateParams[i].enableWaterMarking = gVdecModuleContext.vdecConfig.decChannelParams[i].enableWaterMarking;    }    decPrm.inQueParams.prevLinkId    = gVdecModuleContext.ipcBitsInRTOSId;    decPrm.inQueParams.prevLinkQueId = 0;    decPrm.outQueParams.nextLink  = ipcOutVideoId;    ipcOutVideoPrm.inQueParams.prevLinkId    = gVdecModuleContext.decId;    ipcOutVideoPrm.inQueParams.prevLinkQueId = 0;    ipcOutVideoPrm.numOutQue                 = 1;    ipcOutVideoPrm.outQueParams[0].nextLink  = ipcInVpssId;    ipcOutVideoPrm.notifyNextLink            = TRUE;    ipcOutVideoPrm.notifyPrevLink            = TRUE;    ipcOutVideoPrm.noNotifyMode              = FALSE;    ipcInVpssPrm.inQueParams.prevLinkId    = ipcOutVideoId;    ipcInVpssPrm.inQueParams.prevLinkQueId = 0;    ipcInVpssPrm.numOutQue                 = 1;    ipcInVpssPrm.outQueParams[0].nextLink  = mergeId[LIVE_DECODE_MERGE_LINK_IDX];    ipcInVpssPrm.notifyNextLink            = TRUE;    ipcInVpssPrm.notifyPrevLink            = TRUE;    ipcInVpssPrm.noNotifyMode              = FALSE;    mergePrm[LIVE_DECODE_MERGE_LINK_IDX].numInQue                     = 2;    mergePrm[LIVE_DECODE_MERGE_LINK_IDX].inQueParams[0].prevLinkId    = dupId[D1_DUP_LINK_IDX];    mergePrm[LIVE_DECODE_MERGE_LINK_IDX].inQueParams[0].prevLinkQueId = 0;    mergePrm[LIVE_DECODE_MERGE_LINK_IDX].inQueParams[1].prevLinkId    = ipcInVpssId;    mergePrm[LIVE_DECODE_MERGE_LINK_IDX].inQueParams[1].prevLinkQueId = 0;    mergePrm[LIVE_DECODE_MERGE_LINK_IDX].outQueParams.nextLink        = dupId[LIVE_DECODE_DUP_LINK_IDX];    mergePrm[LIVE_DECODE_MERGE_LINK_IDX].notifyNextLink               = TRUE;    dupPrm[LIVE_DECODE_DUP_LINK_IDX].inQueParams.prevLinkId         = mergeId[LIVE_DECODE_MERGE_LINK_IDX];    dupPrm[LIVE_DECODE_DUP_LINK_IDX].inQueParams.prevLinkQueId      = 0;    dupPrm[LIVE_DECODE_DUP_LINK_IDX].numOutQue                      = 2;    dupPrm[LIVE_DECODE_DUP_LINK_IDX].outQueParams[0].nextLink       = gVdisModuleContext.swMsId[0];    dupPrm[LIVE_DECODE_DUP_LINK_IDX].outQueParams[1].nextLink       = gVdisModuleContext.swMsId[1];    dupPrm[LIVE_DECODE_DUP_LINK_IDX].notifyNextLink                 = TRUE;    for(i=0; i<2; i++)    {        swMsPrm[i].includeVipScInDrvPath     = FALSE;        swMsPrm[i].inQueParams.prevLinkId    = dupId[LIVE_DECODE_DUP_LINK_IDX];        swMsPrm[i].inQueParams.prevLinkQueId = i;        swMsPrm[i].outQueParams.nextLink     = gVdisModuleContext.displayId[i];        swMsPrm[i].maxInputQueLen            = 4; // KC: changed to 4 to make the display smooth        swMsPrm[i].maxOutRes                 = VSYS_STD_1080P_60;        swMsPrm[i].initOutRes                = gVdisModuleContext.vdisConfig.deviceParams[i].resolution;        swMsPrm[i].numOutBuf                 = 8;        if (i == 1){            swMsPrm[i].maxOutRes  = VSYS_STD_PAL;            swMsPrm[i].initOutRes = gVdisModuleContext.vdisConfig.deviceParams[VDIS_DEV_SD].resolution;}#ifdef  SYSTEM_USE_TILER        swMsPrm[i].lineSkipMode = FALSE; // Double pitch not possible in tiler mode; so Line skip not possible#else        swMsPrm[i].lineSkipMode = TRUE; // Set to TRUE for Enable low cost scaling#endif        swMsPrm[i].enableLayoutGridDraw = gVdisModuleContext.vdisConfig.enableLayoutGridDraw;        MultiCh_swMsGetDefaultLayoutPrm(VDIS_DEV_HDMI, &swMsPrm[0], TRUE);        MultiCh_swMsGetDefaultLayoutPrm(VDIS_DEV_SD, &swMsPrm[1], TRUE);        displayPrm[i].inQueParams[0].prevLinkId    = gVdisModuleContext.swMsId[i];        displayPrm[i].inQueParams[0].prevLinkQueId = 0;        displayPrm[i].displayRes                = swMsPrm[i].initOutRes;        if (i == 1)        {            displayPrm[i].displayRes            = gVdisModuleContext.vdisConfig.deviceParams[VDIS_DEV_SD].resolution;            displayPrm[i].forceFieldSeparatedInputMode = TRUE;        }    }    System_linkCreate(gVdecModuleContext.ipcBitsOutHLOSId,&ipcBitsOutHostPrm,sizeof(ipcBitsOutHostPrm));    System_linkCreate(gVdecModuleContext.ipcBitsInRTOSId,&ipcBitsInVideoPrm,sizeof(ipcBitsInVideoPrm));    System_linkCreate(gVdecModuleContext.decId, &decPrm, sizeof(decPrm));    System_linkCreate(ipcOutVideoId, &ipcOutVideoPrm, sizeof(ipcOutVideoPrm));    System_linkCreate(ipcInVpssId  , &ipcInVpssPrm  , sizeof(ipcInVpssPrm)  );    System_linkCreate(mergeId[LIVE_DECODE_MERGE_LINK_IDX], &mergePrm[LIVE_DECODE_MERGE_LINK_IDX], sizeof(mergePrm[LIVE_DECODE_MERGE_LINK_IDX]));    System_linkCreate(dupId[LIVE_DECODE_DUP_LINK_IDX], &dupPrm[LIVE_DECODE_DUP_LINK_IDX], sizeof(dupPrm[LIVE_DECODE_DUP_LINK_IDX]));    for(i=0; i<2; i++)        System_linkCreate(gVdisModuleContext.swMsId[i]  , &swMsPrm[i], sizeof(swMsPrm[i]));    for(i=0; i<2; i++)  /* Both tied VENCs HDMI and DVO2 are handled by single link instance */        System_linkCreate(gVdisModuleContext.displayId[i], &displayPrm[i], sizeof(displayPrm[i]));    {        MergeLink_InLinkChInfo inChInfo;        MergeLink_InLinkChInfo_Init(&inChInfo);        inChInfo.inLinkID = ipcInVpssId;        System_linkControl(mergeId[LIVE_DECODE_MERGE_LINK_IDX],                           MERGE_LINK_CMD_GET_INPUT_LINK_CHINFO,                           &inChInfo,                           sizeof(inChInfo),                           TRUE);        OSA_assert(inChInfo.numCh == gVdecModuleContext.vdecConfig.numChn);        MultiCh_setDec2DispMap(VDIS_DEV_HDMI,gVdecModuleContext.vdecConfig.numChn,0,inChInfo.startChNum);        MultiCh_setDec2DispMap(VDIS_DEV_SD,gVdecModuleContext.vdecConfig.numChn,0,inChInfo.startChNum);   }}Void MultiCh_deleteProgressive4D1VcapVencVdecVdis(){    UInt32 i;    Bool enableAlgLink = gVsysModuleContext.vsysConfig.enableOsd;    UInt32 mergeId[NUM_MERGE_LINK];    UInt32 dupId[NUM_DUP_LINK];    UInt32 ipcOutVpssId, ipcInVpssId;    UInt32 ipcOutVideoId, ipcInVideoId;    mergeId[LIVE_DECODE_MERGE_LINK_IDX]     = SYSTEM_VPSS_LINK_ID_MERGE_0;    mergeId[D1_CIF_MERGE_LINK_IDX]          = SYSTEM_VPSS_LINK_ID_MERGE_1;    dupId[D1_DUP_LINK_IDX]              = SYSTEM_VPSS_LINK_ID_DUP_0;    dupId[LIVE_DECODE_DUP_LINK_IDX]     = SYSTEM_VPSS_LINK_ID_DUP_1;    ipcOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0;    ipcInVideoId = SYSTEM_VIDEO_LINK_ID_IPC_IN_M3_0;    ipcOutVideoId= SYSTEM_VIDEO_LINK_ID_IPC_OUT_M3_0;    ipcInVpssId  = SYSTEM_VPSS_LINK_ID_IPC_IN_M3_0;    gVdecModuleContext.ipcBitsOutHLOSId = SYSTEM_HOST_LINK_ID_IPC_BITS_OUT_0;    gVdecModuleContext.ipcBitsInRTOSId = SYSTEM_VIDEO_LINK_ID_IPC_BITS_IN_0;    System_linkDelete(gVcapModuleContext.captureId);#ifdef     ADD_NSF_AFTER_CAPTURE    System_linkDelete(gVcapModuleContext.nsfId[1]);#endif    System_linkDelete(gVcapModuleContext.deiId[0]);    System_linkDelete(gVcapModuleContext.nsfId[0]);    System_linkDelete(ipcOutVpssId );    System_linkDelete(ipcInVideoId );    if(enableAlgLink)    {        System_linkDelete(gVcapModuleContext.dspAlgId[0]);    }    System_linkDelete(gVencModuleContext.encId);    System_linkDelete(gVencModuleContext.ipcBitsOutRTOSId);    System_linkDelete(gVencModuleContext.ipcBitsInHLOSId);    System_linkDelete(gVdecModuleContext.ipcBitsOutHLOSId);    System_linkDelete(gVdecModuleContext.ipcBitsInRTOSId);    System_linkDelete(gVdecModuleContext.decId);    System_linkDelete(ipcOutVideoId);    System_linkDelete(ipcInVpssId  );    for(i=0; i<2; i++)        System_linkDelete(gVdisModuleContext.swMsId[i] );    for(i=0; i<2; i++)        System_linkDelete(gVdisModuleContext.displayId[i]);    for(i=0; i<NUM_DUP_LINK; i++)        System_linkDelete(dupId[i]);    for(i=0; i<NUM_MERGE_LINK; i++)    {        if (mergeId[i] != SYSTEM_LINK_ID_INVALID )           System_linkDelete(mergeId[i]);    }    /* Print the HWI, SWI and all tasks load */    /* Reset the accumulated timer ticks */    MultiCh_prfLoadCalcEnable(FALSE, TRUE, FALSE);}


三、总结

我这次主要做了标清的swms,所以主要做的也就是对link的一些修改,结合本文其实主要是两个方面mcfw api和link api,mcfw我仅仅是结合 TI给的文档简单说了一下他的大致框架,并没有深入每个code去讲解,而link我是结合一位大神发表的博客:http://blog.csdn.net/crushonme/article/details/10245169

他的博客说的很详细,基本上link的语句都分析了一下,在此我只是借用自己来学习,谢谢!

其实link就是对几个核怎么运作进行设计,凡是用这个平台的link没有太大的区别,都是按照自己的需求进行定制,单是修改link也会很费工夫。

1 0