/** ==================================================================
 *  @file   multich_spectronix_stream.c
 *
 *  @path    ipnc_mcfw/mcfw/src_linux/mcfw_api/usecases/
 *
 *  @desc   This  File contains.
 * ===================================================================
 *  Copyright (c) Texas Instruments Inc 2011, 2012
 *
 *  Use of this software is controlled by the terms and conditions found
 *  in the license agreement under which this software has been supplied
 * ===================================================================*/

/*------------------------------ TRIPLE OUT <1200x1200 + D1> ---------------------------

                                 SENSOR (1200x1200)
                                ________||_______
            					|                |
                                |   CAMERA LINK  |
                                |    (VPSS M3)   |
                                |________________|
	          	  	  	  	  	   |           |
                  				   |           |
                                    WDR ON (for AR0331)
                                   |           |
                  	 	 	      RSZA        RSZB
					(1856x1504, 1200x1200)  (720x480)
                              (420SP/422I)  (420SP)
                                   |           |
   				   -----------------           |
                   | 		                   |
                   |                           |
	  	  	 ISS_NF(VPSSM3)                    |
 	   	   	   	   |                           |
   	   	   	   	   |                           |
 	   	   	   	   |     (1)                   |
 	   	   	   	  DUP_VA-----------------------|------------------------|
 	   	   	   	   |                           |                        |
 	   	   	   	   |(0)                        |             IPC FRAMES OUT (VPSSM3)
 	   	   	   	   |                           |                        |
 	   	   	   	   |      |--------------------|          ______________|___________________
 	   	   	   	   |      |                              |      IPC FRAMES IN (DSP)        |
 	   	   	   	  MUX(VPSSM3)                            |              |                  |
 	   	   	   	   |                                     | SPXVA-SPECTRONIX VIDEO ANALYTICS|
 	   	   	   	  SWOSD(VPSSM3)                          |_________________________________|
 	   	   	   	   |
 	   	   	   	   |
 	   	   	   	   |
                   |
		 DUP_SCLR(VPSSM3) ----- MUX_DISP(VPSSM3)---------DISPLAY_SD(VPSSM3)
                   |(0)                  (1)                   (720x480 � Analog)
 	               |
                   |
             IPC OUT(VPSSM3)
                   |
             IPC IN(VIDEOM3)
                   |
              ENC(VIDEOM3)
                   |
           IPC BITS OUT(VIDEOM3)
                   |
             IPC BITS IN(A8)
                   |
        ************************
        * HTTP, RTSP STREAMING *
        ************************

------------------------------------------------------------------------------------------*/
//#include <sys/types.h>
//#include <sys/shm.h>
//#include <fcntl.h>
//#include <errno.h>

#include "mcfw/src_linux/mcfw_api/usecases/multich_common.h"
#include "mcfw/src_linux/mcfw_api/usecases/multich_ipcbits.h"
#include "mcfw/interfaces/spec_ipc_defs.h"
#include "demos/mcfw_api_demos/multich_usecase/ti_mcfw_ipnc_main.h"

#define YUV_M2M_DRV_TEST //reduce memory consumption


 #define VIDEO_FRAME_SIZE_WIDTH 	SPXVA_FRAME_WIDTH
 #define VIDEO_FRAME_SIZE_HEIGHT	SPXVA_FRAME_HEIGHT
 #define VS_W    VIDEO_FRAME_SIZE_WIDTH
 #define VS_H    VIDEO_FRAME_SIZE_HEIGHT

UInt32 gNoiseFilterMode;

/* =============================================================================
 * Externs
 * ============================================================================= */


/* =============================================================================
 * Use case code
 * ============================================================================= */
static SystemVideo_Ivahd2ChMap_Tbl systemVid_encDecIvaChMapTbl = {
    .isPopulated = 1,
    .ivaMap[0] = {
                  .EncNumCh = 2,
                  .EncChList = {0, 1},
                  .DecNumCh = 2,
                  .DecChList = {0, 1},
                  },

};

#define TILER_ENABLE    FALSE

/* Merge Link for camera streams */
#define NUM_MERGE_LINK                  (1)
#define CAM_STREAM_MERGE_IDX            (0)

#define NTSC_SC_OUT_HEIGHT 480
#define PAL_SC_OUT_HEIGHT  576

/* ===================================================================
 *  @func     MultiCh_createSpectronixStream
 *
 *  @desc     Create all streams and links for spectronix use case
 *
 *  @modif    This function modifies the following structures
 *
 *  @inputs   This function takes the following inputs
 *            None
 *
 *  @outputs  All link structures
 *
 *  @return   None
 *  ==================================================================
 */
