/*******************************************************************************
 *                                                                             *
 * Copyright (c) 2009 Texas Instruments Incorporated - http://www.ti.com/      *
 *                        ALL RIGHTS RESERVED                                  *
 *                                                                             *
 ******************************************************************************/
/*
                                          Capture (4CH 1080p30 422)
                                           ******************
                                                |         |
                                               DUP0      DUP1
                                               | | |     | | |
                                               | | |     | | +---------------------------+
                                               | | |  +--+ |                             |
                                               | | +--[----[--------------------------+  |
                                               | |    |    +--+                       |  |
                                               | +----[----+  |                      MERGE1
                                               |      |    |  |                        |
                                               | +----+  MERGE0                        |
                                               | |          |                          |
                                               | |          +----- SC5 ------+         |
                                               | |             (4CH D1 422)  |        SC5
                                           +---+ +--------+                  |     (4CH 422) (MJPEG)
                                           |              |                  |         |
                                         DEIH (BP-Mode)  DEI (BP-Mode)       |         |
                                          | |            | |                 |  +------+
                              2CH 1080p30 | |            | | 2CH 1080p30     |  |
                                          | |            | |                 |  |
                               +----------+ +-----+  +---+ +---+             |  |
                               |                  |  |            |          |  |
                               |          +-------[--+            |         MERGE2
                               |          |       |               |          |  |
                               |   (DEI-SC2 422)  +--+            |          |  |
                               |          |          |            |          |  |
                               |          |          |       (VIP-SC4 420)   |  |
                          (DEI-SC1 422)   |   (VIP-SC3 420)       |          NSF
                               |          |          |            |           |(4CH D1 420) + 4Ch MJEPG
                               +--+   +---+          +----+       |           |
                                  |   |                   |       |           |
                                  MERGE3                 |       +--------+  |
                                    |                     +--------------+ |  |
                                   DUP2------------------+               | |  |
                                    |                    |               | |  |
    +--<<<processLink>>>--- IPC Frames Out (M3)          |               | |  |
    |                               |                    |               MERGE4
    |                       IPC Frames IN (A8)           |                 |
  FramesInDSP                       |                    |                 |
    |                       IPC Frames Out (A8)          |              IPC OUT(M3)----<<<processLink>>>---FramesInDSP--+
 ALG LINK                           |                    |                 |                                            |
 <OSD SCD Algs>             IPC Frames IN (M3)           |              IPC IN(M3)                                      |
                                    |              On-Chip HDMI            |                                            |
                              OFF-Chip HDMI          1080p60      Encode (4CH 1080p30 + 4CH D1)                      ALG_LINK
                                 1080p60          (1-Ch 1-Window)          |                                       <OSD, SCD Algs>
                             (1-Ch 1-Window)                          IPC Bits OUT (M3)
                                                                           |
                                                                      IPC Bits IN (A8)

(BP-Mode) --> Bypass Mode
*/

#include "multich_common.h"

//#include "mcfw/interfaces/link_api/system_tiler.h"


#define     NUM_CAPTURE_DEVICES     (4)

#define     ENABLE_SCL_NSF           0

/* =============================================================================
 * Externs
 * =============================================================================
 */

//static UInt8 SCDChannelMonitor[4] = {4, 5, 6, 7};

//#define TWOOSD_INSTANCE

typedef struct {

    UInt32 mergeId[5];
    UInt32 dupId[3];
    UInt32 ipcOutVpssId;
    UInt32 ipcInVideoId;
    UInt32 ipcFrameOutVpssId[2];
    UInt32 ipcFramesInDspId[2];
} MultiChHd_VcapVencVdisObj;

MultiChHd_VcapVencVdisObj gMultiChHd_VcapVencVdisObj;

/* =============================================================================
 * Use case code
 * =============================================================================
 */

static SystemVideo_Ivahd2ChMap_Tbl systemVid_encDecIvaChMapTbl =
{
    .isPopulated = 1,
    .ivaMap[0] =
    {
        .EncNumCh  = 2,
        .EncChList = {0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0},
        .DecNumCh  = 0,
        .DecChList = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    },
    .ivaMap[1] =
    {
        .EncNumCh  = 2,
        .EncChList = {1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0},
        .DecNumCh  = 0,
        .DecChList = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    },
    .ivaMap[2] =
    {
        .EncNumCh  = 8,
        .EncChList = {4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0 , 0, 0},
        .DecNumCh  = 0,
        .DecChList = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    },
};

