shithub: openh264

Download patch

ref: 74130321859ece439a8edd04f44da84d1908a2f6
parent: cc81020875b1a19c595b5e46f7036edaca4381ac
author: Sijia Chen <[email protected]>
date: Tue May 20 10:06:31 EDT 2014

using WelsRound for all the double-int32_t conversion

--- a/codec/common/inc/macros.h
+++ b/codec/common/inc/macros.h
@@ -122,7 +122,7 @@
 #endif//WELS_FLOOR
 
 #ifndef WELS_ROUND
-#define WELS_ROUND(x)	((int32_t)(0.5f+(x)))
+#define WELS_ROUND(x)	((int32_t)(0.5+(x)))
 #endif//WELS_ROUND
 
 #define WELS_NON_ZERO_COUNT_AVERAGE(nC,nA,nB) {		\
--- a/codec/console/enc/src/welsenc.cpp
+++ b/codec/console/enc/src/welsenc.cpp
@@ -739,7 +739,7 @@
     if (!fseek (pFileYUV, 0, SEEK_END)) {
       int64_t i_size = ftell (pFileYUV);
       fseek (pFileYUV, 0, SEEK_SET);
-      iTotalFrameMax = WELS_MAX ((int32_t) (i_size / kiPicResSize), iTotalFrameMax);
+      iTotalFrameMax = WELS_MAX (WELS_ROUND (i_size / kiPicResSize), iTotalFrameMax);
     }
   } else {
     fprintf (stderr, "Unable to open source sequence file (%s), check corresponding path!\n",
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -127,10 +127,10 @@
 
     pWelsSvcRc->dSkipBufferRatio  = SKIP_RATIO;
 
-    pWelsSvcRc->iQpRangeUpperInFrame = QP_RANGE_UPPER_MODE1 - (int32_t) ((QP_RANGE_UPPER_MODE1 - QP_RANGE_MODE0) *
-                                       pWelsSvcRc->dRcVaryRatio + 0.5);
-    pWelsSvcRc->iQpRangeLowerInFrame = QP_RANGE_LOWER_MODE1 - (int32_t) ((QP_RANGE_LOWER_MODE1 - QP_RANGE_MODE0) *
-                                       pWelsSvcRc->dRcVaryRatio + 0.5);
+    pWelsSvcRc->iQpRangeUpperInFrame = QP_RANGE_UPPER_MODE1 - WELS_ROUND ((QP_RANGE_UPPER_MODE1 - QP_RANGE_MODE0) *
+                                       pWelsSvcRc->dRcVaryRatio);
+    pWelsSvcRc->iQpRangeLowerInFrame = QP_RANGE_LOWER_MODE1 - WELS_ROUND ((QP_RANGE_LOWER_MODE1 - QP_RANGE_MODE0) *
+                                       pWelsSvcRc->dRcVaryRatio);
 
     if (iMbWidth <= MB_WIDTH_THRESHOLD_90P) {
       pWelsSvcRc->iSkipQpValue = SKIP_QP_90P;
@@ -149,7 +149,7 @@
       iGomRowMode0 = GOM_ROW_MODE0_720P;
       iGomRowMode1 = GOM_ROW_MODE1_720P;
     }
-    iGomRowMode0 = iGomRowMode1 + (int32_t) ((iGomRowMode0 - iGomRowMode1) * pWelsSvcRc->dRcVaryRatio + 0.5);
+    iGomRowMode0 = iGomRowMode1 + WELS_ROUND ((iGomRowMode0 - iGomRowMode1) * pWelsSvcRc->dRcVaryRatio);
 
     pWelsSvcRc->iNumberMbGom   = iMbWidth * iGomRowMode0;
 
@@ -156,10 +156,10 @@
     pWelsSvcRc->iMinQp = GOM_MIN_QP_MODE;
     pWelsSvcRc->iMaxQp = GOM_MAX_QP_MODE;
 
-    pWelsSvcRc->iFrameDeltaQpUpper = LAST_FRAME_QP_RANGE_UPPER_MODE1 - (int32_t) ((LAST_FRAME_QP_RANGE_UPPER_MODE1 -
-                                     LAST_FRAME_QP_RANGE_UPPER_MODE0) * pWelsSvcRc->dRcVaryRatio + 0.5);
-    pWelsSvcRc->iFrameDeltaQpLower = LAST_FRAME_QP_RANGE_LOWER_MODE1 - (int32_t) ((LAST_FRAME_QP_RANGE_LOWER_MODE1 -
-                                     LAST_FRAME_QP_RANGE_LOWER_MODE0) * pWelsSvcRc->dRcVaryRatio + 0.5);
+    pWelsSvcRc->iFrameDeltaQpUpper = LAST_FRAME_QP_RANGE_UPPER_MODE1 - WELS_ROUND ((LAST_FRAME_QP_RANGE_UPPER_MODE1 -
+                                     LAST_FRAME_QP_RANGE_UPPER_MODE0) * pWelsSvcRc->dRcVaryRatio);
+    pWelsSvcRc->iFrameDeltaQpLower = LAST_FRAME_QP_RANGE_LOWER_MODE1 - WELS_ROUND ((LAST_FRAME_QP_RANGE_LOWER_MODE1 -
+                                     LAST_FRAME_QP_RANGE_LOWER_MODE0) * pWelsSvcRc->dRcVaryRatio);
 
     pWelsSvcRc->iSkipFrameNum = 0;
     pWelsSvcRc->iGomSize = (pWelsSvcRc->iNumberMbFrame + pWelsSvcRc->iNumberMbGom - 1) / pWelsSvcRc->iNumberMbGom;
@@ -213,7 +213,7 @@
   const int32_t kiGopSize	= (1 << pDLayerParam->iDecompositionStages);
   const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId;
   double input_dBitsPerFrame = pDLayerParam->iSpatialBitrate / pDLayerParam->fInputFrameRate;
-  const int32_t kiGopBits	= (int32_t) (input_dBitsPerFrame * kiGopSize);
+  const int32_t kiGopBits	= WELS_ROUND (input_dBitsPerFrame * kiGopSize);
   int32_t i;
 
   pWelsSvcRc->iBitRate   = pDLayerParam->iSpatialBitrate;
@@ -225,16 +225,16 @@
 
   for (i = 0; i <= kiHighestTid; i++) {
     const double kdConstraitBits = kiGopBits * pTOverRc[i].dTlayerWeight;
-    pTOverRc[i].iMinBitsTl = (int32_t) (kdConstraitBits * dMinBitsRatio);
-    pTOverRc[i].iMaxBitsTl = (int32_t) (kdConstraitBits * dMaxBitsRatio);
+    pTOverRc[i].iMinBitsTl = WELS_ROUND (kdConstraitBits * dMinBitsRatio);
+    pTOverRc[i].iMaxBitsTl = WELS_ROUND (kdConstraitBits * dMaxBitsRatio);
   }
   //When bitrate is changed, pBuffer size should be updated
-  pWelsSvcRc->iBufferSizeSkip = (int32_t) (pWelsSvcRc->iBitRate * pWelsSvcRc->dSkipBufferRatio);
-  pWelsSvcRc->iBufferSizePadding = (int32_t) (pWelsSvcRc->iBitRate * PADDING_BUFFER_RATIO);
+  pWelsSvcRc->iBufferSizeSkip = WELS_ROUND (pWelsSvcRc->iBitRate * pWelsSvcRc->dSkipBufferRatio);
+  pWelsSvcRc->iBufferSizePadding = WELS_ROUND (pWelsSvcRc->iBitRate * PADDING_BUFFER_RATIO);
 
   //change remaining bits
   if (pWelsSvcRc->dBitsPerFrame > 0.1)
-    pWelsSvcRc->iRemainingBits = (int32_t) (pWelsSvcRc->iRemainingBits * input_dBitsPerFrame / pWelsSvcRc->dBitsPerFrame);
+    pWelsSvcRc->iRemainingBits = WELS_ROUND (pWelsSvcRc->iRemainingBits * input_dBitsPerFrame / pWelsSvcRc->dBitsPerFrame);
   pWelsSvcRc->dBitsPerFrame = input_dBitsPerFrame;
 }
 
@@ -245,7 +245,7 @@
   SRCTemporal* pTOverRc		= pWelsSvcRc->pTemporalOverRc;
   const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId;
 
-  pWelsSvcRc->iRemainingBits = (int32_t) (VGOP_SIZE * pWelsSvcRc->dBitsPerFrame);
+  pWelsSvcRc->iRemainingBits = WELS_ROUND (VGOP_SIZE * pWelsSvcRc->dBitsPerFrame);
   pWelsSvcRc->dRemainingWeights = pWelsSvcRc->iGopNumberInVGop;
 
   pWelsSvcRc->iFrameCodedInVGop = 0;
@@ -325,9 +325,9 @@
     }
     int32_t iFrameInVGop = pWelsSvcRc->iFrameCodedInVGop + pWelsSvcRc->iSkipFrameInVGop;
     if (0 != iFrameInVGop)