Void MultiCh_createSpectronixStream()
{
    UInt32 i, ntsc_pal_standard;
    CameraLink_CreateParams cameraPrm;
    IspLink_CreateParams    ispPrm;
    VnfLink_CreateParams    vnfPrm;

    MuxLink_CreateParams muxPrm;     // 2 queues enter with 1 channel, outputs 1 queue wih 2 channels
    IpcLink_CreateParams ipcOutVpssPrm;
    IpcLink_CreateParams ipcInVideoPrm;
    EncLink_CreateParams encPrm;
    DupLink_CreateParams dupPrm[NUM_DUP_LINK];
    DisplayLink_CreateParams displayPrm_SD;
    SwosdLink_CreateParams swosdPrm;
    IpcBitsOutLinkRTOS_CreateParams ipcBitsOutVideoPrm;
    IpcBitsInLinkHLOS_CreateParams ipcBitsInHostPrm0;
    VstabLink_CreateParams vstabPrm;
    GlbceSupportLink_CreateParams glbceSupportPrm;
    SpxVaLink_CreateParams spxvaPrm;
    IpcFramesOutLinkRTOS_CreateParams ipcFramesOutVpssPrm;
    IpcFramesInLinkRTOS_CreateParams ipcFramesInDspPrm;
    MuxLink_CreateParams muxPrmDisp;  // not "real" MUX - changes channel 1 to channel 0 for display

    CameraLink_VipInstParams *pCameraInstPrm;
    CameraLink_OutParams *pCameraOutPrm;

    UInt32 ipcOutVpssId;
    UInt32 ipcInVideoId;
    UInt32 dupId[NUM_DUP_LINK];
    UInt32 vstabId;
    UInt32 glbceSupportId;
    UInt32 ipcFramesOutVpssId;
    UInt32 ipcFramesInDspId;

#ifdef WDR_ON
    WdrLink_CreateParams  wdrPrm;
#endif
    /* IPC struct init */
    MULTICH_INIT_STRUCT(IpcLink_CreateParams, ipcOutVpssPrm);
    MULTICH_INIT_STRUCT(IpcLink_CreateParams, ipcInVideoPrm);
    MULTICH_INIT_STRUCT(IpcBitsOutLinkRTOS_CreateParams, ipcBitsOutVideoPrm);
    MULTICH_INIT_STRUCT(IpcBitsInLinkHLOS_CreateParams, ipcBitsInHostPrm0);
    MULTICH_INIT_STRUCT(IpcFramesOutLinkRTOS_CreateParams, ipcFramesOutVpssPrm);
    MULTICH_INIT_STRUCT(IpcFramesInLinkRTOS_CreateParams, ipcFramesInDspPrm);
    MULTICH_INIT_STRUCT(MuxLink_CreateParams, muxPrm);

    OSA_printf("\n********** SPECTRONIX USECASE ********\n");
#ifdef SENSOR_10MP_MT9J003
    OSA_printf
        ("********* Entered Spectronix usecase - H264 1200x1200 @20fps + DSP overlay + D1 display ********\n\n");
#endif
#ifdef SENSOR_3MP_AR0331
    OSA_printf
        ("********* Entered Spectronix usecase - H264 1856x1504 @15fps + DSP overlay + D1 display ********\n\n");
#endif

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

    /* Link IDs */
    gVcamModuleContext.cameraId = SYSTEM_LINK_ID_CAMERA;
    gVencModuleContext.encId = SYSTEM_LINK_ID_VENC_0;
    gMjpegModuleContext.mjpepEncId = SYSTEM_LINK_ID_INVALID;
    gVsysModuleContext.muxId = SYSTEM_VPSS_LINK_ID_MUX_0;
    dupId[SCALER_DUP_IDX] = SYSTEM_VPSS_LINK_ID_DUP_1;
    dupId[VA_DUP_IDX] = SYSTEM_VPSS_LINK_ID_DUP_2;
    gVsysModuleContext.muxIdDisp = SYSTEM_VPSS_LINK_ID_MUX_1;
    gVcamModuleContext.sclrId[0] = SYSTEM_LINK_ID_INVALID;
    gVsysModuleContext.fdId = SYSTEM_LINK_ID_INVALID;
    gVsysModuleContext.swOsdId = SYSTEM_LINK_ID_SWOSD_0;
    gVcamModuleContext.ispId = SYSTEM_LINK_ID_ISP_0;
    vstabId = SYSTEM_LINK_ID_VSTAB_0;
    glbceSupportId = SYSTEM_LINK_ID_GLBCE_SUPPORT_0;
	
#ifdef WDR_ON
    gVcamModuleContext.wdrId = SYSTEM_LINK_ID_WDR;
    OSA_printf("WDR_ON: gVcamModuleContext.wdrId = %d (0x%X)\n\n", gVcamModuleContext.wdrId, gVcamModuleContext.wdrId);
#else
    gVcamModuleContext.wdrId = SYSTEM_LINK_ID_INVALID;
#endif

    gVdisModuleContext.displayId[VDIS_DEV_HDMI] = SYSTEM_LINK_ID_DISPLAY_0;
    gVdisModuleContext.displayId[VDIS_DEV_SD] = SYSTEM_LINK_ID_DISPLAY_2;
    ipcOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0;
    ipcInVideoId = SYSTEM_VIDEO_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;
    ipcFramesOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_FRAMES_OUT_0;
    ipcFramesInDspId   = SYSTEM_DSP_LINK_ID_IPC_FRAMES_IN_0;

    gVsysModuleContext.vaId = SYSTEM_LINK_ID_SPXVA_0;

	gVcamModuleContext.glbceId = gVcamModuleContext.wdrId;

    /* Camera Link params */
    CameraLink_CreateParams_Init(&cameraPrm);

    gVcamModuleContext.vnfId = SYSTEM_LINK_ID_VNF;
    cameraPrm.vnfLinkId = SYSTEM_LINK_ID_VNF;

#ifdef WDR_ON
    cameraPrm.captureMode = CAMERA_LINK_CAPMODE_DDR;
    cameraPrm.wdrLinkId = SYSTEM_LINK_ID_WDR;
    cameraPrm.outQueParams[0].nextLink = gVcamModuleContext.ispId;
#else
    cameraPrm.captureMode = CAMERA_LINK_CAPMODE_ISIF;
    cameraPrm.outQueParams[0].nextLink = gVcamModuleContext.vnfId;
#endif

    cameraPrm.ispLinkId = gVcamModuleContext.ispId;
    cameraPrm.outQueParams[1].nextLink = gVsysModuleContext.muxId;

    /* This is for TVP5158 Audio Channels - Change it to 16 if there are 16
     * audio channels connected in cascade */
    cameraPrm.numAudioChannels = 0;
    cameraPrm.numVipInst = 1;

    cameraPrm.tilerEnable = FALSE;

    cameraPrm.vsEnable = gUI_mcfw_config.vsEnable = 1;
    cameraPrm.vstabLinkId = vstabId;

    pCameraInstPrm = &cameraPrm.vipInst[0];
    pCameraInstPrm->vipInstId = SYSTEM_CAMERA_INST_VP_CSI2;
    pCameraInstPrm->videoDecoderId = MultiCh_getSensorId(gUI_mcfw_config.sensorId);
    pCameraInstPrm->inDataFormat = SYSTEM_DF_YUV420SP_UV;

    pCameraInstPrm->sensorOutWidth  = VIDEO_FRAME_SIZE_WIDTH;
    pCameraInstPrm->sensorOutHeight = VIDEO_FRAME_SIZE_HEIGHT;

    cameraPrm.issVnfEnable = 1;
    pCameraInstPrm->numOutput = 2;

    /* First stream */
    pCameraOutPrm = &pCameraInstPrm->outParams[0];
    pCameraOutPrm->scEnable = FALSE;

    pCameraOutPrm->dataFormat = SYSTEM_DF_BAYER_RAW; //SYSTEM_DF_YUV420SP_UV;
    pCameraOutPrm->scOutWidth  = SPXVA_FRAME_WIDTH;
    pCameraOutPrm->scOutHeight = SPXVA_FRAME_HEIGHT;



    pCameraOutPrm->outQueId = 0;
#ifdef SENSOR_10MP_MT9J003   // 10Mp
	pCameraInstPrm->standard        = SYSTEM_STD_1200_1200;
#else  //#ifdef SENSOR_3MP_AR0331  // 3Mp
	pCameraInstPrm->standard        = SYSTEM_STD_1856_1504;
#endif



    /* Second stream */
    pCameraOutPrm = &pCameraInstPrm->outParams[1];
    pCameraOutPrm->dataFormat = SYSTEM_DF_YUV420SP_UV;
    pCameraOutPrm->scEnable = FALSE;

	if(!memcmp(GetAnalogStandard(), "PAL", 3))
		ntsc_pal_standard = SYSTEM_STD_PAL;
	else
		ntsc_pal_standard = SYSTEM_STD_NTSC;

    pCameraOutPrm->standard = ntsc_pal_standard;

    pCameraOutPrm->scOutWidth = 720;
    
	if (ntsc_pal_standard == SYSTEM_STD_PAL)

	{
    	pCameraOutPrm->scOutHeight = PAL_SC_OUT_HEIGHT;
    }
    else
	{
    	pCameraOutPrm->scOutHeight = NTSC_SC_OUT_HEIGHT;
    }
	
	pCameraOutPrm->outQueId = 1;

    /* 2A config */
    cameraPrm.t2aConfig.n2A_vendor = gUI_mcfw_config.n2A_vendor;
    cameraPrm.t2aConfig.n2A_mode = gUI_mcfw_config.n2A_mode;

    /* vstab Link params */
    vstabPrm.totalFrameWidth  = pCameraInstPrm->sensorOutWidth;
    vstabPrm.totalFrameHeight = pCameraInstPrm->sensorOutHeight;

    glbceSupportPrm.glbceLinkID      = gVcamModuleContext.wdrId;  // defined if WDR_ON
    glbceSupportPrm.totalFrameWidth  = pCameraInstPrm->sensorOutWidth;
    glbceSupportPrm.totalFrameHeight = pCameraInstPrm->sensorOutHeight;

#ifdef WDR_ON
	cameraPrm.glbceLinkId = SYSTEM_LINK_ID_INVALID;

	wdrPrm.inQueParams.prevLinkId    = gVcamModuleContext.cameraId;
	wdrPrm.inQueParams.prevLinkQueId = 0;
	wdrPrm.outQueParams[0].nextLink  = gVcamModuleContext.ispId;
	wdrPrm.chCreateParams[0].dParams.wdrMode = gUI_mcfw_config.glbceEnable > 3 ? gUI_mcfw_config.glbceEnable -3 : 0;

	ispPrm.inQueParams.prevLinkId    = gVcamModuleContext.wdrId;
	ispPrm.inQueParams.prevLinkQueId = 0;
	ispPrm.numOutQueue               = 2;
	ispPrm.outQueInfo[0].nextLink    = gVcamModuleContext.vnfId;
	ispPrm.outQueInfo[1].nextLink    = gVsysModuleContext.muxId;
	ispPrm.clkDivM                   = 10;
	ispPrm.clkDivN                   = 20;
	ispPrm.vsEnable = gUI_mcfw_config.vsEnable;

	ispPrm.outQueuePrm[0].dataFormat = SYSTEM_DF_YUV420SP_UV;
	ispPrm.outQueuePrm[0].width      = SPXVA_FRAME_WIDTH;
	ispPrm.outQueuePrm[0].height     = SPXVA_FRAME_HEIGHT;
	ispPrm.outQueuePrm[0].tilerEnable = 0;

	ispPrm.outQueuePrm[1].tilerEnable = 0;
	ispPrm.outQueuePrm[1].dataFormat  = SYSTEM_DF_YUV420SP_UV;
	ispPrm.outQueuePrm[1].width       = 720;
		
    
	if (ntsc_pal_standard == SYSTEM_STD_PAL)
	{
    	ispPrm.outQueuePrm[1].height = PAL_SC_OUT_HEIGHT;
    }
    else
	{
    	ispPrm.outQueuePrm[1].height = NTSC_SC_OUT_HEIGHT;
    }
		
    ispPrm.outQueuePrm[1].standard   = ntsc_pal_standard;
    ispPrm.vnfFullResolution = FALSE;
#endif  // WDR_ON

    cameraPrm.vnfFullResolution = FALSE;


    /* VNF link params */
    VnfLink_ChCreateParams *vnfParams;

    VnfLink_CreateParams_Init(&vnfPrm);
#ifdef WDR_ON
    vnfPrm.inQueParams.prevLinkId = gVcamModuleContext.ispId;
#else
	vnfPrm.inQueParams.prevLinkId = gVcamModuleContext.cameraId;
#endif
	
	vnfPrm.inQueParams.prevLinkQueId = 0;

    //connect to video analytics link
    vnfPrm.outQueParams.nextLink = dupId[VA_DUP_IDX];


    vnfParams = &vnfPrm.chCreateParams[0];
    vnfParams->sParams.eOutputFormat = SYSTEM_DF_YUV420SP_UV;
    if (gUI_mcfw_config.ldcEnable)
    {
        vnfParams->sParams.eOperateMode = VNF_LINK_LDC_AFFINE_NSF_TNF;
    }
    else
    {
#ifdef USE_TNF2_FILTER
        vnfParams->sParams.eOperateMode =  VNF_LINK_3DNF;
#elif defined (USE_TNF3_FILTER)
        vnfParams->sParams.eOperateMode =  VNF_LINK_TNF3;
#else
        vnfParams->sParams.eOperateMode = VNF_LINK_AFFINE_NSF_TNF;
#endif
        vnfParams->sParams.eNsfSet = VNF_LINK_NSF_LUMA_CHROMA;
    }

    if (((vnfParams->sParams.eOperateMode == VNF_LINK_TNF3) && (vnfParams->sParams.eNsfSet == VNF_LINK_NSF_LUMA_CHROMA)) ||
        (vnfParams->sParams.eOperateMode == VNF_LINK_NSF2) || (vnfParams->sParams.eOperateMode == VNF_LINK_LDC_AFFINE_NSF_TNF))
    {
            if (gUI_mcfw_config.glbceEnable)  // WDR_ON
            {
                ispPrm.vnfFullResolution = TRUE;
                cameraPrm.vnfFullResolution = FALSE;
            }
            else
            {
                ispPrm.vnfFullResolution = FALSE;
    			cameraPrm.vnfFullResolution = TRUE;
			}
    }

    vnfParams->dParams.ldcParams.eInterpolationLuma = VNF_LINK_YINTERPOLATION_BILINEAR;
    vnfParams->dParams.ldcParams.unPixelPad = 4;

    vnfParams->dParams.nsfParams.bLumaEn = TRUE;
    vnfParams->dParams.nsfParams.bChromaEn = TRUE;
    vnfParams->dParams.nsfParams.eSmoothVal = VNF_LINK_SMOOTH_2;
    vnfParams->dParams.nsfParams.bSmoothLumaEn = TRUE;
    vnfParams->dParams.nsfParams.bSmoothChromaEn = FALSE;

    vnfParams->dParams.tnfParams.useDefault = TRUE;

    vnfParams->dParams.nsfFilter.eFilterParam = VNF_LINK_PARAM_DEFAULT;
    vnfParams->dParams.nsfEdge.eEdgeParam = VNF_LINK_PARAM_DISABLE;
    vnfParams->dParams.nsfShading.eShdParam = VNF_LINK_PARAM_DISABLE;
    vnfParams->dParams.nsfDesaturation.eDesatParam = VNF_LINK_PARAM_DISABLE;

    vnfPrm.chCreateParams[0].bSnfEnable = gUI_mcfw_config.snfEnable;
    vnfPrm.chCreateParams[0].bTnfEnable = gUI_mcfw_config.tnfEnable;
    vnfPrm.chCreateParams[0].strength   = gUI_mcfw_config.vnfStrength;

    vnfPrm.tilerEnable = FALSE;

    //Muxing the HD video link with the SD video link
    muxPrm.numInQue = 2;

    muxPrm.inQueParams[0].prevLinkId = dupId[VA_DUP_IDX];
    muxPrm.inQueParams[0].prevLinkQueId = 0;

#ifdef WDR_ON
    muxPrm.inQueParams[1].prevLinkId = gVcamModuleContext.ispId;
 	muxPrm.inQueParams[1].prevLinkQueId = 1;
#else
    muxPrm.inQueParams[1].prevLinkId = gVcamModuleContext.cameraId;
 	muxPrm.inQueParams[1].prevLinkQueId = 1;
#endif  // WDR_ON

    muxPrm.outQueParams.nextLink = gVsysModuleContext.swOsdId;

    muxPrm.muxNumOutChan = 2;
    muxPrm.outChMap[0].inQueId = 1;
    muxPrm.outChMap[0].inChNum = 0;

    muxPrm.outChMap[1].inQueId = 0;
    muxPrm.outChMap[1].inChNum = 0;

    /* SWOSD Link Params  - done on both HD and SD*/
    swosdPrm.inQueParams.prevLinkId = gVsysModuleContext.muxId;
    swosdPrm.inQueParams.prevLinkQueId = 0;
    swosdPrm.outQueParams.nextLink = dupId[SCALER_DUP_IDX];

    /* Dup link for Scaler params */
    dupPrm[SCALER_DUP_IDX].dupId = SCALER_DUP_IDX;
    dupPrm[SCALER_DUP_IDX].inQueParams.prevLinkId = gVsysModuleContext.swOsdId;
    dupPrm[SCALER_DUP_IDX].inQueParams.prevLinkQueId = 0;
    dupPrm[SCALER_DUP_IDX].numOutQue = 2;
    dupPrm[SCALER_DUP_IDX].outQueParams[0].nextLink = gVsysModuleContext.muxIdDisp;
    dupPrm[SCALER_DUP_IDX].outQueParams[1].nextLink = gVdisModuleContext.displayId[VDIS_DEV_SD];
    dupPrm[SCALER_DUP_IDX].notifyNextLink = TRUE;


    /* display link params */
    MULTICH_INIT_STRUCT(DisplayLink_CreateParams,displayPrm_SD);
    displayPrm_SD.inQueParams[0].prevLinkId = dupId[SCALER_DUP_IDX];
    displayPrm_SD.inQueParams[0].prevLinkQueId = 1;
    displayPrm_SD.displayRes = pCameraOutPrm->standard;
    displayPrm_SD.displayId  = DISPLAY_LINK_DISPLAY_SD;


    /* Dup link for Spectronix video analytics */
    dupPrm[VA_DUP_IDX].dupId = VA_DUP_IDX;
    dupPrm[VA_DUP_IDX].inQueParams.prevLinkId    = gVcamModuleContext.vnfId;
    dupPrm[VA_DUP_IDX].inQueParams.prevLinkQueId = 0;


    dupPrm[VA_DUP_IDX].numOutQue = 2;
    dupPrm[VA_DUP_IDX].outQueParams[0].nextLink = gVsysModuleContext.muxId;
    dupPrm[VA_DUP_IDX].outQueParams[1].nextLink = ipcFramesOutVpssId;
    dupPrm[VA_DUP_IDX].notifyNextLink = TRUE;

    /* IPC Frames Out VPSS for VA link params */
    ipcFramesOutVpssPrm.baseCreateParams.inQueParams.prevLinkId = dupId[VA_DUP_IDX];
    ipcFramesOutVpssPrm.baseCreateParams.inQueParams.prevLinkQueId = 1;
    ipcFramesOutVpssPrm.baseCreateParams.notifyPrevLink = TRUE;
    ipcFramesOutVpssPrm.baseCreateParams.inputFrameRate = 20;
    ipcFramesOutVpssPrm.baseCreateParams.outputFrameRate = 20;

    ipcFramesOutVpssPrm.baseCreateParams.numOutQue = 1;
    ipcFramesOutVpssPrm.baseCreateParams.outQueParams[0].nextLink = ipcFramesInDspId;
    ipcFramesOutVpssPrm.baseCreateParams.notifyNextLink = TRUE;

    ipcFramesOutVpssPrm.baseCreateParams.processLink = SYSTEM_LINK_ID_INVALID;
    ipcFramesOutVpssPrm.baseCreateParams.notifyProcessLink = FALSE;
    ipcFramesOutVpssPrm.baseCreateParams.noNotifyMode = FALSE;
    ipcFramesOutVpssPrm.linkId = SYSTEM_VPSS_LINK_ID_IPC_FRAMES_OUT_0;

    /* IPC Frames in DSP for VA link params */
    ipcFramesInDspPrm.baseCreateParams.inQueParams.prevLinkId = ipcFramesOutVpssId;
    ipcFramesInDspPrm.baseCreateParams.inQueParams.prevLinkQueId = 0;
    ipcFramesInDspPrm.baseCreateParams.numOutQue   = 1;
    ipcFramesInDspPrm.baseCreateParams.outQueParams[0].nextLink = gVsysModuleContext.vaId;
    ipcFramesInDspPrm.baseCreateParams.notifyPrevLink = TRUE;
    ipcFramesInDspPrm.baseCreateParams.notifyNextLink = TRUE;
    ipcFramesInDspPrm.baseCreateParams.noNotifyMode   = FALSE;

    /* VA link params */
    SpxVaLink_CreateParams_Init(&spxvaPrm);
    spxvaPrm.inQueParams.prevLinkId    = ipcFramesInDspId;
    spxvaPrm.inQueParams.prevLinkQueId = 0;
    spxvaPrm.swosdLinkId               = gVsysModuleContext.swOsdId;

    /* MUX link params to remove encoding of SD*/

    muxPrmDisp.numInQue = 1;
    muxPrmDisp.inQueParams[0].prevLinkId    = dupId[SCALER_DUP_IDX];
    muxPrmDisp.inQueParams[0].prevLinkQueId = 0;

    muxPrmDisp.outQueParams.nextLink = ipcOutVpssId;

    muxPrmDisp.muxNumOutChan = 1;

    muxPrmDisp.outChMap[0].inQueId = 0;
    muxPrmDisp.outChMap[0].inChNum = 1;

    /* IPC Out VPSS link params */
    ipcOutVpssPrm.inQueParams.prevLinkId = gVsysModuleContext.muxIdDisp;
    ipcOutVpssPrm.inQueParams.prevLinkQueId = 0;
    ipcOutVpssPrm.numOutQue = 1;
    ipcOutVpssPrm.outQueParams[0].nextLink = ipcInVideoId;
    ipcOutVpssPrm.notifyNextLink = TRUE;
    ipcOutVpssPrm.notifyPrevLink = TRUE;
    ipcOutVpssPrm.noNotifyMode = FALSE;

    /* IPC In VIDEO params */
    ipcInVideoPrm.inQueParams.prevLinkId = ipcOutVpssId;
    ipcInVideoPrm.inQueParams.prevLinkQueId = 0;
    ipcInVideoPrm.numOutQue = 1;
    ipcInVideoPrm.outQueParams[0].nextLink = gVencModuleContext.encId;
    ipcInVideoPrm.notifyNextLink = TRUE;
    ipcInVideoPrm.notifyPrevLink = TRUE;
    ipcInVideoPrm.noNotifyMode = FALSE;

    /* Video Encoder Link params */
    MULTICH_INIT_STRUCT(EncLink_CreateParams, encPrm);
    {
        EncLink_ChCreateParams *pLinkChPrm;
        EncLink_ChDynamicParams *pLinkDynPrm;
        VENC_CHN_DYNAMIC_PARAM_S *pDynPrm;
        VENC_CHN_PARAMS_S *pChPrm;

        for (i = 0; i < VENC_PRIMARY_CHANNELS; i++)
        {
            pLinkChPrm  = &encPrm.chCreateParams[i];
            pLinkDynPrm = &pLinkChPrm->defaultDynamicParams;

            pChPrm      = &gVencModuleContext.vencConfig.encChannelParams[i];
            pDynPrm     = &pChPrm->dynamicParam;

            switch(gUI_mcfw_config.demoCfg.codec_combo) {
                case 0: pLinkChPrm->format = IVIDEO_H264HP; break; //"SINGLE_H264"
                case 1: pLinkChPrm->format = IVIDEO_MPEG4SP; break; //"SINGLE_MPEG4"
                case 2: pLinkChPrm->format = IVIDEO_MJPEG; break; //"SINGLE_JPEG"
                case 3: pLinkChPrm->format = (i==0)? IVIDEO_H264HP:IVIDEO_MJPEG; break; //"H264_JPEG"
                case 4: pLinkChPrm->format = (i==0)? IVIDEO_MPEG4SP:IVIDEO_MJPEG; break; //"MPEG4_JPEG"
                case 5: pLinkChPrm->format = (i==0)? IVIDEO_H264HP:IVIDEO_H264HP; break; //"DUAL_H264"
                case 6: pLinkChPrm->format = (i==0)? IVIDEO_MPEG4SP:IVIDEO_MPEG4SP; break; //"DUAL_MPEG4"
                case 7: pLinkChPrm->format = (i==0)? IVIDEO_H264HP:IVIDEO_MPEG4SP; break;  //"H264_MPEG4"
                case 8: pLinkChPrm->format = (i==0)? IVIDEO_H264HP:IVIDEO_H264HP; break;  //"TRIPLE_H264"
                case 9: pLinkChPrm->format = (i==0)? IVIDEO_MPEG4SP:IVIDEO_MPEG4SP; break; //"TRIPLE_MPEG4"
                default: pLinkChPrm->format = IVIDEO_H264HP;
            }

            pLinkChPrm->profile                 = gVencModuleContext.vencConfig.h264Profile[i];
            pLinkChPrm->dataLayout              = IVIDEO_PROGRESSIVE;
            pLinkChPrm->fieldMergeEncodeEnable  = FALSE;
            pLinkChPrm->enableAnalyticinfo      = pChPrm->enableAnalyticinfo;
            pLinkChPrm->maxBitRate              = pChPrm->maxBitRate;
            pLinkChPrm->encodingPreset          = pChPrm->encodingPreset;
            pLinkChPrm->rateControlPreset       = IVIDEO_USER_DEFINED; //pChPrm->rcType;
            pLinkChPrm->enableHighSpeed         = FALSE;
            pLinkChPrm->enableWaterMarking      = pChPrm->enableWaterMarking;
            pLinkChPrm->StreamPreset            = gUI_mcfw_config.StreamPreset[i];

            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;

            encPrm.numBufPerCh[i] = 4;
            gVencModuleContext.encFormat[i] = pLinkChPrm->format;
        }
    }

    /* Video Encoder Framerate */
    encPrm.chCreateParams[0].defaultDynamicParams.inputFrameRate = 20;  // ENC_LINK_DEFAULT_ALGPARAMS_INPUTFRAMERATE;

    encPrm.chCreateParams[1].defaultDynamicParams.inputFrameRate = 20;  // ENC_LINK_DEFAULT_ALGPARAMS_INPUTFRAMERATE;

    encPrm.vsEnable = gUI_mcfw_config.vsEnable;

    if(gUI_mcfw_config.vaUseCase == TRUE)
    {
        encPrm.isVaUseCase = 1;
    }
    else
    {
        encPrm.isVaUseCase = 0;
    }
    encPrm.inQueParams.prevLinkId = ipcInVideoId;
    encPrm.inQueParams.prevLinkQueId = 0;
    encPrm.outQueParams.nextLink = gVencModuleContext.ipcBitsOutRTOSId;

    /* IPC Bits Out VIDEO Link params */
    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);

    /* IPC Bits In HOST Link params */
    ipcBitsInHostPrm0.baseCreateParams.inQueParams.prevLinkId = gVencModuleContext.ipcBitsOutRTOSId;
    ipcBitsInHostPrm0.baseCreateParams.inQueParams.prevLinkQueId = 0;
    MultiCh_ipcBitsInitCreateParams_BitsInHLOS(&ipcBitsInHostPrm0);

    /* Links Creation */
    /* Camera Link */
    System_linkCreate(gVcamModuleContext.cameraId, &cameraPrm, sizeof(cameraPrm));
    System_linkControl(gVcamModuleContext.cameraId, CAMERA_LINK_CMD_DETECT_VIDEO, NULL, 0, TRUE);


