/******************************************************************************
* FILE PURPOSE: Client Wrapper to integrate XDM0.9 Compliant Encoder to TVCT
******************************************************************************
* FILE NAME:   vctH264EncClient.c
*
* DESCRIPTION: Client Wrapper to integrate XDM0.9 Compliant Encoder to TVCT
*
* TABS: NONE
*
*
* (C) Copyright 2010, Texas Instruments Incorporated
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/
#include "vctH264EncClient.h"
#include <string.h>

void *h264GetStaticParams(void *h264EncInst) {
   h264EncInst_t *inst = (h264EncInst_t *)h264EncInst;
   return((void *)&inst->extn_params);
}

void *h264GetDynamicParams(void *h264EncInst){
   h264EncInst_t *inst = (h264EncInst_t *)h264EncInst;
   return((void *)&inst->extn_dynamicParams);
}

void *h264GetInArgs(void *h264EncInst) {
   h264EncInst_t *inst = (h264EncInst_t *)h264EncInst;
   return((void *)&inst->inArgs);
}

void *h264GetOutArgs(void *h264EncInst) {
   h264EncInst_t *inst = (h264EncInst_t *)h264EncInst;
   return((void *)&inst->outArgs);
}

void *h264GetStatus(void *h264EncInst) {
   h264EncInst_t *inst = (h264EncInst_t *)h264EncInst;
   return((void *)&inst->status);
}

void *h264GetFxns(void *h264EncInst) {
   h264EncInst_t *inst = (h264EncInst_t *)h264EncInst;
   return((void *)&inst->IALG_Fxns);
}

void h264InitInstance(void *h264EncInst)
{
    h264EncInst_t *inst = (h264EncInst_t *)h264EncInst;
    memset(inst, 0, sizeof(h264EncInst_t));

    inst->IALG_Fxns                    = H264VENC_TI_IH264VENC;
    inst->status.videncStatus.size     = sizeof(IH264VENC_Status);
    inst->inArgs.videncInArgs.size     = sizeof(IH264VENC_InArgs);
    inst->outArgs.videncOutArgs.size   = sizeof(IH264VENC_OutArgs);
    return;
}

extern volatile tulong hdResolution;
void h264SetStaticParams(void *h264EncInst, void *codecParams)
{
    h264EncInst_t *inst           = (h264EncInst_t *)h264EncInst;
    IH264VENC_Params *ext_params    = &(inst->extn_params);
    IVIDENC_Params *params        = &ext_params->videncParams;

    params->size                   = sizeof(IH264VENC_Params);

    if(codecParams != NULL) {
      memcpy(ext_params,codecParams,sizeof(IH264VENC_Params));
    } else {
      params->encodingPreset         = 3;
      params->rateControlPreset      = 1;
      params->maxFrameRate           = 30000;
      params->dataEndianness         = 1; 
      params->maxInterFrameInterval  = 0; 
      params->inputChromaFormat      = 1;
      params->inputContentType       = 0;
      ext_params->profileIdc         = 66;
      ext_params->rcAlgo             = 1;
      ext_params->searchRange        = 64;
      ext_params->mcVidEncParams    = &(inst->mcParams);

      if(hdResolution == 1080)
      {
          params->maxHeight              = 1088;
          params->maxWidth               = 1920;
          params->maxBitRate             = 12000000;
          ext_params->levelIdc           = IH264_LEVEL_40;
      }
      else if(hdResolution == 720)
      {
          params->maxHeight              = 720;
          params->maxWidth               = 1280;
          params->maxBitRate             = 6000000;
          ext_params->levelIdc           = IH264_LEVEL_31;
      }
      else if(hdResolution == 288)
      {
          params->maxHeight				= 288;
          params->maxWidth				= 352;
          params->maxBitRate			= 2500000;
          // params->maxBitRate			= 512000;

          ext_params->searchRange			= 16;
          ext_params->levelIdc           = IH264_LEVEL_20;
      }

    }

    return;
}

extern void shipOutNal ( XDAS_Int32    *pNalu, XDAS_Int32    *pPacketSizeInBytes);
void h264SetDynamicParams(void *h264EncInst, void *dynParams)
{
    h264EncInst_t *inst                  = (h264EncInst_t *)h264EncInst;
    IH264VENC_DynamicParams *extn_dynpar = &inst->extn_dynamicParams;
    IVIDENC_DynamicParams *dynamicParams = &extn_dynpar->videncDynamicParams;
    IVIDENC_Params *params = (IVIDENC_Params *)dynParams;

    memset((void *)dynamicParams, 0, sizeof(IH264VENC_DynamicParams));
    dynamicParams->size            = sizeof(IH264VENC_DynamicParams);
    dynamicParams->inputHeight     = params->maxHeight    ;       
    dynamicParams->inputWidth      = params->maxWidth     ;        
    dynamicParams->refFrameRate    = params->maxFrameRate ;      
    dynamicParams->targetFrameRate = params->maxFrameRate ;   
    dynamicParams->targetBitRate   = params->maxBitRate   ; 
    dynamicParams->intraFrameInterval = 30; 
    dynamicParams->generateHeader  = 0;   
    dynamicParams->captureWidth    = 0;   
    dynamicParams->forceIFrame     = IVIDEO_I_FRAME;
    
    extn_dynpar->qpIntra         = 28;
    extn_dynpar->qpInter         = 28;
    extn_dynpar->qpMax           = 51;
    extn_dynpar->qpMin           = 0;
    extn_dynpar->lfDisableIdc    = 0;
    extn_dynpar->quartPelDisable = 0;
    extn_dynpar->airMbPeriod     = 0;
    extn_dynpar->maxBytesPerSlice           = 0;
    extn_dynpar->sliceRefreshRowStartNumber = 0;
    extn_dynpar->sliceRefreshRowNumber      = 0;
    extn_dynpar->filterOffsetA    = 0;
    extn_dynpar->filterOffsetB    = 0;
    extn_dynpar->log2MaxFNumMinus4    = 0;
    extn_dynpar->chromaQPIndexOffset  = 0;
    extn_dynpar->constrainedIntraPredEnable    = 0;
    extn_dynpar->picOrderCountType    = 0;
    extn_dynpar->mvDataEnable         = 0;
    extn_dynpar->streamFormat         = IH264_BYTE_STREAM;
    extn_dynpar->intraRefreshMethod   = 0;
    extn_dynpar->pfNalUnitCallBack    = shipOutNal;
    
    extn_dynpar->top_slice_line    = inst->topSliceLine;
    extn_dynpar->bottom_slice_line = inst->bottomSliceLine;
    
    extn_dynpar->Intra_QP_modulation    = 1;
    extn_dynpar->Max_delay    = 3;
    extn_dynpar->idrEnable    = 1;

    if(hdResolution == 1080)
    {
        extn_dynpar->maxMBsPerSlice  = 8160;
        extn_dynpar->maxMVperMB           = 4;
        extn_dynpar->intra4x4EnableIdc    = 1;
        extn_dynpar->hierCodingEnable     = 0;
    }
    else if(hdResolution == 720 || hdResolution == 288)
    {
        extn_dynpar->maxMBsPerSlice  = 0;
        extn_dynpar->maxMVperMB           = 1;
        extn_dynpar->intra4x4EnableIdc    = 0;
        extn_dynpar->hierCodingEnable     = 1;
        extn_dynpar->numSliceASO       = 0;
        extn_dynpar->numSliceGroups    = 0;
        extn_dynpar->sliceGroupMapType = 0;
        extn_dynpar->sliceGroupChangeDirectionFlag  = 0;
        extn_dynpar->sliceGroupChangeRate   = 0;
        extn_dynpar->sliceGroupChangeCycle  = 3;
    }

    return;
}

void h264SetMcParams(void *h264EncInst, IVIDMC_t *params, XDAS_UInt32 topSliceLine, XDAS_UInt32 bottomSliceLine)
{
    h264EncInst_t *inst    = (h264EncInst_t *)h264EncInst;
    memcpy(&(inst->mcParams), params, sizeof(IVIDMC_t));
    inst->topSliceLine    = topSliceLine;
    inst->bottomSliceLine = bottomSliceLine;
    return;
}

void *h264GetIresFxns(void) {
   return((void *)&H264VENC_TI_IRES); /* When integrating with FC-based codec library*/
}

/* nothing past this point */