-      iVGopBitrate = (int32_t) (iTotalBits / iFrameInVGop * pWelsSvcRc->fFrameRate);
+      iVGopBitrate = WELS_ROUND (iTotalBits / iFrameInVGop * pWelsSvcRc->fFrameRate);
 #ifdef _TEST_TEMP_Rc_
-    fprintf (fp_vgop, "%d\n", (int32_t) ((double)iTotalBits / iFrameInVGop));
+    fprintf (fp_vgop, "%d\n", WELS_ROUND ((double)iTotalBits / iFrameInVGop));
 #endif
     WelsLog (pEncCtx, WELS_LOG_INFO, "[Rc] VGOPbitrate%d: %d \n", kiDid, iVGopBitrate);
     if (iTotalBits > 0) {
@@ -400,7 +400,7 @@
       break;
   }
   pWelsSvcRc->iInitialQp = dInitialQPArray[iBppIndex][i];
-  pWelsSvcRc->iInitialQp = (int32_t)WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP);
+  pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP);
   pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
   pWelsSvcRc->dQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
   pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
@@ -410,11 +410,12 @@
   SWelsSvcRc* pWelsSvcRc			= &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   //obtain the idr qp using previous idr complexity
   if (pWelsSvcRc->iNumberMbFrame != pWelsSvcRc->iIntraMbCount) {
-    pWelsSvcRc->iIntraComplexity = (int32_t) ((double)pWelsSvcRc->iIntraComplexity * pWelsSvcRc->iNumberMbFrame /
-                                   pWelsSvcRc->iIntraMbCount + 0.5);
+    pWelsSvcRc->iIntraComplexity = WELS_ROUND ((double)pWelsSvcRc->iIntraComplexity * pWelsSvcRc->iNumberMbFrame /
+                                   pWelsSvcRc->iIntraMbCount);
   }