#ifdef WDR_ON
    System_linkCreate(gVcamModuleContext.wdrId, &wdrPrm ,sizeof(wdrPrm));
	System_linkCreate(gVcamModuleContext.ispId, &ispPrm, sizeof(ispPrm));
#endif

    System_linkCreate(gVcamModuleContext.vnfId, &vnfPrm, sizeof(vnfPrm));

    /* Dup link for VA */
    System_linkCreate(dupId[VA_DUP_IDX], &dupPrm[VA_DUP_IDX], sizeof(dupPrm[VA_DUP_IDX]));

    /* IPC Frames links */
    System_linkCreate(ipcFramesOutVpssId, &ipcFramesOutVpssPrm, sizeof(ipcFramesOutVpssPrm));
    System_linkCreate(ipcFramesInDspId, &ipcFramesInDspPrm, sizeof(ipcFramesInDspPrm));

    /* VA link */
    System_linkCreate(gVsysModuleContext.vaId, &spxvaPrm, sizeof(spxvaPrm));

    System_linkCreate(gVsysModuleContext.muxId, &muxPrm, sizeof(muxPrm));

    /* SWOSDHD Link */
    System_linkCreate(gVsysModuleContext.swOsdId, &swosdPrm, sizeof(swosdPrm));

    /* Dup Link for Scaler */
    System_linkCreate(dupId[SCALER_DUP_IDX], &dupPrm[SCALER_DUP_IDX], sizeof(dupPrm[SCALER_DUP_IDX]));

    /* Dup link for display */

    System_linkCreate(gVsysModuleContext.muxIdDisp, &muxPrmDisp, sizeof(muxPrmDisp));

    /* Scaler Link */
    //System_linkCreate(gVcamModuleContext.sclrId[0], &sclrPrm, sizeof(sclrPrm));

    //System_linkCreate(SYSTEM_VPSS_LINK_ID_NULL_0, &nullPrm, sizeof(nullPrm));

    /* IPC Links */
    System_linkCreate(ipcOutVpssId, &ipcOutVpssPrm, sizeof(ipcOutVpssPrm));
    System_linkCreate(ipcInVideoId, &ipcInVideoPrm, sizeof(ipcInVideoPrm));

    /* Video Encoder Link */
    System_linkCreate(gVencModuleContext.encId, &encPrm, sizeof(encPrm));

    /* VSTAB link */
    System_linkCreate(vstabId, &vstabPrm, sizeof(vstabPrm));

    /* IPC Bits Links */
    System_linkCreate(gVencModuleContext.ipcBitsOutRTOSId, &ipcBitsOutVideoPrm, sizeof(ipcBitsOutVideoPrm));
    System_linkCreate(gVencModuleContext.ipcBitsInHLOSId, &ipcBitsInHostPrm0, sizeof(ipcBitsInHostPrm0));

    /* display link */
    System_linkCreate(gVdisModuleContext.displayId[VDIS_DEV_SD], &displayPrm_SD, sizeof(displayPrm_SD));

    /*
     *  changed for spec: fps drop rate bug fix - the delay has been moved to the VA_DUP.
     *	delay on the SCLR_DUP causes for frames drop rate after some time.
     */

