diff --git a/mcfw/src_bios6/links_m3vpss/dei/deiLink_drv.c b/mcfw/src_bios6/links_m3vpss/dei/deiLink_drv.c index ce44dc9..6a4c402 100755 --- a/mcfw/src_bios6/links_m3vpss/dei/deiLink_drv.c +++ b/mcfw/src_bios6/links_m3vpss/dei/deiLink_drv.c @@ -15,6 +15,47 @@ static Int32 DeiLink_drvReleaseContextField(DeiLink_Obj * pObj); #endif /* TI_814X_BUILD */ +char *gSCCoeffStr[] = +{ + "VPS_SC_DS_SET_3_16", + /**< Coefficient for the down sampling (3/16) < Factor <= (4/16). */ + "VPS_SC_DS_SET_4_16", + /**< Coefficient for the down sampling (4/16) < Factor <= (5/16). */ + "VPS_SC_DS_SET_5_16", + /**< Coefficient for the down sampling (5/16) < Factor <= (6/16). */ + "VPS_SC_DS_SET_6_16", + /**< Coefficient for the down sampling (6/16) < Factor <= (7/16). */ + "VPS_SC_DS_SET_7_16", + /**< Coefficient for the down sampling (7/16) < Factor <= (8/16). */ + "VPS_SC_DS_SET_8_16", + /**< Coefficient for the down sampling (8/16) < Factor <= (9/16). */ + "VPS_SC_DS_SET_9_16", + /**< Coefficient for the down sampling (9/16) < Factor <= (10/16). */ + "VPS_SC_DS_SET_10_16", + /**< Coefficient for the down sampling (10/16) < Factor <= (11/16). */ + "VPS_SC_DS_SET_11_16", + /**< Coefficient for the down sampling (11/16) < Factor <= (12/16). */ + "VPS_SC_DS_SET_12_16", + /**< Coefficient for the down sampling (12/16) < Factor <= (13/16). */ + "VPS_SC_DS_SET_13_16", + /**< Coefficient for the down sampling (13/16) < Factor <= (14/16). */ + "VPS_SC_DS_SET_14_16", + /**< Coefficient for the down sampling (14/16) < Factor <= (15/16). */ + "VPS_SC_DS_SET_15_16", + /**< Coefficient for the down sampling (15/16) < Factor. */ + "VPS_SC_US_SET", + /**< Coefficient set for the upsampling. Includes horizontal, vertical + and both chroma and luma up sampling. */ + "VPS_SC_SET_1_1", + /**< Coefficient set for one-to-one scenario, when scaler is not in + bypass. */ + "VPS_SC_SET_MAX", + /**< Should be the last value of this enumeration. + Will be used by driver for validating the input parameters. */ +}; + +static +Int32 DeiLink_drvSelectScCoeffs (DeiLink_Obj * pObj); static inline UInt32 DeiLink_mapQueIdToStrmId(UInt32 queId) { @@ -727,6 +768,193 @@ Int32 DeiLink_drvFreeCtxMem(DeiLink_Obj * pObj) return (retVal); } +static +UInt32 DeiLink_drvMapOutIdToScId(UInt32 outId) +{ + UInt32 scId; + + switch(outId) + { + case DEI_LINK_OUT_QUE_DEI_SC: + case DEI_LINK_OUT_QUE_DEI_SC_SECONDARY_OUT: + case DEI_LINK_OUT_QUE_DEI_SC_TERTIARY_OUT: + scId = VPS_M2M_DEI_SCALAR_ID_DEI_SC; + break; + case DEI_LINK_OUT_QUE_VIP_SC: + case DEI_LINK_OUT_QUE_VIP_SC_SECONDARY_OUT: + scId = VPS_M2M_DEI_SCALAR_ID_VIP_SC; + break; + default: + UTILS_assert(FALSE); + } + return scId; +} + +static +Int32 DeiLink_drvGetScCoeffs (UInt32 inW,UInt32 inH, UInt32 outW, UInt32 outH, struct DeiScCoeffs *coeffs) +{ + UInt32 numerator, denominator; + Vps_ScCoeffSet coeffId_v, coeffId_h; + + coeffs->horz_coeff = VPS_SC_US_SET; + coeffs->vert_coeff = VPS_SC_US_SET; + + /* This is an example of selecting scaling coefficients + + Need to apply the below co-effs todo antiflicker with downscaling / upscaling + + VPS_SC_US_SET - 1x1 + VPS_SC_DS_SET_4_16 - for other layouts + + Selecting scaling co-eff based on vertical resolution. + Assuming horizontal scaling will be proportionate to vertical scaling. + + Selecting co-effs based on SC done for WIN0. + Assuming WIN0 scaling is same as other window's OR WIN0 is bigger / primary window. + */ + + + denominator = 16; + /* find best matching scaling co-effs */ + if (outH >= inH) + { + coeffId_v = VPS_SC_US_SET; + } + else + { + numerator = 15; + for (coeffId_v = VPS_SC_DS_SET_15_16 ; + coeffId_v > VPS_SC_DS_SET_3_16 ; coeffId_v --) + { + if ((outH*denominator) > (inH*numerator)) + break; + numerator --; + } + } + if (outH == inH) + { + coeffId_v = VPS_SC_SET_1_1; + } + + if (outW >= inW) + { + coeffId_h = VPS_SC_US_SET; + } + else + { + numerator = 15; + for (coeffId_h = VPS_SC_DS_SET_15_16 ; + coeffId_h > VPS_SC_DS_SET_3_16 ; coeffId_h --) + { + if ((outW*denominator) > (inW*numerator)) + break; + numerator --; + } + } + if (outW == inW) + { + coeffId_h = VPS_SC_SET_1_1; + } + coeffs->horz_coeff = coeffId_h; + coeffs->vert_coeff = coeffId_v; + return FVID2_SOK; +} + +static +Int32 DeiLink_drvSelectScCoeffs (DeiLink_Obj * pObj) +{ + UInt32 outId,chId; + struct DeiScCoeffs coeff; + UInt32 scId; + + pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].horz_coeff = VPS_SC_SET_MAX; + pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].vert_coeff = VPS_SC_SET_MAX; + pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].horz_coeff = VPS_SC_SET_MAX; + pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].vert_coeff = VPS_SC_SET_MAX; + + for (outId = 0; outId < DEI_LINK_MAX_OUT_QUE; outId++) + { + if (pObj->createArgs.enableOut[outId]) + { + scId = DeiLink_drvMapOutIdToScId(outId); + for (chId = 0; chId < pObj->inQueInfo.numCh; chId++) + { + UInt32 inH, outH, inW, outW; + + inW = pObj->inQueInfo.chInfo[chId].width; + inH = pObj->inQueInfo.chInfo[chId].height; + outW = pObj->chObj[chId].deiRtOutFrmPrm[outId].width; + outH = pObj->chObj[chId].deiRtOutFrmPrm[outId].height; + if (pObj->createArgs.enableDeiForceBypass == FALSE) + { + inH *= 2; + } + Vps_printf("%d:DEI:Resolution LinkId[0x%x],ChId[%d],inW[%d],inH[%d],outW[%d],outH[%d]", + Utils_getCurTimeInMsec(),pObj->linkId,chId,inW,inH,outW,outH); + scId = DeiLink_drvMapOutIdToScId(outId); + DeiLink_drvGetScCoeffs(inW,inH,outW,outH,&coeff); + if (pObj->scCoeff[scId].horz_coeff != VPS_SC_US_SET) + { + pObj->scCoeff[scId].horz_coeff = coeff.horz_coeff; + } + if (pObj->scCoeff[scId].vert_coeff != VPS_SC_US_SET) + { + pObj->scCoeff[scId].vert_coeff = coeff.vert_coeff; + } + } + } + } + if ((pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].horz_coeff != VPS_SC_SET_MAX) + && + (pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].vert_coeff != VPS_SC_SET_MAX)) + { + Int32 retVal; + Vps_ScCoeffParams coeffPrms; + + Vps_printf("%d:DEI:ScalerCoeff LinkId[0x%x],DEI_SC :HorzCoeff:%s,VertCoeff:%s", + Utils_getCurTimeInMsec(), + pObj->linkId, + gSCCoeffStr[pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].horz_coeff], + gSCCoeffStr[pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].vert_coeff]); + + coeffPrms.hScalingSet = pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].horz_coeff; + coeffPrms.vScalingSet = pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_DEI_SC].vert_coeff; + coeffPrms.coeffPtr = NULL; + coeffPrms.scalarId = VPS_M2M_DEI_SCALAR_ID_DEI_SC; + + /* Program DEI scalar coefficient - Always used */ + retVal = FVID2_control(pObj->fvidHandle, + IOCTL_VPS_SET_COEFFS, &coeffPrms, NULL); + UTILS_assert(FVID2_SOK == retVal); + } + + if ((pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].horz_coeff != VPS_SC_SET_MAX) + && + (pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].vert_coeff != VPS_SC_SET_MAX)) + { + Int32 retVal; + Vps_ScCoeffParams coeffPrms; + + Vps_printf("%d:DEI:ScalerCoeff LinkId[0x%x],VIP_SC :HorzCoeff:%s,VertCoeff:%s", + Utils_getCurTimeInMsec(), + pObj->linkId, + gSCCoeffStr[pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].horz_coeff], + gSCCoeffStr[pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].vert_coeff]); + + coeffPrms.hScalingSet = pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].horz_coeff; + coeffPrms.vScalingSet = pObj->scCoeff[VPS_M2M_DEI_SCALAR_ID_VIP_SC].vert_coeff; + coeffPrms.coeffPtr = NULL; + coeffPrms.scalarId = VPS_M2M_DEI_SCALAR_ID_VIP_SC; + + /* Program DEI scalar coefficient - Always used */ + retVal = FVID2_control(pObj->fvidHandle, + IOCTL_VPS_SET_COEFFS, &coeffPrms, NULL); + UTILS_assert(FVID2_SOK == retVal); + } + return FVID2_SOK; + +} + Int32 DeiLink_drvSetScCoeffs(DeiLink_Obj * pObj, Bool loadAll) { Int32 retVal = FVID2_SOK; @@ -1158,6 +1386,7 @@ Int32 DeiLink_drvCreate(DeiLink_Obj * pObj, DeiLink_CreateParams * pPrm) DeiLink_drvAllocCtxMem(pObj); DeiLink_drvSetScCoeffs(pObj, TRUE); + DeiLink_drvSelectScCoeffs(pObj); DeiLink_drvCreateReqObj(pObj); DeiLink_drvCreateDupObj(pObj); UTILS_MEMLOG_USED_END(pObj->memUsed); @@ -1331,7 +1560,7 @@ Int32 DeiLink_drvQueueFramesToChQue(DeiLink_Obj * pObj) return FVID2_SOK; } -Int32 DeiLink_drvUpdateInputRtPrm(DeiLink_Obj * pObj, FVID2_Frame *pInFrame, UInt32 chId) +Bool DeiLink_drvUpdateInputRtPrm(DeiLink_Obj * pObj, FVID2_Frame *pInFrame, UInt32 chId) { DeiLink_ChObj *pChObj; System_FrameInfo *pInFrameInfo; @@ -1339,6 +1568,9 @@ Int32 DeiLink_drvUpdateInputRtPrm(DeiLink_Obj * pObj, FVID2_Frame *pInFrame, UIn #ifdef TI_816X_BUILD Vps_PlatformCpuRev cpuRev; #endif + Bool rtParamsChanged; + + rtParamsChanged = FALSE; pChObj = &pObj->chObj[chId]; /* Monitor input resolution and configure parameters when change happens */ @@ -1402,11 +1634,12 @@ Int32 DeiLink_drvUpdateInputRtPrm(DeiLink_Obj * pObj, FVID2_Frame *pInFrame, UIn pInQueChInfo->height ); #endif + rtParamsChanged = TRUE; } } - return FVID2_SOK; + return rtParamsChanged; } Int32 DeiLink_drvMakeFrameLists(DeiLink_Obj * pObj, @@ -1428,6 +1661,7 @@ Int32 DeiLink_drvMakeFrameLists(DeiLink_Obj * pObj, FVID2_FrameList freeFrameList; UInt32 *outQueIdArray, numOutputs; System_FrameInfo *pInFrameInfo; + Bool rtParamsUpdated = FALSE; frameId = 0; freeFrameList.numFrames = 0; @@ -1519,7 +1753,8 @@ Int32 DeiLink_drvMakeFrameLists(DeiLink_Obj * pObj, pInFrameInfo = (System_FrameInfo *) pInFrame->appData; - DeiLink_drvUpdateInputRtPrm(pObj, pInFrame, chId); + if (DeiLink_drvUpdateInputRtPrm(pObj, pInFrame, chId)) + rtParamsUpdated = TRUE; pChObj->inFrameProcessCount++; @@ -1914,6 +2149,11 @@ Int32 DeiLink_drvMakeFrameLists(DeiLink_Obj * pObj, } } + if (rtParamsUpdated) + { + DeiLink_drvSelectScCoeffs(pObj); + } + inFrameList->numFrames = frameId; if(pObj->useOverridePrevFldBuf) diff --git a/mcfw/src_bios6/links_m3vpss/dei/deiLink_priv.h b/mcfw/src_bios6/links_m3vpss/dei/deiLink_priv.h index 3e3baaa..1c8461e 100755 --- a/mcfw/src_bios6/links_m3vpss/dei/deiLink_priv.h +++ b/mcfw/src_bios6/links_m3vpss/dei/deiLink_priv.h @@ -197,6 +197,10 @@ typedef struct { Bool enableDualVipOut; UInt32 numVipOutputs; DeiLink_DupObj dupObj; + struct DeiScCoeffs { + Vps_ScCoeffSet horz_coeff; + Vps_ScCoeffSet vert_coeff; + } scCoeff[VPS_M2M_DEI_SCALAR_ID_MAX]; } DeiLink_Obj;