-  pWelsSvcRc->iInitialQp = (int32_t)RcConvertQStep2Qp ((double)pWelsSvcRc->iIntraComplexity / pWelsSvcRc->iTargetBits);
-  pWelsSvcRc->iInitialQp = (int32_t)WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP);
+  pWelsSvcRc->iInitialQp = WELS_ROUND (RcConvertQStep2Qp ((double)pWelsSvcRc->iIntraComplexity /
+                                       pWelsSvcRc->iTargetBits));
+  pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP);
   pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
   pWelsSvcRc->dQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp);
   pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
@@ -451,7 +452,7 @@
     pWelsSvcRc->iLastCalculatedQScale = iLumaQp;
 
     if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
-      iLumaQp = (int32_t) (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
+      iLumaQp = WELS_ROUND (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
     }
 
     pEncCtx->iGlobalQp = iLumaQp;
@@ -462,7 +463,7 @@
     dCmplxRatio = WELS_CLIP3 (dCmplxRatio, 1.0 - FRAME_CMPLX_RATIO_RANGE, 1.0 + FRAME_CMPLX_RATIO_RANGE);
 
     pWelsSvcRc->dQStep = pTOverRc->dLinearCmplx * dCmplxRatio / pWelsSvcRc->iTargetBits;
-    iLumaQp = (int32_t) (RcConvertQStep2Qp (pWelsSvcRc->dQStep) + 0.5);
+    iLumaQp = WELS_ROUND (RcConvertQStep2Qp (pWelsSvcRc->dQStep));
 
     //limit QP
     int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1;
@@ -487,10 +488,10 @@
 #ifndef _NOT_USE_AQ_FOR_TEST_
   if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) {
 
-    iLumaQp = (int32_t) (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
+    iLumaQp = WELS_ROUND (iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp);
 
     if (pEncCtx->pSvcParam->iRCMode != RC_LOW_BW_MODE)
-      iLumaQp = (int32_t)WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
+      iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
 
   }
 #endif
@@ -510,7 +511,7 @@
     pSOverRc->iEndMbSlice		+= (pCurSliceCtx->pCountMbNumInSlice[i] - 1);
     pSOverRc->iTotalQpSlice	= 0;
     pSOverRc->iTotalMbSlice	= 0;
-    pSOverRc->iTargetBitsSlice = (int32_t) (kdBitsPerMb * pCurSliceCtx->pCountMbNumInSlice[i]);
+    pSOverRc->iTargetBitsSlice = WELS_ROUND (kdBitsPerMb * pCurSliceCtx->pCountMbNumInSlice[i]);
     pSOverRc->iFrameBitsSlice	= 0;
     pSOverRc->iGomBitsSlice	= 0;
     ++ pSOverRc;
@@ -524,10 +525,10 @@
   pWelsSvcRc->iCurrentBitsLevel = BITS_NORMAL;
   //allocate bits
   if (pEncCtx->eSliceType == I_SLICE) {
-    pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO);
+    pWelsSvcRc->iTargetBits = WELS_ROUND (pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO);
   } else {
-    pWelsSvcRc->iTargetBits = (int32_t) (pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight /
-                                         pWelsSvcRc->dRemainingWeights);
+    pWelsSvcRc->iTargetBits = WELS_ROUND (pWelsSvcRc->iRemainingBits * pTOverRc->dTlayerWeight /
+                                          pWelsSvcRc->dRemainingWeights);
     if ((pWelsSvcRc->iTargetBits <= 0) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) {
       pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED;
     } else if ((pWelsSvcRc->iTargetBits <= pTOverRc->iMinBitsTl) && (pEncCtx->pSvcParam->iRCMode == RC_LOW_BW_MODE)) {
@@ -625,7 +626,7 @@
       dAllocateBits = (double)iLeftBits * pWelsSvcRc_Base->pCurrentFrameGomSad[kiComplexityIndex + 1] / iSumSad;
 
   }
-  pSOverRc->iGomTargetBits = int32_t (dAllocateBits + 0.5);
+  pSOverRc->iGomTargetBits = WELS_ROUND (dAllocateBits);
 }
 
 