Void MultiChHd_createVcapVencVdis()
{
    CaptureLink_CreateParams        capturePrm;
    DisplayLink_CreateParams    displayPrm;
    IpcLink_CreateParams            ipcOutVpssPrm;
    IpcLink_CreateParams            ipcInVideoPrm;
    EncLink_CreateParams            encPrm;
    IpcBitsOutLinkRTOS_CreateParams ipcBitsOutVideoPrm;
    IpcBitsInLinkHLOS_CreateParams  ipcBitsInHostPrm;

    CaptureLink_VipInstParams *pCaptureInstPrm;
    CaptureLink_OutParams     *pCaptureOutPrm;
    UInt32 vipInstId, i, j;

    MULTICH_INIT_STRUCT(IpcLink_CreateParams           ,ipcOutVpssPrm);
    MULTICH_INIT_STRUCT(IpcLink_CreateParams           ,ipcInVideoPrm);
    MULTICH_INIT_STRUCT(IpcBitsOutLinkRTOS_CreateParams,ipcBitsOutVideoPrm);
    MULTICH_INIT_STRUCT(IpcBitsInLinkHLOS_CreateParams ,ipcBitsInHostPrm);
	MULTICH_INIT_STRUCT(CaptureLink_CreateParams ,capturePrm);
    MULTICH_INIT_STRUCT(EncLink_CreateParams, encPrm);
    MULTICH_INIT_STRUCT(DisplayLink_CreateParams ,displayPrm);

    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
    );

    gVcapModuleContext.captureId    = SYSTEM_LINK_ID_CAPTURE;
    gVdisModuleContext.displayId[0] = SYSTEM_LINK_ID_DISPLAY_0; // ON CHIP HDMI
    gVencModuleContext.encId            = SYSTEM_LINK_ID_VENC_0;
    gVencModuleContext.ipcBitsInHLOSId   = SYSTEM_HOST_LINK_ID_IPC_BITS_IN_0;
    gVencModuleContext.ipcBitsOutRTOSId = SYSTEM_VIDEO_LINK_ID_IPC_BITS_OUT_0;

    gMultiChHd_VcapVencVdisObj.ipcOutVpssId      = SYSTEM_VPSS_LINK_ID_IPC_OUT_M3_0;
    gMultiChHd_VcapVencVdisObj.ipcInVideoId      = SYSTEM_VIDEO_LINK_ID_IPC_IN_M3_0;

    CaptureLink_CreateParams_Init(&capturePrm);

    capturePrm.numVipInst               = 2;
    capturePrm.outQueParams[0].nextLink = gMultiChHd_VcapVencVdisObj.ipcOutVpssId;
    capturePrm.outQueParams[1].nextLink = gVdisModuleContext.displayId[0];//mergeId;
    capturePrm.tilerEnable              = FALSE;
    capturePrm.enableSdCrop             = FALSE;
    capturePrm.numBufsPerCh               = 8;
    vipInstId = 0;
	{
        pCaptureInstPrm                     = &capturePrm.vipInst[vipInstId];
        pCaptureInstPrm->vipInstId          = SYSTEM_CAPTURE_INST_VIP0_PORTA; /* Need to change based on actual HD video decoder */
        pCaptureInstPrm->videoDecoderId     = SYSTEM_DEVICE_VID_DEC_TVP7002_DRV; /* Need to change based on actual HD video decoder */
        pCaptureInstPrm->inDataFormat       = SYSTEM_DF_YUV422P;
        pCaptureInstPrm->standard           = SYSTEM_STD_720P_60; /* Need to change based on actual HD video decoder */
        pCaptureInstPrm->numOutput          = 1; /* Need to change based on actual HD video decoder */

        pCaptureOutPrm                      = &pCaptureInstPrm->outParams[0];
        pCaptureOutPrm->dataFormat          = SYSTEM_DF_YUV420SP_UV;
        pCaptureOutPrm->scEnable            = FALSE; /* Need to change based on actual HD video decoder */
        pCaptureOutPrm->scOutWidth          = 176; /* Need to change based on actual HD video decoder */
        pCaptureOutPrm->scOutHeight         = 144; /* Need to change based on actual HD video decoder */
        pCaptureOutPrm->outQueId            = 0;
    }
	vipInstId = 1;
	{
		pCaptureInstPrm                     = &capturePrm.vipInst[vipInstId];
		pCaptureInstPrm->vipInstId          = SYSTEM_CAPTURE_INST_VIP1_PORTA; /* Need to change based on actual HD video decoder */
		pCaptureInstPrm->videoDecoderId     = SYSTEM_DEVICE_VID_DEC_TVP7002_DRV; /* Need to change based on actual HD video decoder */
		pCaptureInstPrm->inDataFormat       = SYSTEM_DF_YUV422P;
		pCaptureInstPrm->standard           = SYSTEM_STD_720P_60; /* Need to change based on actual HD video decoder */
		pCaptureInstPrm->numOutput          = 1; /* Need to change based on actual HD video decoder */

		pCaptureOutPrm                      = &pCaptureInstPrm->outParams[0];
		pCaptureOutPrm->dataFormat          = SYSTEM_DF_YUV422I_YUYV;//SYSTEM_DF_YUV420SP_UV;
		pCaptureOutPrm->scEnable            = FALSE; /* Need to change based on actual HD video decoder */
		pCaptureOutPrm->scOutWidth          = 176; /* Need to change based on actual HD video decoder */
		pCaptureOutPrm->scOutHeight         = 144; /* Need to change based on actual HD video decoder */
		pCaptureOutPrm->outQueId            = 1;
	}

    ipcOutVpssPrm.inQueParams.prevLinkId    = gVcapModuleContext.captureId;//gMultiChHd_VcapVencVdisObj.mergeId[4];