//#define NO_DUP_DELAY_PARAM
#ifndef NO_DUP_DELAY_PARAM
    Vsys_setDupDelayPrm(dupId[VA_DUP_IDX],
                        0,                      // outQueId - should be a valid out queue Id.
                        1);                     // syncOutQueId - can be valid queue Id or
                                                //              - an invlaid queueId(DUP_LINK_DELAYED_OUTPUT_QUE_INVALID_ID)
                                                //              - In the latter case it waits on all the other output queues.
#endif // NO_DUP_DELAY_PARAM
    gNoiseFilterMode = gUI_mcfw_config.noisefilterMode;

    OSA_printf("USECASE SETUP DONE vnfParams->sParams.eOperateMode %d\n", vnfParams->sParams.eOperateMode);
}

/* ===================================================================
 *  @func     MultiCh_deleteSpectronixStream
 *
 *  @desc     Delete and release resource from all usecase links
 *
 *  @modif    This function modifies the following structures
 *
 *  @inputs   This function takes the following inputs
 *			  None
 *
 *  @outputs  None
 *
 *  @return   None
 *  ==================================================================
 */
Void MultiCh_deleteSpectronixStream()
{
    //UInt32 ispId;
    UInt32 mergeId[NUM_MERGE_LINK];
    UInt32 ipcOutVpssId;
    UInt32 ipcInVideoId;
    UInt32 ipcFramesOutVpssId;
    UInt32 ipcFramesInDspId;
    UInt32 dupId[NUM_DUP_LINK];
    UInt32 vstabId;
    UInt32 glbceSupportId;

    mergeId[CAM_STREAM_MERGE_IDX] = SYSTEM_LINK_ID_INVALID;
    dupId[SCALER_DUP_IDX] = SYSTEM_VPSS_LINK_ID_DUP_1;
    dupId[VA_DUP_IDX] = SYSTEM_VPSS_LINK_ID_DUP_2;
    gVcamModuleContext.sclrId[0] = SYSTEM_LINK_ID_INVALID;
    gVsysModuleContext.fdId = SYSTEM_LINK_ID_INVALID;
    gVsysModuleContext.swOsdId = SYSTEM_LINK_ID_SWOSD_0;
    ipcOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0;
    ipcInVideoId = SYSTEM_VIDEO_LINK_ID_IPC_IN_M3_0;
    ipcFramesOutVpssId = SYSTEM_VPSS_LINK_ID_IPC_FRAMES_OUT_0;
    ipcFramesInDspId   = SYSTEM_DSP_LINK_ID_IPC_FRAMES_IN_0;
    gVcamModuleContext.ispId = SYSTEM_LINK_ID_INVALID;
    vstabId = SYSTEM_LINK_ID_VSTAB_0;
    glbceSupportId = SYSTEM_LINK_ID_INVALID;

    /* Links Deletion in reverse order from sink to source */

    /* display link */
    System_linkDelete(gVdisModuleContext.displayId[VDIS_DEV_SD]);

    /* IPC Bits Links */
    System_linkDelete(gVencModuleContext.ipcBitsInHLOSId);
    System_linkDelete(gVencModuleContext.ipcBitsOutRTOSId);

    /* VSTAB Link */
    System_linkDelete(vstabId);

    /* Video Encoder Link */
    System_linkDelete(gVencModuleContext.encId);

    /* IPC Links */
    System_linkDelete(ipcInVideoId);
    System_linkDelete(ipcOutVpssId);

    System_linkDelete(gVsysModuleContext.muxIdDisp);

    /* Scaler Link */
    //System_linkDelete(gVcamModuleContext.sclrId[0]);

    /* Dup link for Scaler */
    System_linkDelete(dupId[SCALER_DUP_IDX]);

    /* SWOSDHD Link */
    System_linkDelete(gVsysModuleContext.swOsdId);

#ifdef INCLUDE_MUX_LINK_INSTEAD_OF_MERGE
    System_linkDelete(gVsysModuleContext.muxId);
#endif

    /* VA link */
    System_linkDelete(gVsysModuleContext.vaId);

    /* IPC Frames Links */
    System_linkDelete(ipcFramesInDspId);
    System_linkDelete(ipcFramesOutVpssId);

    /* Dup for VA link */
    System_linkDelete(dupId[VA_DUP_IDX]);

    System_linkDelete(gVcamModuleContext.vnfId);

#ifdef WDR_ON
    System_linkDelete(gVcamModuleContext.wdrId);
#endif
    /* Camera Link */
    System_linkDelete(gVcamModuleContext.cameraId);

    /* Print the HWI, SWI and all tasks load */
    /* Reset the accumulated timer ticks */
    MultiCh_prfLoadCalcEnable(FALSE, TRUE, FALSE);

    OSA_printf("USECASE TEARDOWN DONE\n");
}