@@ -665,11 +666,11 @@
 void   RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) {
   SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   SRCTemporal* pTOverRc		= pWelsSvcRc->pTemporalOverRc;
-  const int32_t kiOutputBits = (int32_t) (pWelsSvcRc->dBitsPerFrame + 0.5);
+  const int32_t kiOutputBits = WELS_ROUND (pWelsSvcRc->dBitsPerFrame);
   //condition 1: whole pBuffer fullness
   pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
   //condition 2: VGOP bits constraint
-  const int32_t kiVGopBits = (int32_t) (pWelsSvcRc->dBitsPerFrame * VGOP_SIZE);
+  const int32_t kiVGopBits = WELS_ROUND (pWelsSvcRc->dBitsPerFrame * VGOP_SIZE);
   int32_t iVGopBitsPred = 0;
   for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++)
     iVGopBitsPred += pTOverRc[pWelsSvcRc->iTlOfFrames[i]].iMinBitsTl;
@@ -690,7 +691,7 @@
     pWelsSvcRc->iBufferFullnessSkip = 0;
 
   if (pEncCtx->iSkipFrameFlag == 1) {
-    pWelsSvcRc->iRemainingBits += (int32_t) (pWelsSvcRc->dBitsPerFrame + 0.5);
+    pWelsSvcRc->iRemainingBits += WELS_ROUND (pWelsSvcRc->dBitsPerFrame);
     pWelsSvcRc->iSkipFrameNum++;
     pWelsSvcRc->iSkipFrameInVGop++;
   }