//    ipcOutVpssPrm.inQueParams.prevLinkId        = mergeId;

    ipcOutVpssPrm.inQueParams.prevLinkQueId = 0;
    ipcOutVpssPrm.outQueParams[0].nextLink  = gMultiChHd_VcapVencVdisObj.ipcInVideoId;
    ipcOutVpssPrm.notifyNextLink            = TRUE;//FALSE;
    ipcOutVpssPrm.notifyPrevLink            = TRUE;
    ipcOutVpssPrm.noNotifyMode              = FALSE;

    ipcInVideoPrm.inQueParams.prevLinkId    = gMultiChHd_VcapVencVdisObj.ipcOutVpssId;
    ipcInVideoPrm.inQueParams.prevLinkQueId = 0;
    ipcInVideoPrm.outQueParams[0].nextLink  = gVencModuleContext.encId;
    ipcInVideoPrm.notifyNextLink            = TRUE;
    ipcInVideoPrm.notifyPrevLink            = TRUE;//FALSE;
    ipcInVideoPrm.noNotifyMode              = TRUE;

    ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkId    = gVencModuleContext.encId;
    ipcBitsOutVideoPrm.baseCreateParams.inQueParams.prevLinkQueId = 0;
    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;
    ipcBitsInHostPrm[0].baseCreateParams.outQueParams[0].nextLink   = SYSTEM_LINK_ID_INVALID;
    MultiCh_ipcBitsInitCreateParams_BitsInHLOS(&ipcBitsInHostPrm[0]);

    encPrm.numBufPerCh[0] = 6; //D1
    {
        EncLink_ChCreateParams *pLinkChPrm;
        EncLink_ChDynamicParams *pLinkDynPrm;
        VENC_CHN_DYNAMIC_PARAM_S *pDynPrm;
        VENC_CHN_PARAMS_S *pChPrm;

        /* Primary Stream Params - D1 */
        for (i=0; i<1; 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              = IVIDEO_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;
            printf("************************pLinkDynPrm->inputFrameRate: %d\n",pLinkDynPrm->inputFrameRate);
        }

        encPrm.inQueParams.prevLinkId   = gMultiChHd_VcapVencVdisObj.ipcInVideoId;
        encPrm.inQueParams.prevLinkQueId= 0;
        encPrm.outQueParams.nextLink    = gVencModuleContext.ipcBitsOutRTOSId;
    }

    displayPrm.inQueParams[0].prevLinkId    = gVcapModuleContext.captureId;
    displayPrm.inQueParams[0].prevLinkQueId = 1;

    displayPrm.displayRes                = gVdisModuleContext.vdisConfig.deviceParams[VDIS_DEV_HDMI].resolution;

#ifndef SYSTEM_USE_VIDEO_DECODER
    capturePrm.isPalMode = Vcap_isPalMode();
#endif

    System_linkCreate (gVcapModuleContext.captureId, &capturePrm, sizeof(capturePrm));

    //System_linkCreate(mergeId, &mergePrm, sizeof(mergePrm));
    System_linkCreate(gMultiChHd_VcapVencVdisObj.ipcOutVpssId , &ipcOutVpssPrm , sizeof(ipcOutVpssPrm) );
    System_linkCreate(gMultiChHd_VcapVencVdisObj.ipcInVideoId , &ipcInVideoPrm , sizeof(ipcInVideoPrm) );

    System_linkCreate(gVencModuleContext.encId, &encPrm, sizeof(encPrm));
    System_linkCreate(gVencModuleContext.ipcBitsOutRTOSId, &ipcBitsOutVideoPrm, sizeof(ipcBitsOutVideoPrm));
    System_linkCreate(gVencModuleContext.ipcBitsInHLOSId, &ipcBitsInHostPrm[0], sizeof(ipcBitsInHostPrm[0]));
    System_linkCreate(gVdisModuleContext.displayId[0], &displayPrm, sizeof(displayPrm));
    MultiCh_memPrintHeapStatus();
}