@@ -698,8 +699,8 @@
 
 void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) {
   SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
-  const int32_t kiOutputBits = (int32_t) (pWelsSvcRc->dBitsPerFrame + 0.5);
-  const int32_t kiBufferThreshold = (int32_t) (PADDING_THRESHOLD * (-pWelsSvcRc->iBufferSizePadding));
+  const int32_t kiOutputBits = WELS_ROUND (pWelsSvcRc->dBitsPerFrame);
+  const int32_t kiBufferThreshold = WELS_ROUND (PADDING_THRESHOLD * (-pWelsSvcRc->iBufferSizePadding));
 
   pWelsSvcRc->iBufferFullnessPadding += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
 
@@ -736,7 +737,7 @@
       ++ pSOverRc;
     }
     if (iTotalMb > 0)
-      pWelsSvcRc->iAverageFrameQp = (int32_t) (1.0 * iTotalQp / iTotalMb + 0.5);
+      pWelsSvcRc->iAverageFrameQp = WELS_ROUND (1.0 * iTotalQp / iTotalMb);
     else
       pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
   } else {
@@ -753,7 +754,7 @@
 
   double dIntraCmplx = pWelsSvcRc->dQStep * pWelsSvcRc->iFrameDqBits;
   dIntraCmplx = (1.0 - iAlpha) * pWelsSvcRc->iIntraComplexity + iAlpha * dIntraCmplx;
-  pWelsSvcRc->iIntraComplexity = (int32_t) (dIntraCmplx + 0.5);
+  pWelsSvcRc->iIntraComplexity = WELS_ROUND (dIntraCmplx);
   pWelsSvcRc->iIntraMbCount = pWelsSvcRc->iNumberMbFrame;
 
   pWelsSvcRc->iIdrNum++;
@@ -775,8 +776,8 @@
   double iAlpha = 1.0 / (1 + pTOverRc->iPFrameNum);
   if (iAlpha < SMOOTH_FACTOR_MIN_VALUE)
     iAlpha = SMOOTH_FACTOR_MIN_VALUE;
-  pTOverRc->iFrameCmplxMean = (int32_t) ((1.0 - iAlpha) * pTOverRc->iFrameCmplxMean + iAlpha *
-                                         pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity + 0.5);
+  pTOverRc->iFrameCmplxMean = WELS_ROUND ((1.0 - iAlpha) * pTOverRc->iFrameCmplxMean + iAlpha *
+                                          pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity);
 
   pTOverRc->iPFrameNum++;
   if (pTOverRc->iPFrameNum > 255)
@@ -918,10 +919,10 @@
   pEncCtx->iGlobalQp	= RcCalculateCascadingQp (pEncCtx, kiQp);
 
   if (pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE)) {
-    pEncCtx->iGlobalQp = (int32_t)WELS_CLIP3 (pEncCtx->iGlobalQp -
-                         pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp, GOM_MIN_QP_MODE, GOM_MAX_QP_MODE);
-  }else{
-    pEncCtx->iGlobalQp = WELS_CLIP3(pEncCtx->iGlobalQp, FIX_MIN_QP_MODE, FIX_MAX_QP_MODE);
+    pEncCtx->iGlobalQp = WELS_CLIP3 (WELS_ROUND (pEncCtx->iGlobalQp -
+                                     pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp), GOM_MIN_QP_MODE, GOM_MAX_QP_MODE);
+  } else {
+    pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, FIX_MIN_QP_MODE, FIX_MAX_QP_MODE);
   }
 
   pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
@@ -937,8 +938,8 @@
   if (pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE)) {
     iLumaQp   = (int8_t)WELS_CLIP3 (iLumaQp +
                                     pEncCtx->pVaa->sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[pCurMb->iMbXY], GOM_MIN_QP_MODE, 51);
-  }else{
-    iLumaQp = WELS_CLIP3(iLumaQp,FIX_MIN_QP_MODE,FIX_MAX_QP_MODE);
+  } else {
+    iLumaQp = WELS_CLIP3 (iLumaQp, FIX_MIN_QP_MODE, FIX_MAX_QP_MODE);
   }
   pCurMb->uiChromaQp = g_kuiChromaQpTable[iLumaQp];
   pCurMb->uiLumaQp = iLumaQp;
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -236,11 +236,11 @@
 
   iSliceIdx	= 0;
   while (iSliceIdx + 1 < kiCountSliceNum) {
-    int32_t iNumMbAssigning = (int32_t) (kiCountNumMb * pSliceComplexRatio[iSliceIdx] + EPSN);
+    int32_t iNumMbAssigning = WELS_ROUND (kiCountNumMb * pSliceComplexRatio[iSliceIdx]);
 
     // GOM boundary aligned
     if (pCtx->pSvcParam->iRCMode != RC_OFF_MODE) {
-      iNumMbAssigning = (int32_t) (1.0f * iNumMbAssigning / iNumMbInEachGom + 0.5f + EPSN) * iNumMbInEachGom;
+      iNumMbAssigning = WELS_ROUND (1.0f * iNumMbAssigning / iNumMbInEachGom) * iNumMbInEachGom;
     }
 
     // make sure one GOM at least in each pSlice for safe
--- a/codec/encoder/core/src/svc_enc_slice_segment.cpp
+++ b/codec/encoder/core/src/svc_enc_slice_segment.cpp
@@ -276,7 +276,7 @@
 
   while (uiSliceIdx + 1 < kuiSliceNum) {
     // GOM boundary aligned
-    int32_t iNumMbAssigning = (int32_t) (1.0f * kiMbNumPerSlice / iGomSize + 0.5f + EPSN) * iGomSize;
+    int32_t iNumMbAssigning = WELS_ROUND (1.0f * kiMbNumPerSlice / iGomSize) * iGomSize;
 
     // make sure one GOM at least in each slice for safe
     if (iNumMbAssigning < iMinimalMbNum)
--- a/codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp
+++ b/codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp
@@ -101,7 +101,7 @@
   m_sComplexityAnalysisParam.iFrameComplexity = pVaaCalcResults->iFrameSad;
 
   if (m_sComplexityAnalysisParam.iCalcBgd) { //BGD control
-    m_sComplexityAnalysisParam.iFrameComplexity = (int32_t)GetFrameSadExcludeBackground (pSrcPixMap, pRefPixMap);
+    m_sComplexityAnalysisParam.iFrameComplexity = GetFrameSadExcludeBackground (pSrcPixMap, pRefPixMap);
   }
 }
 
--- a/codec/processing/src/downsample/downsample.h
+++ b/codec/processing/src/downsample/downsample.h
@@ -45,6 +45,7 @@
 #include "util.h"
 #include "WelsFrameWork.h"
 #include "IWelsVP.h"
+#include "macros.h"
 
 WELSVP_NAMESPACE_BEGIN
 
--- a/codec/processing/src/downsample/downsamplefuncs.cpp
+++ b/codec/processing/src/downsample/downsamplefuncs.cpp
@@ -73,8 +73,8 @@
                                        uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
   const uint32_t kuiScaleBitWidth = 16, kuiScaleBitHeight = 15;
   const uint32_t kuiScaleWidth = (1 << kuiScaleBitWidth), kuiScaleHeight = (1 << kuiScaleBitHeight);
-  int32_t fScalex = (int32_t) ((float)kiSrcWidth / (float)kiDstWidth * kuiScaleWidth);
-  int32_t fScaley = (int32_t) ((float)kiSrcHeight / (float)kiDstHeight * kuiScaleHeight);
+  int32_t fScalex = WELS_ROUND ((float)kiSrcWidth / (float)kiDstWidth * kuiScaleWidth);
+  int32_t fScaley = WELS_ROUND ((float)kiSrcHeight / (float)kiDstHeight * kuiScaleHeight);
   uint32_t x;
   int32_t iYInverse, iXInverse;
 
@@ -142,8 +142,8 @@
     uint8_t* pSrc, const int32_t kiSrcStride, const int32_t kiSrcWidth, const int32_t kiSrcHeight) {
   const int32_t kiScaleBit = 15;
   const int32_t kiScale = (1 << kiScaleBit);
-  int32_t iScalex = (int32_t) ((float)kiSrcWidth / (float)kiDstWidth * kiScale);
-  int32_t iScaley = (int32_t) ((float)kiSrcHeight / (float)kiDstHeight * kiScale);
+  int32_t iScalex = WELS_ROUND ((float)kiSrcWidth / (float)kiDstWidth * kiScale);
+  int32_t iScaley = WELS_ROUND ((float)kiSrcHeight / (float)kiDstHeight * kiScale);
   int64_t x;
   int32_t iYInverse, iXInverse;
 
--- a/test/api/decode_encode_test.cpp
+++ b/test/api/decode_encode_test.cpp
@@ -104,8 +104,8 @@
 }
 
 static const DecodeEncodeFileParam kFileParamArray[] = {
-  {"res/test_vd_1d.264", "028b5de8a9110223fc611d8a490c7bbb75d93974", 320, 192, 12.0f},
-  {"res/test_vd_rc.264", "31b4b12d0f91b5407f39ad6f8622cab1366bff2b", 320, 192, 12.0f},
+  {"res/test_vd_1d.264", "c73c1cc9b7dbab51f48cf41453073bb11337a445", 320, 192, 12.0f},
+  {"res/test_vd_rc.264", "593ab31fdc67cbad7373abbf7d08daf2771fb229", 320, 192, 12.0f},
 };
 
 INSTANTIATE_TEST_CASE_P(DecodeEncodeFile, DecodeEncodeTest,
--- a/test/api/encoder_test.cpp
+++ b/test/api/encoder_test.cpp
@@ -73,27 +73,27 @@
 static const EncodeFileParam kFileParamArray[] = {
   {
       "res/CiscoVT2people_320x192_12fps.yuv",
-      "8d4c87f48e8a679c1ccbf5fe1ee040fed4776b30", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1
+      "5fa8c8551133b7d7586f498121028d0e05a28e1d", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 1
   },
   {
       "res/CiscoVT2people_160x96_6fps.yuv",
-      "75334dc69d95b8ac2e0a52977bba0179df4f151f", CAMERA_VIDEO_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1
+      "c619645a7d46f8fade40d2b0e5ae01adc2e5c3ff", CAMERA_VIDEO_REAL_TIME, 160, 96, 6.0f, SM_SINGLE_SLICE, false, 1
   },
   {
       "res/Static_152_100.yuv",
-      "3467201e18a934e7f8c50f3c8f3e05f4334ad12c", CAMERA_VIDEO_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1
+      "68cde1b5f790213baab1a10d4a19a3618c138405", CAMERA_VIDEO_REAL_TIME, 152, 100, 6.0f, SM_SINGLE_SLICE, false, 1
   },
   {
       "res/CiscoVT2people_320x192_12fps.yuv",
-      "a57c7cc8a00ffe8d8ca5527a13af1683a41b5150", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1 // One slice per MB row
+      "d0d0a087451c2813e9b0fd61bc5b25a4e82519ac", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_ROWMB_SLICE, false, 1 // One slice per MB row
   },
   {
       "res/CiscoVT2people_320x192_12fps.yuv",
-      "bc9b203c1b031299df7981201c2af393994d876f", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1
+      "d3760e61e38af978d5b59232d8402448812d1540", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, true, 1
   },
   {
       "res/CiscoVT2people_320x192_12fps.yuv",
-      "ba81a0f1a14214e6d3c7f1608991b3ac97789370", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 2
+      "a74ae382356098fb5cce216a97f2c0cef00a0a9d", CAMERA_VIDEO_REAL_TIME, 320, 192, 12.0f, SM_SINGLE_SLICE, false, 2
   },
   {
       "res/CiscoVT2people_320x192_12fps.yuv",