Showing the changes to codec/encoder/core/src/ratectl.cpp (1 of 7 files). Show all
Unified · Split
| @@ -52,7 +52,7 @@ namespace WelsEnc { · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | #define VIRTUAL_BUFFER_LOW_TH 120 //*INT_MULTIPLY |
| 54 | 54 | #define VIRTUAL_BUFFER_HIGH_TH 180 //*INT_MULTIPLY |
| 55 | − | |
| 55 | + | |
| 56 | 56 | //#define _TEST_TEMP_RC_ |
| 57 | 57 | #ifdef _TEST_TEMP_RC_ |
| 58 | 58 | //#define _NOT_USE_AQ_FOR_TEST_ |
| @@ -61,855 +61,857 @@ FILE* fp_vgop = NULL; · 2 unmodified lines | ||
| 61 | 61 | #endif |
| 62 | 62 | #define _BITS_RANGE 0 |
| 63 | 63 | const int32_t g_kiQpToQstepTable[52] = { 63, 71, 79, 89, 100, 112, 126, 141, 159, 178, |
| 64 | − 200, 224, 252, 283, 317, 356, 400, 449, 504, 566, | |
| 65 | − 635, 713, 800, 898, 1008, 1131, 1270, 1425, 1600, 1796, | |
| 66 | − 2016, 2263, 2540, 2851, 3200, 3592, 4032, 4525, 5080, 5702, | |
| 67 | − 6400, 7184, 8063, 9051, 10159, 11404, 12800, 14368, 16127, 18102, | |
| 68 | − 20319, 22807 | |
| 69 | − }; //WELS_ROUND(INT_MULTIPLY*pow (2.0, (iQP - 4.0) / 6.0)) | |
| 70 | − | |
| 64 | +200, 224, 252, 283, 317, 356, 400, 449, 504, 566, | |
| 65 | +635, 713, 800, 898, 1008, 1131, 1270, 1425, 1600, 1796, | |
| 66 | +2016, 2263, 2540, 2851, 3200, 3592, 4032, 4525, 5080, 5702, | |
| 67 | +6400, 7184, 8063, 9051, 10159, 11404, 12800, 14368, 16127, 18102, | |
| 68 | +20319, 22807 | |
| 69 | +}; //WELS_ROUND(INT_MULTIPLY*pow (2.0, (iQP - 4.0) / 6.0)) | |
| 70 | + | |
| 71 | 71 | void RcInitLayerMemory (SWelsSvcRc* pWelsSvcRc, CMemoryAlign* pMA, const int32_t kiMaxTl) { |
| 72 | − const int32_t kiSliceNum = pWelsSvcRc->iSliceNum; | |
| 73 | − const int32_t kiGomSize = pWelsSvcRc->iGomSize; | |
| 74 | − const int32_t kiGomSizeD = kiGomSize * sizeof (double); | |
| 75 | − const int32_t kiGomSizeI = kiGomSize * sizeof (int32_t); | |
| 76 | − const int32_t kiLayerRcSize = kiGomSizeD + (kiGomSizeI * 3) + sizeof (SRCTemporal) * kiMaxTl; | |
| 77 | − uint8_t* pBaseMem = (uint8_t*)pMA->WelsMalloc (kiLayerRcSize, "pWelsSvcRc->pTemporalOverRc"); | |
| 78 | − | |
| 79 | − if (NULL == pBaseMem) | |
| 80 | − return; | |
| 81 | − | |
| 82 | − pWelsSvcRc->pTemporalOverRc = (SRCTemporal*)pBaseMem; | |
| 83 | − pBaseMem += sizeof (SRCTemporal) * kiMaxTl; | |
| 84 | − pWelsSvcRc->pGomComplexity = (double*)pBaseMem; | |
| 85 | − pBaseMem += kiGomSizeD; | |
| 86 | − pWelsSvcRc->pGomForegroundBlockNum = (int32_t*)pBaseMem; | |
| 87 | − pBaseMem += kiGomSizeI; | |
| 88 | − pWelsSvcRc->pCurrentFrameGomSad = (int32_t*)pBaseMem; | |
| 89 | − pBaseMem += kiGomSizeI; | |
| 90 | − pWelsSvcRc->pGomCost = (int32_t*)pBaseMem; | |
| 91 | − | |
| 92 | − pWelsSvcRc->pSlicingOverRc = (SRCSlicing*)pMA->WelsMalloc (sizeof (SRCSlicing) * kiSliceNum, "SlicingOverRC"); | |
| 72 | +const int32_t kiSliceNum = pWelsSvcRc->iSliceNum; | |
| 73 | +const int32_t kiGomSize = pWelsSvcRc->iGomSize; | |
| 74 | +const int32_t kiGomSizeD = kiGomSize * sizeof (double); | |
| 75 | +const int32_t kiGomSizeI = kiGomSize * sizeof (int32_t); | |
| 76 | +const int32_t kiLayerRcSize = kiGomSizeD + (kiGomSizeI * 3) + sizeof (SRCTemporal) * kiMaxTl; | |
| 77 | +uint8_t* pBaseMem = (uint8_t*)pMA->WelsMalloc (kiLayerRcSize, "pWelsSvcRc->pTemporalOverRc"); | |
| 78 | + | |
| 79 | +if (NULL == pBaseMem) | |
| 80 | +return; | |
| 81 | + | |
| 82 | +pWelsSvcRc->pTemporalOverRc = (SRCTemporal*)pBaseMem; | |
| 83 | +pBaseMem += sizeof (SRCTemporal) * kiMaxTl; | |
| 84 | +pWelsSvcRc->pGomComplexity = (double*)pBaseMem; | |
| 85 | +pBaseMem += kiGomSizeD; | |
| 86 | +pWelsSvcRc->pGomForegroundBlockNum = (int32_t*)pBaseMem; | |
| 87 | +pBaseMem += kiGomSizeI; | |
| 88 | +pWelsSvcRc->pCurrentFrameGomSad = (int32_t*)pBaseMem; | |
| 89 | +pBaseMem += kiGomSizeI; | |
| 90 | +pWelsSvcRc->pGomCost = (int32_t*)pBaseMem; | |
| 91 | + | |
| 92 | +pWelsSvcRc->pSlicingOverRc = (SRCSlicing*)pMA->WelsMalloc (sizeof (SRCSlicing) * kiSliceNum, "SlicingOverRC"); | |
| 93 | 93 | } |
| 94 | − | |
| 94 | + | |
| 95 | 95 | void RcFreeLayerMemory (SWelsSvcRc* pWelsSvcRc, CMemoryAlign* pMA) { |
| 96 | − if (pWelsSvcRc != NULL && pWelsSvcRc->pSlicingOverRc != NULL) { | |
| 97 | − pMA->WelsFree (pWelsSvcRc->pSlicingOverRc, "SlicingOverRC"); | |
| 98 | − pWelsSvcRc->pSlicingOverRc = NULL; | |
| 99 | − } | |
| 100 | − if (pWelsSvcRc != NULL && pWelsSvcRc->pTemporalOverRc != NULL) { | |
| 101 | − pMA->WelsFree (pWelsSvcRc->pTemporalOverRc, "pWelsSvcRc->pTemporalOverRc"); | |
| 102 | − pWelsSvcRc->pTemporalOverRc = NULL; | |
| 103 | − pWelsSvcRc->pGomComplexity = NULL; | |
| 104 | − pWelsSvcRc->pGomForegroundBlockNum = NULL; | |
| 105 | − pWelsSvcRc->pCurrentFrameGomSad = NULL; | |
| 106 | − pWelsSvcRc->pGomCost = NULL; | |
| 107 | − } | |
| 96 | +if (pWelsSvcRc != NULL && pWelsSvcRc->pSlicingOverRc != NULL) { | |
| 97 | +pMA->WelsFree (pWelsSvcRc->pSlicingOverRc, "SlicingOverRC"); | |
| 98 | +pWelsSvcRc->pSlicingOverRc = NULL; | |
| 108 | 99 | } |
| 109 | − | |
| 100 | +if (pWelsSvcRc != NULL && pWelsSvcRc->pTemporalOverRc != NULL) { | |
| 101 | +pMA->WelsFree (pWelsSvcRc->pTemporalOverRc, "pWelsSvcRc->pTemporalOverRc"); | |
| 102 | +pWelsSvcRc->pTemporalOverRc = NULL; | |
| 103 | +pWelsSvcRc->pGomComplexity = NULL; | |
| 104 | +pWelsSvcRc->pGomForegroundBlockNum = NULL; | |
| 105 | +pWelsSvcRc->pCurrentFrameGomSad = NULL; | |
| 106 | +pWelsSvcRc->pGomCost = NULL; | |
| 107 | +} | |
| 108 | +} | |
| 109 | + | |
| 110 | 110 | static inline int32_t RcConvertQp2QStep (int32_t iQP) { |
| 111 | − return g_kiQpToQstepTable[iQP]; | |
| 111 | +return g_kiQpToQstepTable[iQP]; | |
| 112 | 112 | } |
| 113 | 113 | static inline int32_t RcConvertQStep2Qp (int32_t iQpStep) { |
| 114 | − return WELS_ROUND ((6 * log (iQpStep * 1.0f / INT_MULTIPLY) / log (2.0) + 4.0)); | |
| 114 | +return WELS_ROUND ((6 * log (iQpStep * 1.0f / INT_MULTIPLY) / log (2.0) + 4.0)); | |
| 115 | 115 | } |
| 116 | − | |
| 116 | + | |
| 117 | 117 | void RcInitSequenceParameter (sWelsEncCtx* pEncCtx) { |
| 118 | − SWelsSvcRc* pWelsSvcRc = NULL; | |
| 119 | − SSpatialLayerConfig* pDLayerParam = NULL; | |
| 120 | − | |
| 121 | − int32_t j = 0; | |
| 122 | − int32_t iMbWidth = 0; | |
| 123 | − | |
| 124 | − bool bMultiSliceMode = false; | |
| 125 | − int32_t iGomRowMode0 = 1, iGomRowMode1 = 1; | |
| 118 | +SWelsSvcRc* pWelsSvcRc = NULL; | |
| 119 | +SSpatialLayerConfig* pDLayerParam = NULL; | |
| 120 | + | |
| 121 | +int32_t j = 0; | |
| 122 | +int32_t iMbWidth = 0; | |
| 123 | + | |
| 124 | +bool bMultiSliceMode = false; | |
| 125 | +int32_t iGomRowMode0 = 1, iGomRowMode1 = 1; | |
| 126 | 126 | #ifdef _TEST_TEMP_RC_ |
| 127 | − fp_test_rc = fopen ("testRC.dat", "w"); | |
| 128 | − fp_vgop = fopen ("vgop.dat", "w"); | |
| 127 | +fp_test_rc = fopen ("testRC.dat", "w"); | |
| 128 | +fp_vgop = fopen ("vgop.dat", "w"); | |
| 129 | 129 | #endif |
| 130 | − for (j = 0; j < pEncCtx->pSvcParam->iSpatialLayerNum; j++) { | |
| 131 | − SSliceCtx* pSliceCtx = &pEncCtx->pSliceCtxList[j]; | |
| 132 | − pWelsSvcRc = &pEncCtx->pWelsSvcRc[j]; | |
| 133 | − pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[j]; | |
| 134 | − iMbWidth = (pDLayerParam->iVideoWidth >> 4); | |
| 135 | − pWelsSvcRc->iNumberMbFrame = iMbWidth * (pDLayerParam->iVideoHeight >> 4); | |
| 136 | − pWelsSvcRc->iSliceNum = pSliceCtx->iSliceNumInFrame; | |
| 137 | − | |
| 138 | − pWelsSvcRc->iRcVaryPercentage = _BITS_RANGE; // % -- for temp | |
| 139 | − pWelsSvcRc->iRcVaryRatio = pWelsSvcRc->iRcVaryPercentage; | |
| 140 | − | |
| 141 | − pWelsSvcRc->iSkipBufferRatio = SKIP_RATIO; | |
| 142 | − | |
| 143 | − pWelsSvcRc->iQpRangeUpperInFrame = (QP_RANGE_UPPER_MODE1 * MAX_BITS_VARY_PERCENTAGE - (( | |
| 144 | − QP_RANGE_UPPER_MODE1 - QP_RANGE_MODE0) * | |
| 145 | − pWelsSvcRc->iRcVaryRatio)) / MAX_BITS_VARY_PERCENTAGE; | |
| 146 | − pWelsSvcRc->iQpRangeLowerInFrame = (QP_RANGE_LOWER_MODE1 * MAX_BITS_VARY_PERCENTAGE - (( | |
| 147 | − QP_RANGE_LOWER_MODE1 - QP_RANGE_MODE0) * | |
| 148 | − pWelsSvcRc->iRcVaryRatio)) / MAX_BITS_VARY_PERCENTAGE; | |
| 149 | − | |
| 150 | − if (iMbWidth <= MB_WIDTH_THRESHOLD_90P) { | |
| 151 | − pWelsSvcRc->iSkipQpValue = SKIP_QP_90P; | |
| 152 | − iGomRowMode0 = GOM_ROW_MODE0_90P; | |
| 153 | − iGomRowMode1 = GOM_ROW_MODE1_90P; | |
| 154 | − } else if (iMbWidth <= MB_WIDTH_THRESHOLD_180P) { | |
| 155 | − pWelsSvcRc->iSkipQpValue = SKIP_QP_180P; | |
| 156 | − iGomRowMode0 = GOM_ROW_MODE0_180P; | |
| 157 | − iGomRowMode1 = GOM_ROW_MODE1_180P; | |
| 158 | − } else if (iMbWidth <= MB_WIDTH_THRESHOLD_360P) { | |
| 159 | − pWelsSvcRc->iSkipQpValue = SKIP_QP_360P; | |
| 160 | − iGomRowMode0 = GOM_ROW_MODE0_360P; | |
| 161 | − iGomRowMode1 = GOM_ROW_MODE1_360P; | |
| 162 | − } else { | |
| 163 | − pWelsSvcRc->iSkipQpValue = SKIP_QP_720P; | |
| 164 | − iGomRowMode0 = GOM_ROW_MODE0_720P; | |
| 165 | − iGomRowMode1 = GOM_ROW_MODE1_720P; | |
| 166 | − } | |
| 167 | − iGomRowMode0 = iGomRowMode1 + ((iGomRowMode0 - iGomRowMode1) * pWelsSvcRc->iRcVaryRatio / MAX_BITS_VARY_PERCENTAGE); | |
| 168 | − | |
| 169 | − pWelsSvcRc->iNumberMbGom = iMbWidth * iGomRowMode0; | |
| 170 | − | |
| 171 | − pWelsSvcRc->iMinQp = GOM_MIN_QP_MODE; | |
| 172 | − pWelsSvcRc->iMaxQp = GOM_MAX_QP_MODE; | |
| 173 | − | |
| 174 | − pWelsSvcRc->iFrameDeltaQpUpper = LAST_FRAME_QP_RANGE_UPPER_MODE1 - ((LAST_FRAME_QP_RANGE_UPPER_MODE1 - | |
| 175 | − LAST_FRAME_QP_RANGE_UPPER_MODE0) * pWelsSvcRc->iRcVaryRatio / MAX_BITS_VARY_PERCENTAGE); | |
| 176 | − pWelsSvcRc->iFrameDeltaQpLower = LAST_FRAME_QP_RANGE_LOWER_MODE1 - ((LAST_FRAME_QP_RANGE_LOWER_MODE1 - | |
| 177 | − LAST_FRAME_QP_RANGE_LOWER_MODE0) * pWelsSvcRc->iRcVaryRatio / MAX_BITS_VARY_PERCENTAGE); | |
| 178 | − | |
| 179 | − pWelsSvcRc->iSkipFrameNum = 0; | |
| 180 | − pWelsSvcRc->iGomSize = (pWelsSvcRc->iNumberMbFrame + pWelsSvcRc->iNumberMbGom - 1) / pWelsSvcRc->iNumberMbGom; | |
| 181 | − | |
| 182 | − | |
| 183 | − RcInitLayerMemory (pWelsSvcRc, pEncCtx->pMemAlign, 1 + pEncCtx->pSvcParam->sDependencyLayers[j].iHighestTemporalId); | |
| 184 | − | |
| 185 | − bMultiSliceMode = ((SM_RASTER_SLICE == pDLayerParam->sSliceCfg.uiSliceMode) || | |
| 186 | − (SM_ROWMB_SLICE == pDLayerParam->sSliceCfg.uiSliceMode) || | |
| 187 | − (SM_DYN_SLICE == pDLayerParam->sSliceCfg.uiSliceMode)); | |
| 188 | − if (bMultiSliceMode) | |
| 189 | − pWelsSvcRc->iNumberMbGom = pWelsSvcRc->iNumberMbFrame; | |
| 190 | − } | |
| 130 | +for (j = 0; j < pEncCtx->pSvcParam->iSpatialLayerNum; j++) { | |
| 131 | +SSliceCtx* pSliceCtx = &pEncCtx->pSliceCtxList[j]; | |
| 132 | +pWelsSvcRc = &pEncCtx->pWelsSvcRc[j]; | |
| 133 | +pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[j]; | |
| 134 | +iMbWidth = (pDLayerParam->iVideoWidth >> 4); | |
| 135 | +pWelsSvcRc->iNumberMbFrame = iMbWidth * (pDLayerParam->iVideoHeight >> 4); | |
| 136 | +pWelsSvcRc->iSliceNum = pSliceCtx->iSliceNumInFrame; | |
| 137 | + | |
| 138 | +pWelsSvcRc->iRcVaryPercentage = _BITS_RANGE; // % -- for temp | |
| 139 | +pWelsSvcRc->iRcVaryRatio = pWelsSvcRc->iRcVaryPercentage; | |
| 140 | + | |
| 141 | +pWelsSvcRc->iSkipBufferRatio = SKIP_RATIO; | |
| 142 | + | |
| 143 | +pWelsSvcRc->iQpRangeUpperInFrame = (QP_RANGE_UPPER_MODE1 * MAX_BITS_VARY_PERCENTAGE - (( | |
| 144 | +QP_RANGE_UPPER_MODE1 - QP_RANGE_MODE0) * | |
| 145 | +pWelsSvcRc->iRcVaryRatio)) / MAX_BITS_VARY_PERCENTAGE; | |
| 146 | +pWelsSvcRc->iQpRangeLowerInFrame = (QP_RANGE_LOWER_MODE1 * MAX_BITS_VARY_PERCENTAGE - (( | |
| 147 | +QP_RANGE_LOWER_MODE1 - QP_RANGE_MODE0) * | |
| 148 | +pWelsSvcRc->iRcVaryRatio)) / MAX_BITS_VARY_PERCENTAGE; | |
| 149 | + | |
| 150 | +if (iMbWidth <= MB_WIDTH_THRESHOLD_90P) { | |
| 151 | +pWelsSvcRc->iSkipQpValue = SKIP_QP_90P; | |
| 152 | +iGomRowMode0 = GOM_ROW_MODE0_90P; | |
| 153 | +iGomRowMode1 = GOM_ROW_MODE1_90P; | |
| 154 | +} else if (iMbWidth <= MB_WIDTH_THRESHOLD_180P) { | |
| 155 | +pWelsSvcRc->iSkipQpValue = SKIP_QP_180P; | |
| 156 | +iGomRowMode0 = GOM_ROW_MODE0_180P; | |
| 157 | +iGomRowMode1 = GOM_ROW_MODE1_180P; | |
| 158 | +} else if (iMbWidth <= MB_WIDTH_THRESHOLD_360P) { | |
| 159 | +pWelsSvcRc->iSkipQpValue = SKIP_QP_360P; | |
| 160 | +iGomRowMode0 = GOM_ROW_MODE0_360P; | |
| 161 | +iGomRowMode1 = GOM_ROW_MODE1_360P; | |
| 162 | +} else { | |
| 163 | +pWelsSvcRc->iSkipQpValue = SKIP_QP_720P; | |
| 164 | +iGomRowMode0 = GOM_ROW_MODE0_720P; | |
| 165 | +iGomRowMode1 = GOM_ROW_MODE1_720P; | |
| 191 | 166 | } |
| 192 | − | |
| 193 | − | |
| 167 | +iGomRowMode0 = iGomRowMode1 + ((iGomRowMode0 - iGomRowMode1) * pWelsSvcRc->iRcVaryRatio / MAX_BITS_VARY_PERCENTAGE); | |
| 168 | + | |
| 169 | +pWelsSvcRc->iNumberMbGom = iMbWidth * iGomRowMode0; | |
| 170 | + | |
| 171 | +pWelsSvcRc->iMinQp = GOM_MIN_QP_MODE; | |
| 172 | +pWelsSvcRc->iMaxQp = GOM_MAX_QP_MODE; | |
| 173 | + | |
| 174 | +pWelsSvcRc->iFrameDeltaQpUpper = LAST_FRAME_QP_RANGE_UPPER_MODE1 - ((LAST_FRAME_QP_RANGE_UPPER_MODE1 - | |
| 175 | +LAST_FRAME_QP_RANGE_UPPER_MODE0) * pWelsSvcRc->iRcVaryRatio / MAX_BITS_VARY_PERCENTAGE); | |
| 176 | +pWelsSvcRc->iFrameDeltaQpLower = LAST_FRAME_QP_RANGE_LOWER_MODE1 - ((LAST_FRAME_QP_RANGE_LOWER_MODE1 - | |
| 177 | +LAST_FRAME_QP_RANGE_LOWER_MODE0) * pWelsSvcRc->iRcVaryRatio / MAX_BITS_VARY_PERCENTAGE); | |
| 178 | + | |
| 179 | +pWelsSvcRc->iSkipFrameNum = 0; | |
| 180 | +pWelsSvcRc->iGomSize = (pWelsSvcRc->iNumberMbFrame + pWelsSvcRc->iNumberMbGom - 1) / pWelsSvcRc->iNumberMbGom; | |
| 181 | + | |
| 182 | + | |
| 183 | +RcInitLayerMemory (pWelsSvcRc, pEncCtx->pMemAlign, 1 + pEncCtx->pSvcParam->sDependencyLayers[j].iHighestTemporalId); | |
| 184 | + | |
| 185 | +bMultiSliceMode = ((SM_RASTER_SLICE == pDLayerParam->sSliceCfg.uiSliceMode) || | |
| 186 | +(SM_ROWMB_SLICE == pDLayerParam->sSliceCfg.uiSliceMode) || | |
| 187 | +(SM_DYN_SLICE == pDLayerParam->sSliceCfg.uiSliceMode)); | |
| 188 | +if (bMultiSliceMode) | |
| 189 | +pWelsSvcRc->iNumberMbGom = pWelsSvcRc->iNumberMbFrame; | |
| 190 | +} | |
| 191 | +} | |
| 192 | + | |
| 193 | + | |
| 194 | 194 | void RcInitTlWeight (sWelsEncCtx* pEncCtx) { |
| 195 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 196 | − SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 197 | − SSpatialLayerInternal* pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId]; | |
| 198 | − const int32_t kiDecompositionStages = pDLayerParam->iDecompositionStages; | |
| 199 | − const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId; | |
| 200 | − | |
| 201 | − //Index 0:Virtual GOP size, Index 1:Frame rate | |
| 202 | − //double WeightArray[4][4] = { {1.0, 0, 0, 0}, {0.6, 0.4, 0, 0}, {0.4, 0.3, 0.15, 0}, {0.25, 0.15, 0.125, 0.0875}}; | |
| 203 | − int32_t iWeightArray[4][4] = { {2000, 0, 0, 0}, {1200, 800, 0, 0}, {800, 600, 300, 0}, {500, 300, 250, 175}}; // original*WEIGHT_MULTIPLY | |
| 204 | − const int32_t kiGopSize = (1 << kiDecompositionStages); | |
| 205 | − int32_t i, k, n; | |
| 206 | − | |
| 207 | − n = 0; | |
| 208 | − while (n <= kiHighestTid) { | |
| 209 | − pTOverRc[n].iTlayerWeight = iWeightArray[kiDecompositionStages][n]; | |
| 210 | − ++ n; | |
| 211 | − } | |
| 212 | − //Calculate the frame index for the current frame and its reference frame | |
| 213 | − for (n = 0; n < VGOP_SIZE; n += kiGopSize) { | |
| 214 | − pWelsSvcRc->iTlOfFrames[n] = 0; | |
| 215 | − for (i = 1; i <= kiDecompositionStages; i++) { | |
| 216 | − for (k = 1 << (kiDecompositionStages - i); k < kiGopSize; k += (kiGopSize >> (i - 1))) { | |
| 217 | − pWelsSvcRc->iTlOfFrames[k + n] = i; | |
| 218 | − } | |
| 219 | − } | |
| 220 | − } | |
| 221 | − pWelsSvcRc->iPreviousGopSize = kiGopSize; | |
| 222 | − pWelsSvcRc->iGopNumberInVGop = VGOP_SIZE / kiGopSize; | |
| 195 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 196 | +SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 197 | +SSpatialLayerInternal* pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId]; | |
| 198 | +const int32_t kiDecompositionStages = pDLayerParam->iDecompositionStages; | |
| 199 | +const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId; | |
| 200 | + | |
| 201 | +//Index 0:Virtual GOP size, Index 1:Frame rate | |
| 202 | +//double WeightArray[4][4] = { {1.0, 0, 0, 0}, {0.6, 0.4, 0, 0}, {0.4, 0.3, 0.15, 0}, {0.25, 0.15, 0.125, 0.0875}}; | |
| 203 | +int32_t iWeightArray[4][4] = { {2000, 0, 0, 0}, {1200, 800, 0, 0}, {800, 600, 300, 0}, {500, 300, 250, 175}}; // original*WEIGHT_MULTIPLY | |
| 204 | +const int32_t kiGopSize = (1 << kiDecompositionStages); | |
| 205 | +int32_t i, k, n; | |
| 206 | + | |
| 207 | +n = 0; | |
| 208 | +while (n <= kiHighestTid) { | |
| 209 | +pTOverRc[n].iTlayerWeight = iWeightArray[kiDecompositionStages][n]; | |
| 210 | +++ n; | |
| 223 | 211 | } |
| 224 | − | |
| 212 | +//Calculate the frame index for the current frame and its reference frame | |
| 213 | +for (n = 0; n < VGOP_SIZE; n += kiGopSize) { | |
| 214 | +pWelsSvcRc->iTlOfFrames[n] = 0; | |
| 215 | +for (i = 1; i <= kiDecompositionStages; i++) { | |
| 216 | +for (k = 1 << (kiDecompositionStages - i); k < kiGopSize; k += (kiGopSize >> (i - 1))) { | |
| 217 | +pWelsSvcRc->iTlOfFrames[k + n] = i; | |
| 218 | +} | |
| 219 | +} | |
| 220 | +} | |
| 221 | +pWelsSvcRc->iPreviousGopSize = kiGopSize; | |
| 222 | +pWelsSvcRc->iGopNumberInVGop = VGOP_SIZE / kiGopSize; | |
| 223 | +} | |
| 224 | + | |
| 225 | 225 | void RcUpdateBitrateFps (sWelsEncCtx* pEncCtx) { |
| 226 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 227 | − SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 228 | − | |
| 229 | − SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 230 | − SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId]; | |
| 231 | − const int32_t kiGopSize = (1 << pDLayerParamInternal->iDecompositionStages); | |
| 232 | − const int32_t kiHighestTid = pDLayerParamInternal->iHighestTemporalId; | |
| 233 | − int32_t input_iBitsPerFrame = WELS_ROUND (pDLayerParam->iSpatialBitrate * INT_MULTIPLY / | |
| 234 | − pDLayerParamInternal->fInputFrameRate); | |
| 235 | − const int32_t kiGopBits = WELS_DIV_ROUND (input_iBitsPerFrame * kiGopSize, INT_MULTIPLY); | |
| 236 | − int32_t i; | |
| 237 | − | |
| 238 | − pWelsSvcRc->iBitRate = pDLayerParam->iSpatialBitrate; | |
| 239 | − pWelsSvcRc->fFrameRate = pDLayerParamInternal->fInputFrameRate; | |
| 240 | − | |
| 241 | − int32_t iTargetVaryRange = FRAME_iTargetBits_VARY_RANGE * (MAX_BITS_VARY_PERCENTAGE - pWelsSvcRc->iRcVaryRatio); | |
| 242 | − int32_t iMinBitsRatio = (MAX_BITS_VARY_PERCENTAGE) * INT_MULTIPLY - iTargetVaryRange; | |
| 243 | − int32_t iMaxBitsRatio = (MAX_BITS_VARY_PERCENTAGE) * (INT_MULTIPLY + FRAME_iTargetBits_VARY_RANGE); | |
| 244 | − | |
| 245 | − for (i = 0; i <= kiHighestTid; i++) { | |
| 246 | − const int64_t kdConstraitBits = kiGopBits * pTOverRc[i].iTlayerWeight; | |
| 247 | − pTOverRc[i].iMinBitsTl = WELS_DIV_ROUND (kdConstraitBits * iMinBitsRatio, | |
| 248 | − INT_MULTIPLY * MAX_BITS_VARY_PERCENTAGE * WEIGHT_MULTIPLY); | |
| 249 | − pTOverRc[i].iMaxBitsTl = WELS_DIV_ROUND (kdConstraitBits * iMaxBitsRatio, | |
| 250 | − INT_MULTIPLY * MAX_BITS_VARY_PERCENTAGE * WEIGHT_MULTIPLY); | |
| 251 | − } | |
| 252 | − //When bitrate is changed, pBuffer size should be updated | |
| 253 | − pWelsSvcRc->iBufferSizeSkip = WELS_DIV_ROUND (pWelsSvcRc->iBitRate * pWelsSvcRc->iSkipBufferRatio, INT_MULTIPLY); | |
| 254 | − pWelsSvcRc->iBufferSizePadding = WELS_DIV_ROUND (pWelsSvcRc->iBitRate * PADDING_BUFFER_RATIO, INT_MULTIPLY); | |
| 255 | − | |
| 256 | − //change remaining bits | |
| 257 | − if (pWelsSvcRc->iBitsPerFrame > REMAIN_BITS_TH) | |
| 258 | − pWelsSvcRc->iRemainingBits = pWelsSvcRc->iRemainingBits * input_iBitsPerFrame / pWelsSvcRc->iBitsPerFrame; | |
| 259 | − pWelsSvcRc->iBitsPerFrame = input_iBitsPerFrame; | |
| 226 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 227 | +SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 228 | + | |
| 229 | +SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 230 | +SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId]; | |
| 231 | +const int32_t kiGopSize = (1 << pDLayerParamInternal->iDecompositionStages); | |
| 232 | +const int32_t kiHighestTid = pDLayerParamInternal->iHighestTemporalId; | |
| 233 | +int32_t input_iBitsPerFrame = WELS_ROUND (pDLayerParam->iSpatialBitrate * INT_MULTIPLY / | |
| 234 | +pDLayerParamInternal->fInputFrameRate); | |
| 235 | +const int32_t kiGopBits = WELS_DIV_ROUND (input_iBitsPerFrame * kiGopSize, INT_MULTIPLY); | |
| 236 | +int32_t i; | |
| 237 | + | |
| 238 | +pWelsSvcRc->iBitRate = pDLayerParam->iSpatialBitrate; | |
| 239 | +pWelsSvcRc->fFrameRate = pDLayerParamInternal->fInputFrameRate; | |
| 240 | + | |
| 241 | +int32_t iTargetVaryRange = FRAME_iTargetBits_VARY_RANGE * (MAX_BITS_VARY_PERCENTAGE - pWelsSvcRc->iRcVaryRatio); | |
| 242 | +int32_t iMinBitsRatio = (MAX_BITS_VARY_PERCENTAGE) * INT_MULTIPLY - iTargetVaryRange; | |
| 243 | +int32_t iMaxBitsRatio = (MAX_BITS_VARY_PERCENTAGE) * (INT_MULTIPLY + FRAME_iTargetBits_VARY_RANGE); | |
| 244 | + | |
| 245 | +for (i = 0; i <= kiHighestTid; i++) { | |
| 246 | +const int64_t kdConstraitBits = kiGopBits * pTOverRc[i].iTlayerWeight; | |
| 247 | +pTOverRc[i].iMinBitsTl = WELS_DIV_ROUND (kdConstraitBits * iMinBitsRatio, | |
| 248 | +INT_MULTIPLY * MAX_BITS_VARY_PERCENTAGE * WEIGHT_MULTIPLY); | |
| 249 | +pTOverRc[i].iMaxBitsTl = WELS_DIV_ROUND (kdConstraitBits * iMaxBitsRatio, | |
| 250 | +INT_MULTIPLY * MAX_BITS_VARY_PERCENTAGE * WEIGHT_MULTIPLY); | |
| 260 | 251 | } |
| 261 | − | |
| 262 | − | |
| 252 | +//When bitrate is changed, pBuffer size should be updated | |
| 253 | +pWelsSvcRc->iBufferSizeSkip = WELS_DIV_ROUND (pWelsSvcRc->iBitRate * pWelsSvcRc->iSkipBufferRatio, INT_MULTIPLY); | |
| 254 | +pWelsSvcRc->iBufferSizePadding = WELS_DIV_ROUND (pWelsSvcRc->iBitRate * PADDING_BUFFER_RATIO, INT_MULTIPLY); | |
| 255 | + | |
| 256 | +//change remaining bits | |
| 257 | +if (pWelsSvcRc->iBitsPerFrame > REMAIN_BITS_TH) | |
| 258 | +pWelsSvcRc->iRemainingBits = pWelsSvcRc->iRemainingBits * input_iBitsPerFrame / pWelsSvcRc->iBitsPerFrame; | |
| 259 | +pWelsSvcRc->iBitsPerFrame = input_iBitsPerFrame; | |
| 260 | +} | |
| 261 | + | |
| 262 | + | |
| 263 | 263 | void RcInitVGop (sWelsEncCtx* pEncCtx) { |
| 264 | − const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 265 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 266 | − SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 267 | − const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId; | |
| 268 | − | |
| 269 | − pWelsSvcRc->iRemainingBits = WELS_DIV_ROUND (VGOP_SIZE * pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY); | |
| 270 | − pWelsSvcRc->iRemainingWeights = pWelsSvcRc->iGopNumberInVGop * WEIGHT_MULTIPLY; | |
| 271 | − | |
| 272 | − pWelsSvcRc->iFrameCodedInVGop = 0; | |
| 273 | − pWelsSvcRc->iGopIndexInVGop = 0; | |
| 274 | − | |
| 275 | − for (int32_t i = 0; i <= kiHighestTid; ++ i) | |
| 276 | − pTOverRc[i].iGopBitsDq = 0; | |
| 277 | − pWelsSvcRc->iSkipFrameInVGop = 0; | |
| 264 | +const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 265 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 266 | +SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 267 | +const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId; | |
| 268 | + | |
| 269 | +pWelsSvcRc->iRemainingBits = WELS_DIV_ROUND (VGOP_SIZE * pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY); | |
| 270 | +pWelsSvcRc->iRemainingWeights = pWelsSvcRc->iGopNumberInVGop * WEIGHT_MULTIPLY; | |
| 271 | + | |
| 272 | +pWelsSvcRc->iFrameCodedInVGop = 0; | |
| 273 | +pWelsSvcRc->iGopIndexInVGop = 0; | |
| 274 | + | |
| 275 | +for (int32_t i = 0; i <= kiHighestTid; ++ i) | |
| 276 | +pTOverRc[i].iGopBitsDq = 0; | |
| 277 | +pWelsSvcRc->iSkipFrameInVGop = 0; | |
| 278 | 278 | } |
| 279 | − | |
| 279 | + | |
| 280 | 280 | void RcInitRefreshParameter (sWelsEncCtx* pEncCtx) { |
| 281 | − const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 282 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 283 | − SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 284 | − SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[kiDid]; | |
| 285 | − SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDid]; | |
| 286 | − const int32_t kiHighestTid = pDLayerParamInternal->iHighestTemporalId; | |
| 287 | − int32_t i; | |
| 288 | − | |
| 289 | − //I frame R-Q Model | |
| 290 | − pWelsSvcRc->iIntraComplexity = 0; | |
| 291 | − pWelsSvcRc->iIntraMbCount = 0; | |
| 292 | − | |
| 293 | − //P frame R-Q Model | |
| 294 | − for (i = 0; i <= kiHighestTid; i++) { | |
| 295 | − pTOverRc[i].iPFrameNum = 0; | |
| 296 | − pTOverRc[i].iLinearCmplx = 0; | |
| 297 | − pTOverRc[i].iFrameCmplxMean = 0; | |
| 298 | − } | |
| 299 | − | |
| 300 | − pWelsSvcRc->iBufferFullnessSkip = 0; | |
| 301 | − pWelsSvcRc->iBufferFullnessPadding = 0; | |
| 302 | − | |
| 303 | − pWelsSvcRc->iGopIndexInVGop = 0; | |
| 304 | − pWelsSvcRc->iRemainingBits = 0; | |
| 305 | − pWelsSvcRc->iBitsPerFrame = 0; | |
| 306 | − | |
| 307 | − //Backup the initial bitrate and fps | |
| 308 | − pWelsSvcRc->iPreviousBitrate = pDLayerParam->iSpatialBitrate; | |
| 309 | − pWelsSvcRc->dPreviousFps = pDLayerParamInternal->fInputFrameRate; | |
| 310 | − | |
| 311 | − memset (pWelsSvcRc->pCurrentFrameGomSad, 0, pWelsSvcRc->iGomSize * sizeof (int32_t)); | |
| 312 | − | |
| 313 | − RcInitTlWeight (pEncCtx); | |
| 314 | − RcUpdateBitrateFps (pEncCtx); | |
| 315 | − RcInitVGop (pEncCtx); | |
| 281 | +const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 282 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 283 | +SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 284 | +SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[kiDid]; | |
| 285 | +SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[kiDid]; | |
| 286 | +const int32_t kiHighestTid = pDLayerParamInternal->iHighestTemporalId; | |
| 287 | +int32_t i; | |
| 288 | + | |
| 289 | +//I frame R-Q Model | |
| 290 | +pWelsSvcRc->iIntraComplexity = 0; | |
| 291 | +pWelsSvcRc->iIntraMbCount = 0; | |
| 292 | + | |
| 293 | +//P frame R-Q Model | |
| 294 | +for (i = 0; i <= kiHighestTid; i++) { | |
| 295 | +pTOverRc[i].iPFrameNum = 0; | |
| 296 | +pTOverRc[i].iLinearCmplx = 0; | |
| 297 | +pTOverRc[i].iFrameCmplxMean = 0; | |
| 316 | 298 | } |
| 317 | − | |
| 299 | + | |
| 300 | +pWelsSvcRc->iBufferFullnessSkip = 0; | |
| 301 | +pWelsSvcRc->iBufferFullnessPadding = 0; | |
| 302 | + | |
| 303 | +pWelsSvcRc->iGopIndexInVGop = 0; | |
| 304 | +pWelsSvcRc->iRemainingBits = 0; | |
| 305 | +pWelsSvcRc->iBitsPerFrame = 0; | |
| 306 | + | |
| 307 | +//Backup the initial bitrate and fps | |
| 308 | +pWelsSvcRc->iPreviousBitrate = pDLayerParam->iSpatialBitrate; | |
| 309 | +pWelsSvcRc->dPreviousFps = pDLayerParamInternal->fInputFrameRate; | |
| 310 | + | |
| 311 | +memset (pWelsSvcRc->pCurrentFrameGomSad, 0, pWelsSvcRc->iGomSize * sizeof (int32_t)); | |
| 312 | + | |
| 313 | +RcInitTlWeight (pEncCtx); | |
| 314 | +RcUpdateBitrateFps (pEncCtx); | |
| 315 | +RcInitVGop (pEncCtx); | |
| 316 | +} | |
| 317 | + | |
| 318 | 318 | bool RcJudgeBitrateFpsUpdate (sWelsEncCtx* pEncCtx) { |
| 319 | − int32_t iCurDid = pEncCtx->uiDependencyId; | |
| 320 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[iCurDid]; | |
| 321 | − SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[iCurDid]; | |
| 322 | − SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[iCurDid]; | |
| 323 | − | |
| 324 | − if ((pWelsSvcRc->iPreviousBitrate != pDLayerParam->iSpatialBitrate) || | |
| 325 | − (pWelsSvcRc->dPreviousFps - pDLayerParamInternal->fInputFrameRate) > EPSN || | |
| 326 | − (pWelsSvcRc->dPreviousFps - pDLayerParamInternal->fInputFrameRate) < -EPSN) { | |
| 327 | − pWelsSvcRc->iPreviousBitrate = pDLayerParam->iSpatialBitrate; | |
| 328 | − pWelsSvcRc->dPreviousFps = pDLayerParamInternal->fInputFrameRate; | |
| 329 | − return true; | |
| 330 | − } else | |
| 331 | − return false; | |
| 319 | +int32_t iCurDid = pEncCtx->uiDependencyId; | |
| 320 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[iCurDid]; | |
| 321 | +SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[iCurDid]; | |
| 322 | +SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[iCurDid]; | |
| 323 | + | |
| 324 | +if ((pWelsSvcRc->iPreviousBitrate != pDLayerParam->iSpatialBitrate) || | |
| 325 | +(pWelsSvcRc->dPreviousFps - pDLayerParamInternal->fInputFrameRate) > EPSN || | |
| 326 | +(pWelsSvcRc->dPreviousFps - pDLayerParamInternal->fInputFrameRate) < -EPSN) { | |
| 327 | +pWelsSvcRc->iPreviousBitrate = pDLayerParam->iSpatialBitrate; | |
| 328 | +pWelsSvcRc->dPreviousFps = pDLayerParamInternal->fInputFrameRate; | |
| 329 | +return true; | |
| 330 | +} else | |
| 331 | +return false; | |
| 332 | 332 | } |
| 333 | − | |
| 333 | + | |
| 334 | 334 | #if GOM_TRACE_FLAG |
| 335 | 335 | void RcTraceVGopBitrate (sWelsEncCtx* pEncCtx) { |
| 336 | − const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 337 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 338 | − | |
| 339 | − if (pWelsSvcRc->iFrameCodedInVGop) { | |
| 340 | − const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId; | |
| 341 | − SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 342 | − int32_t iVGopBitrate = 0; | |
| 343 | − int32_t iTotalBits = pWelsSvcRc->iPaddingBitrateStat; | |
| 344 | − int32_t iTid = 0; | |
| 345 | − while (iTid <= kiHighestTid) { | |
| 346 | − iTotalBits += pTOverRc[iTid].iGopBitsDq; | |
| 347 | − ++ iTid; | |
| 348 | − } | |
| 349 | − int32_t iFrameInVGop = pWelsSvcRc->iFrameCodedInVGop + pWelsSvcRc->iSkipFrameInVGop; | |
| 350 | − if (0 != iFrameInVGop) | |
| 351 | − iVGopBitrate = WELS_ROUND (iTotalBits / iFrameInVGop * pWelsSvcRc->fFrameRate); | |
| 336 | +const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 337 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 338 | + | |
| 339 | +if (pWelsSvcRc->iFrameCodedInVGop) { | |
| 340 | +const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId; | |
| 341 | +SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 342 | +int32_t iVGopBitrate = 0; | |
| 343 | +int32_t iTotalBits = pWelsSvcRc->iPaddingBitrateStat; | |
| 344 | +int32_t iTid = 0; | |
| 345 | +while (iTid <= kiHighestTid) { | |
| 346 | +iTotalBits += pTOverRc[iTid].iGopBitsDq; | |
| 347 | +++ iTid; | |
| 348 | +} | |
| 349 | +int32_t iFrameInVGop = pWelsSvcRc->iFrameCodedInVGop + pWelsSvcRc->iSkipFrameInVGop; | |
| 350 | +if (0 != iFrameInVGop) | |
| 351 | +iVGopBitrate = WELS_ROUND (iTotalBits / iFrameInVGop * pWelsSvcRc->fFrameRate); | |
| 352 | 352 | #ifdef _TEST_TEMP_Rc_ |
| 353 | − fprintf (fp_vgop, "%d\n", WELS_ROUND ((double)iTotalBits / iFrameInVGop)); | |
| 353 | +fprintf (fp_vgop, "%d\n", WELS_ROUND ((double)iTotalBits / iFrameInVGop)); | |
| 354 | 354 | #endif |
| 355 | − WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "[Rc] VGOPbitrate%d: %d ", kiDid, iVGopBitrate); | |
| 356 | − if (iTotalBits > 0) { | |
| 357 | − iTid = 0; | |
| 358 | − while (iTid <= kiHighestTid) { | |
| 359 | − WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "T%d=%8.3f ", iTid, (double) (pTOverRc[iTid].iGopBitsDq / iTotalBits)); | |
| 360 | − ++ iTid; | |
| 361 | − } | |
| 362 | − } | |
| 363 | − } | |
| 355 | +WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "[Rc] VGOPbitrate%d: %d ", kiDid, iVGopBitrate); | |
| 356 | +if (iTotalBits > 0) { | |
| 357 | +iTid = 0; | |
| 358 | +while (iTid <= kiHighestTid) { | |
| 359 | +WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "T%d=%8.3f ", iTid, (double) (pTOverRc[iTid].iGopBitsDq / iTotalBits)); | |
| 360 | +++ iTid; | |
| 361 | +} | |
| 362 | +} | |
| 363 | +} | |
| 364 | 364 | } |
| 365 | 365 | #endif |
| 366 | − | |
| 366 | + | |
| 367 | 367 | void RcUpdateTemporalZero (sWelsEncCtx* pEncCtx) { |
| 368 | − const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 369 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 370 | − SSpatialLayerInternal* pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[kiDid]; | |
| 371 | − const int32_t kiGopSize = (1 << pDLayerParam->iDecompositionStages); | |
| 372 | − | |
| 373 | − if (pWelsSvcRc->iPreviousGopSize != kiGopSize) { | |
| 368 | +const int32_t kiDid = pEncCtx->uiDependencyId; | |
| 369 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid]; | |
| 370 | +SSpatialLayerInternal* pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[kiDid]; | |
| 371 | +const int32_t kiGopSize = (1 << pDLayerParam->iDecompositionStages); | |
| 372 | + | |
| 373 | +if (pWelsSvcRc->iPreviousGopSize != kiGopSize) { | |
| 374 | 374 | #if GOM_TRACE_FLAG |
| 375 | − RcTraceVGopBitrate (pEncCtx); | |
| 375 | +RcTraceVGopBitrate (pEncCtx); | |
| 376 | 376 | #endif |
| 377 | − RcInitTlWeight (pEncCtx); | |
| 378 | − RcInitVGop (pEncCtx); | |
| 379 | − } else if (pWelsSvcRc->iGopIndexInVGop == pWelsSvcRc->iGopNumberInVGop || pEncCtx->eSliceType == I_SLICE) { | |
| 377 | +RcInitTlWeight (pEncCtx); | |
| 378 | +RcInitVGop (pEncCtx); | |
| 379 | +} else if (pWelsSvcRc->iGopIndexInVGop == pWelsSvcRc->iGopNumberInVGop || pEncCtx->eSliceType == I_SLICE) { | |
| 380 | 380 | #if GOM_TRACE_FLAG |
| 381 | − RcTraceVGopBitrate (pEncCtx); | |
| 381 | +RcTraceVGopBitrate (pEncCtx); | |
| 382 | 382 | #endif |
| 383 | − RcInitVGop (pEncCtx); | |
| 384 | − } | |
| 385 | − pWelsSvcRc->iGopIndexInVGop++; | |
| 383 | +RcInitVGop (pEncCtx); | |
| 386 | 384 | } |
| 387 | − | |
| 388 | − | |
| 385 | +pWelsSvcRc->iGopIndexInVGop++; | |
| 386 | +} | |
| 387 | + | |
| 388 | + | |
| 389 | 389 | void RcInitIdrQp (sWelsEncCtx* pEncCtx) { |
| 390 | − double dBpp = 0; | |
| 391 | − int32_t i; | |
| 392 | − | |
| 393 | − //64k@6fps for 90p: bpp 0.74 QP:24 | |
| 394 | − //192k@12fps for 180p: bpp 0.28 QP:26 | |
| 395 | − //512k@24fps for 360p: bpp 0.09 QP:30 | |
| 396 | − //1500k@30fps for 720p: bpp 0.05 QP:32 | |
| 397 | − double dBppArray[4][3] = {{0.5, 0.75, 1.0}, {0.2, 0.3, 0.4}, {0.05, 0.09, 0.13}, {0.03, 0.06, 0.1}}; | |
| 398 | − int32_t dInitialQPArray[4][4] = {{28, 26, 24, 22}, {30, 28, 26, 24}, {32, 30, 28, 26}, {34, 32, 30, 28}}; | |
| 399 | − int32_t iBppIndex = 0; | |
| 400 | − | |
| 401 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 402 | − SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 403 | − | |
| 404 | − if (pDLayerParam->fFrameRate > EPSN && pDLayerParam->iVideoWidth && pDLayerParam->iVideoHeight) | |
| 405 | − dBpp = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParam->fFrameRate * pDLayerParam->iVideoWidth * | |
| 406 | − pDLayerParam->iVideoHeight); | |
| 407 | − else | |
| 408 | − dBpp = 0.1; | |
| 409 | − | |
| 410 | − //Area*2 | |
| 411 | − if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 28800) // 90p video:160*90 | |
| 412 | − iBppIndex = 0; | |
| 413 | − else if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 115200) // 180p video:320*180 | |
| 414 | − iBppIndex = 1; | |
| 415 | − else if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 460800) // 360p video:640*360 | |
| 416 | − iBppIndex = 2; | |
| 417 | − else | |
| 418 | − iBppIndex = 3; | |
| 419 | − | |
| 420 | − //Search | |
| 421 | − for (i = 0; i < 3; i++) { | |
| 422 | − if (dBpp <= dBppArray[iBppIndex][i]) | |
| 423 | − break; | |
| 424 | − } | |
| 425 | − pWelsSvcRc->iInitialQp = dInitialQPArray[iBppIndex][i]; | |
| 426 | − pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP); | |
| 427 | − pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp; | |
| 428 | − pWelsSvcRc->iQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp); | |
| 429 | − pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp; | |
| 390 | +double dBpp = 0; | |
| 391 | +int32_t i; | |
| 392 | + | |
| 393 | +//64k@6fps for 90p: bpp 0.74 QP:24 | |
| 394 | +//192k@12fps for 180p: bpp 0.28 QP:26 | |
| 395 | +//512k@24fps for 360p: bpp 0.09 QP:30 | |
| 396 | +//1500k@30fps for 720p: bpp 0.05 QP:32 | |
| 397 | +double dBppArray[4][3] = {{0.5, 0.75, 1.0}, {0.2, 0.3, 0.4}, {0.05, 0.09, 0.13}, {0.03, 0.06, 0.1}}; | |
| 398 | +int32_t dInitialQPArray[4][4] = {{28, 26, 24, 22}, {30, 28, 26, 24}, {32, 30, 28, 26}, {34, 32, 30, 28}}; | |
| 399 | +int32_t iBppIndex = 0; | |
| 400 | + | |
| 401 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 402 | +SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 403 | + | |
| 404 | +if (pDLayerParam->fFrameRate > EPSN && pDLayerParam->iVideoWidth && pDLayerParam->iVideoHeight) | |
| 405 | +dBpp = (double) (pDLayerParam->iSpatialBitrate) / (double) (pDLayerParam->fFrameRate * pDLayerParam->iVideoWidth * | |
| 406 | +pDLayerParam->iVideoHeight); | |
| 407 | +else | |
| 408 | +dBpp = 0.1; | |
| 409 | + | |
| 410 | +//Area*2 | |
| 411 | +if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 28800) // 90p video:160*90 | |
| 412 | +iBppIndex = 0; | |
| 413 | +else if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 115200) // 180p video:320*180 | |
| 414 | +iBppIndex = 1; | |
| 415 | +else if (pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight <= 460800) // 360p video:640*360 | |
| 416 | +iBppIndex = 2; | |
| 417 | +else | |
| 418 | +iBppIndex = 3; | |
| 419 | + | |
| 420 | +//Search | |
| 421 | +for (i = 0; i < 3; i++) { | |
| 422 | +if (dBpp <= dBppArray[iBppIndex][i]) | |
| 423 | +break; | |
| 430 | 424 | } |
| 431 | − | |
| 425 | +pWelsSvcRc->iInitialQp = dInitialQPArray[iBppIndex][i]; | |
| 426 | +pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP); | |
| 427 | +pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp; | |
| 428 | +pWelsSvcRc->iQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp); | |
| 429 | +pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp; | |
| 430 | +} | |
| 431 | + | |
| 432 | 432 | void RcCalculateIdrQp (sWelsEncCtx* pEncCtx) { |
| 433 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 434 | − //obtain the idr qp using previous idr complexity | |
| 435 | − if (pWelsSvcRc->iNumberMbFrame != pWelsSvcRc->iIntraMbCount) { | |
| 436 | − pWelsSvcRc->iIntraComplexity = pWelsSvcRc->iIntraComplexity * pWelsSvcRc->iNumberMbFrame / | |
| 437 | − pWelsSvcRc->iIntraMbCount; | |
| 438 | − } | |
| 439 | − pWelsSvcRc->iInitialQp = RcConvertQStep2Qp (pWelsSvcRc->iIntraComplexity / | |
| 440 | − pWelsSvcRc->iTargetBits); | |
| 441 | − pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP); | |
| 442 | − pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp; | |
| 443 | − pWelsSvcRc->iQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp); | |
| 444 | − pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp; | |
| 433 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 434 | +//obtain the idr qp using previous idr complexity | |
| 435 | +if (pWelsSvcRc->iNumberMbFrame != pWelsSvcRc->iIntraMbCount) { | |
| 436 | +pWelsSvcRc->iIntraComplexity = pWelsSvcRc->iIntraComplexity * pWelsSvcRc->iNumberMbFrame / | |
| 437 | +pWelsSvcRc->iIntraMbCount; | |
| 445 | 438 | } |
| 446 | − | |
| 447 | − | |
| 439 | +pWelsSvcRc->iInitialQp = RcConvertQStep2Qp (pWelsSvcRc->iIntraComplexity / | |
| 440 | +pWelsSvcRc->iTargetBits); | |
| 441 | +pWelsSvcRc->iInitialQp = WELS_CLIP3 (pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP); | |
| 442 | +pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp; | |
| 443 | +pWelsSvcRc->iQStep = RcConvertQp2QStep (pEncCtx->iGlobalQp); | |
| 444 | +pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp; | |
| 445 | +} | |
| 446 | + | |
| 447 | + | |
| 448 | 448 | void RcCalculatePictureQp (sWelsEncCtx* pEncCtx) { |
| 449 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 450 | − int32_t iTl = pEncCtx->uiTemporalId; | |
| 451 | − SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[iTl]; | |
| 452 | − int32_t iLumaQp = 0; | |
| 453 | − | |
| 454 | − if (0 == pTOverRc->iPFrameNum) { | |
| 455 | − iLumaQp = pWelsSvcRc->iInitialQp; | |
| 456 | − } else if (pWelsSvcRc->iCurrentBitsLevel == BITS_EXCEEDED) { | |
| 457 | − iLumaQp = MAX_LOW_BR_QP; | |
| 458 | − //limit QP | |
| 459 | − int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1; | |
| 460 | − if (iLastIdxCodecInVGop < 0) | |
| 461 | − iLastIdxCodecInVGop += VGOP_SIZE; | |
| 462 | − int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop]; | |
| 463 | − int32_t iDeltaQpTemporal = iTl - iTlLast; | |
| 464 | − if (0 == iTlLast && iTl > 0) | |
| 465 | − iDeltaQpTemporal += 3; | |
| 466 | − else if (0 == iTl && iTlLast > 0) | |
| 467 | − iDeltaQpTemporal -= 3; | |
| 468 | − | |
| 469 | − iLumaQp = WELS_CLIP3 (iLumaQp, | |
| 470 | − pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower + iDeltaQpTemporal, | |
| 471 | − pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper + iDeltaQpTemporal); | |
| 472 | − iLumaQp = WELS_CLIP3 (iLumaQp, GOM_MIN_QP_MODE, MAX_LOW_BR_QP); | |
| 473 | − | |
| 474 | − pWelsSvcRc->iQStep = RcConvertQp2QStep (iLumaQp); | |
| 475 | − pWelsSvcRc->iLastCalculatedQScale = iLumaQp; | |
| 476 | − | |
| 477 | − if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { | |
| 478 | − iLumaQp = WELS_CLIP3 ((iLumaQp * INT_MULTIPLY - pEncCtx->pVaa->sAdaptiveQuantParam.iAverMotionTextureIndexToDeltaQp) / | |
| 479 | − INT_MULTIPLY, GOM_MIN_QP_MODE, MAX_LOW_BR_QP); | |
| 480 | − } | |
| 481 | − | |
| 482 | − pEncCtx->iGlobalQp = iLumaQp; | |
| 483 | − | |
| 484 | − return; | |
| 485 | − } else { | |
| 486 | − int64_t iCmplxRatio = WELS_DIV_ROUND64 (pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity * INT_MULTIPLY, | |
| 487 | − pTOverRc->iFrameCmplxMean); | |
| 488 | − iCmplxRatio = WELS_CLIP3 (iCmplxRatio, INT_MULTIPLY - FRAME_CMPLX_RATIO_RANGE, INT_MULTIPLY + FRAME_CMPLX_RATIO_RANGE); | |
| 489 | − | |
| 490 | − pWelsSvcRc->iQStep = WELS_DIV_ROUND ((pTOverRc->iLinearCmplx * iCmplxRatio), (pWelsSvcRc->iTargetBits * INT_MULTIPLY)); | |
| 491 | − iLumaQp = RcConvertQStep2Qp (pWelsSvcRc->iQStep); | |
| 492 | − | |
| 493 | − //limit QP | |
| 494 | − int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1; | |
| 495 | − if (iLastIdxCodecInVGop < 0) | |
| 496 | − iLastIdxCodecInVGop += VGOP_SIZE; | |
| 497 | − int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop]; | |
| 498 | − int32_t iDeltaQpTemporal = iTl - iTlLast; | |
| 499 | − if (0 == iTlLast && iTl > 0) | |
| 500 | − iDeltaQpTemporal += 3; | |
| 501 | − else if (0 == iTl && iTlLast > 0) | |
| 502 | − iDeltaQpTemporal -= 3; | |
| 503 | − | |
| 504 | − iLumaQp = WELS_CLIP3 (iLumaQp, | |
| 505 | − pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower + iDeltaQpTemporal, | |
| 506 | − pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper + iDeltaQpTemporal); | |
| 507 | − } | |
| 508 | − | |
| 509 | − iLumaQp = WELS_CLIP3 (iLumaQp, GOM_MIN_QP_MODE, GOM_MAX_QP_MODE); | |
| 510 | − | |
| 511 | − pWelsSvcRc->iQStep = RcConvertQp2QStep (iLumaQp); | |
| 512 | − pWelsSvcRc->iLastCalculatedQScale = iLumaQp; | |
| 449 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 450 | +int32_t iTl = pEncCtx->uiTemporalId; | |
| 451 | +SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[iTl]; | |
| 452 | +int32_t iLumaQp = 0; | |
| 453 | + | |
| 454 | +if (0 == pTOverRc->iPFrameNum) { | |
| 455 | +iLumaQp = pWelsSvcRc->iInitialQp; | |
| 456 | +} else if (pWelsSvcRc->iCurrentBitsLevel == BITS_EXCEEDED) { | |
| 457 | +iLumaQp = MAX_LOW_BR_QP; | |
| 458 | +//limit QP | |
| 459 | +int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1; | |
| 460 | +if (iLastIdxCodecInVGop < 0) | |
| 461 | +iLastIdxCodecInVGop += VGOP_SIZE; | |
| 462 | +int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop]; | |
| 463 | +int32_t iDeltaQpTemporal = iTl - iTlLast; | |
| 464 | +if (0 == iTlLast && iTl > 0) | |
| 465 | +iDeltaQpTemporal += 3; | |
| 466 | +else if (0 == iTl && iTlLast > 0) | |
| 467 | +iDeltaQpTemporal -= 3; | |
| 468 | + | |
| 469 | +iLumaQp = WELS_CLIP3 (iLumaQp, | |
| 470 | +pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower + iDeltaQpTemporal, | |
| 471 | +pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper + iDeltaQpTemporal); | |
| 472 | +iLumaQp = WELS_CLIP3 (iLumaQp, GOM_MIN_QP_MODE, MAX_LOW_BR_QP); | |
| 473 | + | |
| 474 | +pWelsSvcRc->iQStep = RcConvertQp2QStep (iLumaQp); | |
| 475 | +pWelsSvcRc->iLastCalculatedQScale = iLumaQp; | |
| 476 | + | |
| 477 | +if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { | |
| 478 | +iLumaQp = WELS_CLIP3 ((iLumaQp * INT_MULTIPLY - pEncCtx->pVaa->sAdaptiveQuantParam.iAverMotionTextureIndexToDeltaQp) / | |
| 479 | +INT_MULTIPLY, GOM_MIN_QP_MODE, MAX_LOW_BR_QP); | |
| 480 | +} | |
| 481 | + | |
| 482 | +pEncCtx->iGlobalQp = iLumaQp; | |
| 483 | + | |
| 484 | +return; | |
| 485 | +} else { | |
| 486 | +int64_t iCmplxRatio = WELS_DIV_ROUND64 (pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity * INT_MULTIPLY, | |
| 487 | +pTOverRc->iFrameCmplxMean); | |
| 488 | +iCmplxRatio = WELS_CLIP3 (iCmplxRatio, INT_MULTIPLY - FRAME_CMPLX_RATIO_RANGE, INT_MULTIPLY + FRAME_CMPLX_RATIO_RANGE); | |
| 489 | + | |
| 490 | +pWelsSvcRc->iQStep = WELS_DIV_ROUND ((pTOverRc->iLinearCmplx * iCmplxRatio), (pWelsSvcRc->iTargetBits * INT_MULTIPLY)); | |
| 491 | +iLumaQp = RcConvertQStep2Qp (pWelsSvcRc->iQStep); | |
| 492 | + | |
| 493 | +//limit QP | |
| 494 | +int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1; | |
| 495 | +if (iLastIdxCodecInVGop < 0) | |
| 496 | +iLastIdxCodecInVGop += VGOP_SIZE; | |
| 497 | +int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop]; | |
| 498 | +int32_t iDeltaQpTemporal = iTl - iTlLast; | |
| 499 | +if (0 == iTlLast && iTl > 0) | |
| 500 | +iDeltaQpTemporal += 3; | |
| 501 | +else if (0 == iTl && iTlLast > 0) | |
| 502 | +iDeltaQpTemporal -= 3; | |
| 503 | + | |
| 504 | +iLumaQp = WELS_CLIP3 (iLumaQp, | |
| 505 | +pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower + iDeltaQpTemporal, | |
| 506 | +pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper + iDeltaQpTemporal); | |
| 507 | +} | |
| 508 | + | |
| 509 | +iLumaQp = WELS_CLIP3 (iLumaQp, GOM_MIN_QP_MODE, GOM_MAX_QP_MODE); | |
| 510 | + | |
| 511 | +pWelsSvcRc->iQStep = RcConvertQp2QStep (iLumaQp); | |
| 512 | +pWelsSvcRc->iLastCalculatedQScale = iLumaQp; | |
| 513 | 513 | #ifndef _NOT_USE_AQ_FOR_TEST_ |
| 514 | − if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { | |
| 515 | − | |
| 516 | − iLumaQp = WELS_DIV_ROUND (iLumaQp * INT_MULTIPLY - pEncCtx->pVaa->sAdaptiveQuantParam.iAverMotionTextureIndexToDeltaQp, | |
| 517 | − INT_MULTIPLY); | |
| 518 | − | |
| 519 | − if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false))) | |
| 520 | − iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp); | |
| 521 | − | |
| 522 | − } | |
| 514 | +if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { | |
| 515 | + | |
| 516 | +iLumaQp = WELS_DIV_ROUND (iLumaQp * INT_MULTIPLY - pEncCtx->pVaa->sAdaptiveQuantParam.iAverMotionTextureIndexToDeltaQp, | |
| 517 | +INT_MULTIPLY); | |
| 518 | + | |
| 519 | +if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false))) | |
| 520 | +iLumaQp = WELS_CLIP3 (iLumaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp); | |
| 521 | + | |
| 522 | +} | |
| 523 | 523 | #endif |
| 524 | − pEncCtx->iGlobalQp = iLumaQp; | |
| 524 | +pEncCtx->iGlobalQp = iLumaQp; | |
| 525 | 525 | } |
| 526 | − | |
| 526 | + | |
| 527 | 527 | void RcInitSliceInformation (sWelsEncCtx* pEncCtx) { |
| 528 | − SSliceCtx* pCurSliceCtx = pEncCtx->pCurDqLayer->pSliceEncCtx; | |
| 529 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 530 | − SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[0]; | |
| 531 | − const int32_t kiSliceNum = pWelsSvcRc->iSliceNum; | |
| 532 | − const int32_t kiBitsPerMb = WELS_DIV_ROUND (pWelsSvcRc->iTargetBits * INT_MULTIPLY, pWelsSvcRc->iNumberMbFrame); | |
| 533 | − | |
| 534 | − for (int32_t i = 0; i < kiSliceNum; i++) { | |
| 535 | − pSOverRc->iStartMbSlice = | |
| 536 | − pSOverRc->iEndMbSlice = pCurSliceCtx->pFirstMbInSlice[i]; | |
| 537 | − pSOverRc->iEndMbSlice += (pCurSliceCtx->pCountMbNumInSlice[i] - 1); | |
| 538 | − pSOverRc->iTotalQpSlice = 0; | |
| 539 | − pSOverRc->iTotalMbSlice = 0; | |
| 540 | − pSOverRc->iTargetBitsSlice = WELS_DIV_ROUND (kiBitsPerMb * pCurSliceCtx->pCountMbNumInSlice[i], INT_MULTIPLY); | |
| 541 | − pSOverRc->iFrameBitsSlice = 0; | |
| 542 | − pSOverRc->iGomBitsSlice = 0; | |
| 543 | − ++ pSOverRc; | |
| 544 | − } | |
| 528 | +SSliceCtx* pCurSliceCtx = pEncCtx->pCurDqLayer->pSliceEncCtx; | |
| 529 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 530 | +SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[0]; | |
| 531 | +const int32_t kiSliceNum = pWelsSvcRc->iSliceNum; | |
| 532 | +const int32_t kiBitsPerMb = WELS_DIV_ROUND (pWelsSvcRc->iTargetBits * INT_MULTIPLY, pWelsSvcRc->iNumberMbFrame); | |
| 533 | + | |
| 534 | +for (int32_t i = 0; i < kiSliceNum; i++) { | |
| 535 | +pSOverRc->iStartMbSlice = | |
| 536 | +pSOverRc->iEndMbSlice = pCurSliceCtx->pFirstMbInSlice[i]; | |
| 537 | +pSOverRc->iEndMbSlice += (pCurSliceCtx->pCountMbNumInSlice[i] - 1); | |
| 538 | +pSOverRc->iTotalQpSlice = 0; | |
| 539 | +pSOverRc->iTotalMbSlice = 0; | |
| 540 | +pSOverRc->iTargetBitsSlice = WELS_DIV_ROUND (kiBitsPerMb * pCurSliceCtx->pCountMbNumInSlice[i], INT_MULTIPLY); | |
| 541 | +pSOverRc->iFrameBitsSlice = 0; | |
| 542 | +pSOverRc->iGomBitsSlice = 0; | |
| 543 | +++ pSOverRc; | |
| 545 | 544 | } |
| 546 | − | |
| 545 | +} | |
| 546 | + | |
| 547 | 547 | void RcDecideTargetBits (sWelsEncCtx* pEncCtx) { |
| 548 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 549 | − SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId]; | |
| 550 | − | |
| 551 | − pWelsSvcRc->iCurrentBitsLevel = BITS_NORMAL; | |
| 552 | − //allocate bits | |
| 553 | − if (pEncCtx->eSliceType == I_SLICE) { | |
| 554 | − pWelsSvcRc->iTargetBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame * IDR_BITRATE_RATIO, INT_MULTIPLY); | |
| 555 | − } else { | |
| 556 | − if (pWelsSvcRc->iRemainingWeights > pTOverRc->iTlayerWeight) | |
| 557 | − pWelsSvcRc->iTargetBits = (int32_t) ((int64_t)pWelsSvcRc->iRemainingBits * pTOverRc->iTlayerWeight / | |
| 558 | − pWelsSvcRc->iRemainingWeights); | |
| 559 | − else //this case should be not hit. needs to more test case to verify this | |
| 560 | − pWelsSvcRc->iTargetBits = pWelsSvcRc->iRemainingBits; | |
| 561 | − if ((pWelsSvcRc->iTargetBits <= 0) && ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) | |
| 562 | − && (pEncCtx->pSvcParam->bEnableFrameSkip == false))) { | |
| 563 | − pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED; | |
| 564 | − } | |
| 565 | − pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl); | |
| 566 | − } | |
| 567 | − pWelsSvcRc->iRemainingWeights -= pTOverRc->iTlayerWeight; | |
| 548 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 549 | +SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId]; | |
| 550 | + | |
| 551 | +pWelsSvcRc->iCurrentBitsLevel = BITS_NORMAL; | |
| 552 | +//allocate bits | |
| 553 | +if (pEncCtx->eSliceType == I_SLICE) { | |
| 554 | +pWelsSvcRc->iTargetBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame * IDR_BITRATE_RATIO, INT_MULTIPLY); | |
| 555 | +} else { | |
| 556 | +if (pWelsSvcRc->iRemainingWeights > pTOverRc->iTlayerWeight) | |
| 557 | +pWelsSvcRc->iTargetBits = (int32_t) ((int64_t)pWelsSvcRc->iRemainingBits * pTOverRc->iTlayerWeight / | |
| 558 | +pWelsSvcRc->iRemainingWeights); | |
| 559 | +else //this case should be not hit. needs to more test case to verify this | |
| 560 | +pWelsSvcRc->iTargetBits = pWelsSvcRc->iRemainingBits; | |
| 561 | +if ((pWelsSvcRc->iTargetBits <= 0) && ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) | |
| 562 | +&& (pEncCtx->pSvcParam->bEnableFrameSkip == false))) { | |
| 563 | +pWelsSvcRc->iCurrentBitsLevel = BITS_EXCEEDED; | |
| 568 | 564 | } |
| 569 | − | |
| 570 | − | |
| 565 | +pWelsSvcRc->iTargetBits = WELS_CLIP3 (pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl); | |
| 566 | +} | |
| 567 | +pWelsSvcRc->iRemainingWeights -= pTOverRc->iTlayerWeight; | |
| 568 | +} | |
| 569 | + | |
| 570 | + | |
| 571 | 571 | void RcInitGomParameters (sWelsEncCtx* pEncCtx) { |
| 572 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 573 | − SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[0]; | |
| 574 | − const int32_t kiSliceNum = pWelsSvcRc->iSliceNum; | |
| 575 | − const int32_t kiGlobalQp = pEncCtx->iGlobalQp; | |
| 576 | − | |
| 577 | − pWelsSvcRc->iAverageFrameQp = 0; | |
| 578 | − pWelsSvcRc->iMinFrameQp = 51;; | |
| 579 | − pWelsSvcRc->iMaxFrameQp = 0; | |
| 580 | − for (int32_t i = 0; i < kiSliceNum; ++i) { | |
| 581 | − pSOverRc->iComplexityIndexSlice = 0; | |
| 582 | − pSOverRc->iCalculatedQpSlice = kiGlobalQp; | |
| 583 | − ++ pSOverRc; | |
| 584 | − } | |
| 585 | − memset (pWelsSvcRc->pGomComplexity, 0, pWelsSvcRc->iGomSize * sizeof (double)); | |
| 586 | − memset (pWelsSvcRc->pGomCost, 0, pWelsSvcRc->iGomSize * sizeof (int32_t)); | |
| 572 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 573 | +SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[0]; | |
| 574 | +const int32_t kiSliceNum = pWelsSvcRc->iSliceNum; | |
| 575 | +const int32_t kiGlobalQp = pEncCtx->iGlobalQp; | |
| 576 | + | |
| 577 | +pWelsSvcRc->iAverageFrameQp = 0; | |
| 578 | +pWelsSvcRc->iMinFrameQp = 51;; | |
| 579 | +pWelsSvcRc->iMaxFrameQp = 0; | |
| 580 | +for (int32_t i = 0; i < kiSliceNum; ++i) { | |
| 581 | +pSOverRc->iComplexityIndexSlice = 0; | |
| 582 | +pSOverRc->iCalculatedQpSlice = kiGlobalQp; | |
| 583 | +++ pSOverRc; | |
| 587 | 584 | } |
| 588 | − | |
| 585 | +memset (pWelsSvcRc->pGomComplexity, 0, pWelsSvcRc->iGomSize * sizeof (double)); | |
| 586 | +memset (pWelsSvcRc->pGomCost, 0, pWelsSvcRc->iGomSize * sizeof (int32_t)); | |
| 587 | +} | |
| 588 | + | |
| 589 | 589 | void RcCalculateMbQp (sWelsEncCtx* pEncCtx, SMB* pCurMb, const int32_t kiSliceId) { |
| 590 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 591 | − SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[kiSliceId]; | |
| 592 | − int32_t iLumaQp = pSOverRc->iCalculatedQpSlice; | |
| 593 | − SDqLayer* pCurLayer = pEncCtx->pCurDqLayer; | |
| 594 | − const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset; | |
| 590 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 591 | +SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[kiSliceId]; | |
| 592 | +int32_t iLumaQp = pSOverRc->iCalculatedQpSlice; | |
| 593 | +SDqLayer* pCurLayer = pEncCtx->pCurDqLayer; | |
| 594 | +const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset; | |
| 595 | 595 | #ifndef _NOT_USE_AQ_FOR_TEST_ |
| 596 | − if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { | |
| 597 | − iLumaQp = (int8_t)WELS_CLIP3 (iLumaQp + | |
| 598 | − pEncCtx->pVaa->sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[pCurMb->iMbXY], pWelsSvcRc->iMinQp, 51); | |
| 599 | − } | |
| 596 | +if (pEncCtx->pSvcParam->bEnableAdaptiveQuant) { | |
| 597 | +iLumaQp = (int8_t)WELS_CLIP3 (iLumaQp + | |
| 598 | +pEncCtx->pVaa->sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[pCurMb->iMbXY], pWelsSvcRc->iMinQp, 51); | |
| 599 | +} | |
| 600 | 600 | #endif |
| 601 | − pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (iLumaQp + kuiChromaQpIndexOffset)]; | |
| 602 | − pCurMb->uiLumaQp = iLumaQp; | |
| 601 | +pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (iLumaQp + kuiChromaQpIndexOffset)]; | |
| 602 | +pCurMb->uiLumaQp = iLumaQp; | |
| 603 | 603 | } |
| 604 | − | |
| 604 | + | |
| 605 | 605 | SWelsSvcRc* RcJudgeBaseUsability (sWelsEncCtx* pEncCtx) { |
| 606 | − SWelsSvcRc* pWelsSvcRc = NULL, *pWelsSvcRc_Base = NULL; | |
| 607 | − SSpatialLayerConfig* pDlpBase = NULL, *pDLayerParam = NULL; | |
| 608 | − SSpatialLayerInternal* pDlpBaseInternal = NULL; | |
| 609 | − if (pEncCtx->uiDependencyId <= 0) | |
| 610 | − return NULL; | |
| 611 | − pDlpBaseInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId - 1]; | |
| 612 | − pDlpBase = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId - 1]; | |
| 613 | − pWelsSvcRc_Base = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId - 1]; | |
| 614 | − if (pEncCtx->uiTemporalId <= pDlpBaseInternal->iDecompositionStages) { | |
| 615 | − pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 616 | − pWelsSvcRc_Base = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId - 1]; | |
| 617 | − pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 618 | − pDlpBase = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId - 1]; | |
| 619 | − if ((pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight / pWelsSvcRc->iNumberMbGom) == | |
| 620 | − (pDlpBase->iVideoWidth * pDlpBase->iVideoHeight / pWelsSvcRc_Base->iNumberMbGom)) | |
| 621 | − return pWelsSvcRc_Base; | |
| 622 | − else | |
| 623 | − return NULL; | |
| 624 | − } else | |
| 625 | − return NULL; | |
| 606 | +SWelsSvcRc* pWelsSvcRc = NULL, *pWelsSvcRc_Base = NULL; | |
| 607 | +SSpatialLayerConfig* pDlpBase = NULL, *pDLayerParam = NULL; | |
| 608 | +SSpatialLayerInternal* pDlpBaseInternal = NULL; | |
| 609 | +if (pEncCtx->uiDependencyId <= 0) | |
| 610 | +return NULL; | |
| 611 | +pDlpBaseInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId - 1]; | |
| 612 | +pDlpBase = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId - 1]; | |
| 613 | +pWelsSvcRc_Base = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId - 1]; | |
| 614 | +if (pEncCtx->uiTemporalId <= pDlpBaseInternal->iDecompositionStages) { | |
| 615 | +pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 616 | +pWelsSvcRc_Base = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId - 1]; | |
| 617 | +pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 618 | +pDlpBase = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId - 1]; | |
| 619 | +if ((pDLayerParam->iVideoWidth * pDLayerParam->iVideoHeight / pWelsSvcRc->iNumberMbGom) == | |
| 620 | +(pDlpBase->iVideoWidth * pDlpBase->iVideoHeight / pWelsSvcRc_Base->iNumberMbGom)) | |
| 621 | +return pWelsSvcRc_Base; | |
| 622 | +else | |
| 623 | +return NULL; | |
| 624 | +} else | |
| 625 | +return NULL; | |
| 626 | 626 | } |
| 627 | − | |
| 627 | + | |
| 628 | 628 | void RcGomTargetBits (sWelsEncCtx* pEncCtx, const int32_t kiSliceId) { |
| 629 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 630 | − SWelsSvcRc* pWelsSvcRc_Base = NULL; | |
| 631 | − SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[kiSliceId]; | |
| 632 | − | |
| 633 | − int32_t iAllocateBits = 0; | |
| 634 | − int32_t iSumSad = 0; | |
| 635 | − int32_t iLastGomIndex = 0; | |
| 636 | − int32_t iLeftBits = 0; | |
| 637 | − const int32_t kiComplexityIndex = pSOverRc->iComplexityIndexSlice; | |
| 638 | − int32_t i; | |
| 639 | − | |
| 640 | − iLastGomIndex = pSOverRc->iEndMbSlice / pWelsSvcRc->iNumberMbGom; | |
| 641 | − iLeftBits = pSOverRc->iTargetBitsSlice - pSOverRc->iFrameBitsSlice; | |
| 642 | − | |
| 643 | − if (iLeftBits <= 0) { | |
| 644 | − pSOverRc->iGomTargetBits = 0; | |
| 645 | − return; | |
| 646 | − } else if (kiComplexityIndex >= iLastGomIndex) { | |
| 647 | − iAllocateBits = iLeftBits; | |
| 648 | − } else { | |
| 649 | − pWelsSvcRc_Base = RcJudgeBaseUsability (pEncCtx); | |
| 650 | − pWelsSvcRc_Base = (pWelsSvcRc_Base) ? pWelsSvcRc_Base : pWelsSvcRc; | |
| 651 | − for (i = kiComplexityIndex; i <= iLastGomIndex; i++) { | |
| 652 | − iSumSad += pWelsSvcRc_Base->pCurrentFrameGomSad[i]; | |
| 653 | − } | |
| 654 | − if (0 == iSumSad) | |
| 655 | − iAllocateBits = WELS_DIV_ROUND (iLeftBits, (iLastGomIndex - kiComplexityIndex)); | |
| 656 | − else | |
| 657 | − iAllocateBits = WELS_DIV_ROUND ((int64_t)iLeftBits * pWelsSvcRc_Base->pCurrentFrameGomSad[kiComplexityIndex + 1], | |
| 658 | − iSumSad); | |
| 659 | − | |
| 660 | − } | |
| 661 | − pSOverRc->iGomTargetBits = iAllocateBits; | |
| 629 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 630 | +SWelsSvcRc* pWelsSvcRc_Base = NULL; | |
| 631 | +SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[kiSliceId]; | |
| 632 | + | |
| 633 | +int32_t iAllocateBits = 0; | |
| 634 | +int32_t iSumSad = 0; | |
| 635 | +int32_t iLastGomIndex = 0; | |
| 636 | +int32_t iLeftBits = 0; | |
| 637 | +const int32_t kiComplexityIndex = pSOverRc->iComplexityIndexSlice; | |
| 638 | +int32_t i; | |
| 639 | + | |
| 640 | +iLastGomIndex = pSOverRc->iEndMbSlice / pWelsSvcRc->iNumberMbGom; | |
| 641 | +iLeftBits = pSOverRc->iTargetBitsSlice - pSOverRc->iFrameBitsSlice; | |
| 642 | + | |
| 643 | +if (iLeftBits <= 0) { | |
| 644 | +pSOverRc->iGomTargetBits = 0; | |
| 645 | +return; | |
| 646 | +} else if (kiComplexityIndex >= iLastGomIndex) { | |
| 647 | +iAllocateBits = iLeftBits; | |
| 648 | +} else { | |
| 649 | +pWelsSvcRc_Base = RcJudgeBaseUsability (pEncCtx); | |
| 650 | +pWelsSvcRc_Base = (pWelsSvcRc_Base) ? pWelsSvcRc_Base : pWelsSvcRc; | |
| 651 | +for (i = kiComplexityIndex; i <= iLastGomIndex; i++) { | |
| 652 | +iSumSad += pWelsSvcRc_Base->pCurrentFrameGomSad[i]; | |
| 662 | 653 | } |
| 663 | − | |
| 664 | − | |
| 665 | − | |
| 654 | +if (0 == iSumSad) | |
| 655 | +iAllocateBits = WELS_DIV_ROUND (iLeftBits, (iLastGomIndex - kiComplexityIndex)); | |
| 656 | +else | |
| 657 | +iAllocateBits = WELS_DIV_ROUND ((int64_t)iLeftBits * pWelsSvcRc_Base->pCurrentFrameGomSad[kiComplexityIndex + 1], | |
| 658 | +iSumSad); | |
| 659 | + | |
| 660 | +} | |
| 661 | +pSOverRc->iGomTargetBits = iAllocateBits; | |
| 662 | +} | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | 666 | void RcCalculateGomQp (sWelsEncCtx* pEncCtx, SMB* pCurMb, int32_t iSliceId) { |
| 667 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 668 | − SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[iSliceId]; | |
| 669 | − int64_t iBitsRatio = 1; | |
| 670 | − | |
| 671 | − int64_t iLeftBits = pSOverRc->iTargetBitsSlice - pSOverRc->iFrameBitsSlice; | |
| 672 | − int64_t iTargetLeftBits = iLeftBits + pSOverRc->iGomBitsSlice - pSOverRc->iGomTargetBits; | |
| 673 | − | |
| 674 | − if (iLeftBits <= 0) { | |
| 675 | − pSOverRc->iCalculatedQpSlice += 2; | |
| 676 | − } else { | |
| 677 | − //globe decision | |
| 678 | − iBitsRatio = 10000 * iLeftBits / (iTargetLeftBits + 1); | |
| 679 | − if (iBitsRatio < 8409) //2^(-1.5/6)*10000 | |
| 680 | − pSOverRc->iCalculatedQpSlice += 2; | |
| 681 | − else if (iBitsRatio < 9439) //2^(-0.5/6)*10000 | |
| 682 | − pSOverRc->iCalculatedQpSlice += 1; | |
| 683 | − else if (iBitsRatio > 10600) //2^(0.5/6)*10000 | |
| 684 | − pSOverRc->iCalculatedQpSlice -= 1; | |
| 685 | − else if (iBitsRatio > 11900) //2^(1.5/6)*10000 | |
| 686 | − pSOverRc->iCalculatedQpSlice -= 2; | |
| 687 | − } | |
| 688 | − | |
| 689 | − pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, | |
| 690 | − pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame); | |
| 691 | − if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false))) | |
| 692 | − pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp); | |
| 693 | − | |
| 694 | − pSOverRc->iGomBitsSlice = 0; | |
| 695 | − | |
| 667 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 668 | +SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[iSliceId]; | |
| 669 | +int64_t iBitsRatio = 1; | |
| 670 | + | |
| 671 | +int64_t iLeftBits = pSOverRc->iTargetBitsSlice - pSOverRc->iFrameBitsSlice; | |
| 672 | +int64_t iTargetLeftBits = iLeftBits + pSOverRc->iGomBitsSlice - pSOverRc->iGomTargetBits; | |
| 673 | + | |
| 674 | +if (iLeftBits <= 0) { | |
| 675 | +pSOverRc->iCalculatedQpSlice += 2; | |
| 676 | +} else { | |
| 677 | +//globe decision | |
| 678 | +iBitsRatio = 10000 * iLeftBits / (iTargetLeftBits + 1); | |
| 679 | +if (iBitsRatio < 8409) //2^(-1.5/6)*10000 | |
| 680 | +pSOverRc->iCalculatedQpSlice += 2; | |
| 681 | +else if (iBitsRatio < 9439) //2^(-0.5/6)*10000 | |
| 682 | +pSOverRc->iCalculatedQpSlice += 1; | |
| 683 | +else if (iBitsRatio > 10600) //2^(0.5/6)*10000 | |
| 684 | +pSOverRc->iCalculatedQpSlice -= 1; | |
| 685 | +else if (iBitsRatio > 11900) //2^(1.5/6)*10000 | |
| 686 | +pSOverRc->iCalculatedQpSlice -= 2; | |
| 696 | 687 | } |
| 697 | − | |
| 688 | + | |
| 689 | +pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, | |
| 690 | +pEncCtx->iGlobalQp - pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp + pWelsSvcRc->iQpRangeUpperInFrame); | |
| 691 | +if (! ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE) && (pEncCtx->pSvcParam->bEnableFrameSkip == false))) | |
| 692 | +pSOverRc->iCalculatedQpSlice = WELS_CLIP3 (pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp); | |
| 693 | + | |
| 694 | +pSOverRc->iGomBitsSlice = 0; | |
| 695 | + | |
| 696 | +} | |
| 697 | + | |
| 698 | 698 | void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) { |
| 699 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 700 | − SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 701 | − const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY); | |
| 702 | − //condition 1: whole pBuffer fullness | |
| 703 | − pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits); | |
| 704 | − WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip); | |
| 705 | − //condition 2: VGOP bits constraint | |
| 706 | − int32_t iVGopBitsPred = 0; | |
| 707 | − for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++) | |
| 708 | − iVGopBitsPred += pTOverRc[pWelsSvcRc->iTlOfFrames[i]].iMinBitsTl; | |
| 709 | − iVGopBitsPred -= pWelsSvcRc->iRemainingBits; | |
| 710 | − double dIncPercent = iVGopBitsPred * 100.0 * INT_MULTIPLY / (pWelsSvcRc->iBitsPerFrame * VGOP_SIZE) - | |
| 711 | − (double)VGOP_BITS_PERCENTAGE_DIFF; | |
| 712 | − | |
| 713 | − if ((pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip | |
| 714 | − && pWelsSvcRc->iAverageFrameQp > pWelsSvcRc->iSkipQpValue) | |
| 715 | − || (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) { | |
| 716 | − pEncCtx->iSkipFrameFlag = 1; | |
| 717 | − pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits; | |
| 718 | − WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip); | |
| 719 | − } | |
| 720 | − | |
| 721 | − pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0); | |
| 722 | − | |
| 723 | − if (pEncCtx->iSkipFrameFlag == 1) { | |
| 724 | − pWelsSvcRc->iRemainingBits += kiOutputBits; | |
| 725 | − pWelsSvcRc->iSkipFrameNum++; | |
| 726 | − pWelsSvcRc->iSkipFrameInVGop++; | |
| 727 | − } | |
| 699 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 700 | +SRCTemporal* pTOverRc = pWelsSvcRc->pTemporalOverRc; | |
| 701 | +const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY); | |
| 702 | +//condition 1: whole pBuffer fullness | |
| 703 | +pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits); | |
| 704 | +WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] bits in buffer = %3d", pWelsSvcRc->iBufferFullnessSkip); | |
| 705 | +//condition 2: VGOP bits constraint | |
| 706 | +int32_t iVGopBitsPred = 0; | |
| 707 | +for (int32_t i = pWelsSvcRc->iFrameCodedInVGop + 1; i < VGOP_SIZE; i++) | |
| 708 | +iVGopBitsPred += pTOverRc[pWelsSvcRc->iTlOfFrames[i]].iMinBitsTl; | |
| 709 | +iVGopBitsPred -= pWelsSvcRc->iRemainingBits; | |
| 710 | +double dIncPercent = iVGopBitsPred * 100.0 * INT_MULTIPLY / (pWelsSvcRc->iBitsPerFrame * VGOP_SIZE) - | |
| 711 | +(double)VGOP_BITS_PERCENTAGE_DIFF; | |
| 712 | + | |
| 713 | +if ((pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip | |
| 714 | +&& pWelsSvcRc->iAverageFrameQp > pWelsSvcRc->iSkipQpValue) | |
| 715 | +|| (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) { | |
| 716 | +pEncCtx->iSkipFrameFlag = 1; | |
| 717 | +pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits; | |
| 718 | +WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] bits in buffer = %3d", pWelsSvcRc->iBufferFullnessSkip); | |
| 728 | 719 | } |
| 729 | − | |
| 720 | + | |
| 721 | +pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0); | |
| 722 | + | |
| 723 | +if (pEncCtx->iSkipFrameFlag == 1) { | |
| 724 | +pWelsSvcRc->iRemainingBits += kiOutputBits; | |
| 725 | +pWelsSvcRc->iSkipFrameNum++; | |
| 726 | +pWelsSvcRc->iSkipFrameInVGop++; | |
| 727 | +} | |
| 728 | +} | |
| 729 | + | |
| 730 | 730 | void WelsRcFrameDelayJudge (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp) { |
| 731 | − sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 732 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 733 | − SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 734 | − SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId]; | |
| 735 | − | |
| 736 | − int32_t iSentBits = WELS_ROUND (pDLayerParam->iSpatialBitrate / pDLayerParamInternal->fOutputFrameRate); | |
| 737 | − | |
| 738 | − pWelsSvcRc->bSkipFlag = false; | |
| 739 | − if (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip) { | |
| 740 | − pWelsSvcRc->bSkipFlag = true; | |
| 741 | − pWelsSvcRc->iSkipFrameNum++; | |
| 742 | − pWelsSvcRc->iSkipFrameInVGop++; | |
| 743 | − pWelsSvcRc->iBufferFullnessSkip -= iSentBits; | |
| 744 | − WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,"[Rc] bits in buffer = %3d",pWelsSvcRc->iBufferFullnessSkip); | |
| 745 | − pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0); | |
| 746 | − } | |
| 731 | +sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 732 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 733 | +SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | |
| 734 | +SSpatialLayerInternal* pDLayerParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId]; | |
| 735 | + | |
| 736 | +int32_t iSentBits = WELS_ROUND (pDLayerParam->iSpatialBitrate / pDLayerParamInternal->fOutputFrameRate); | |
| 737 | + | |
| 738 | +pWelsSvcRc->bSkipFlag = false; | |
| 739 | +if (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip) { | |
| 740 | +pWelsSvcRc->bSkipFlag = true; | |
| 741 | +pWelsSvcRc->iSkipFrameNum++; | |
| 742 | +pWelsSvcRc->iSkipFrameInVGop++; | |
| 743 | +pWelsSvcRc->iBufferFullnessSkip -= iSentBits; | |
| 744 | +WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] bits in buffer = %3d", pWelsSvcRc->iBufferFullnessSkip); | |
| 745 | +pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (pWelsSvcRc->iBufferFullnessSkip, 0); | |
| 747 | 746 | } |
| 748 | − | |
| 747 | +} | |
| 748 | + | |
| 749 | 749 | void RcVBufferCalculationPadding (sWelsEncCtx* pEncCtx) { |
| 750 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 751 | − const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY); | |
| 752 | − const int32_t kiBufferThreshold = WELS_DIV_ROUND (PADDING_THRESHOLD * (-pWelsSvcRc->iBufferSizePadding), INT_MULTIPLY); | |
| 753 | − | |
| 754 | − pWelsSvcRc->iBufferFullnessPadding += (pWelsSvcRc->iFrameDqBits - kiOutputBits); | |
| 755 | − | |
| 756 | − if (pWelsSvcRc->iBufferFullnessPadding < kiBufferThreshold) { | |
| 757 | − pWelsSvcRc->iPaddingSize = -pWelsSvcRc->iBufferFullnessPadding; | |
| 758 | − pWelsSvcRc->iPaddingSize >>= 3; // /8 | |
| 759 | − pWelsSvcRc->iBufferFullnessPadding = 0; | |
| 760 | − } else | |
| 761 | − pWelsSvcRc->iPaddingSize = 0; | |
| 750 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 751 | +const int32_t kiOutputBits = WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY); | |
| 752 | +const int32_t kiBufferThreshold = WELS_DIV_ROUND (PADDING_THRESHOLD * (-pWelsSvcRc->iBufferSizePadding), INT_MULTIPLY); | |
| 753 | + | |
| 754 | +pWelsSvcRc->iBufferFullnessPadding += (pWelsSvcRc->iFrameDqBits - kiOutputBits); | |
| 755 | + | |
| 756 | +if (pWelsSvcRc->iBufferFullnessPadding < kiBufferThreshold) { | |
| 757 | +pWelsSvcRc->iPaddingSize = -pWelsSvcRc->iBufferFullnessPadding; | |
| 758 | +pWelsSvcRc->iPaddingSize >>= 3; // /8 | |
| 759 | +pWelsSvcRc->iBufferFullnessPadding = 0; | |
| 760 | +} else | |
| 761 | +pWelsSvcRc->iPaddingSize = 0; | |
| 762 | 762 | } |
| 763 | − | |
| 764 | − | |
| 763 | + | |
| 764 | + | |
| 765 | 765 | void RcTraceFrameBits (void* pCtx, long long uiTimeStamp) { |
| 766 | − sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 767 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 768 | − | |
| 769 | − WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, | |
| 770 | − "[Rc] Frame timestamp = %8d, Frame type =%d, encoding_qp%d, average qp = %3d, max qp = %3d, min qp = %3d, index = %8d,\ | |
| 766 | +sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 767 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 768 | + | |
| 769 | +WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, | |
| 770 | +"[Rc] Frame timestamp = %8d, Frame type =%d, encoding_qp%d, average qp = %3d, max qp = %3d, min qp = %3d, index = %8d,\ | |
| 771 | 771 | iTid = %1d, used = %8d, bitsperframe = %8d, target = %8d, remaingbits = %8d, skipbuffersize = %8d", |
| 772 | − (uint32_t)uiTimeStamp,pEncCtx->eSliceType, pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp,pWelsSvcRc->iMaxFrameQp,pWelsSvcRc->iMinFrameQp, | |
| 773 | − pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits,WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, INT_MULTIPLY), | |
| 774 | − pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits, pWelsSvcRc->iBufferSizeSkip); | |
| 775 | − | |
| 772 | +(uint32_t)uiTimeStamp, pEncCtx->eSliceType, pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp, | |
| 773 | +pWelsSvcRc->iMaxFrameQp, pWelsSvcRc->iMinFrameQp, | |
| 774 | +pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits, WELS_DIV_ROUND (pWelsSvcRc->iBitsPerFrame, | |
| 775 | +INT_MULTIPLY), | |
| 776 | +pWelsSvcRc->iTargetBits, pWelsSvcRc->iRemainingBits, pWelsSvcRc->iBufferSizeSkip); | |
| 777 | + | |
| 776 | 778 | } |
| 777 | − | |
| 779 | + | |
| 778 | 780 | void RcUpdatePictureQpBits (sWelsEncCtx* pEncCtx, int32_t iCodedBits) { |
| 779 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 780 | − SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[0]; | |
| 781 | − SSliceCtx* pCurSliceCtx = pEncCtx->pCurDqLayer->pSliceEncCtx; | |
| 782 | − int32_t iTotalQp = 0, iTotalMb = 0; | |
| 783 | − int32_t i; | |
| 784 | − | |
| 785 | − if (pEncCtx->eSliceType == P_SLICE) { | |
| 786 | − for (i = 0; i < pCurSliceCtx->iSliceNumInFrame; i++) { | |
| 787 | − iTotalQp += pSOverRc->iTotalQpSlice; | |
| 788 | − iTotalMb += pSOverRc->iTotalMbSlice; | |
| 789 | − ++ pSOverRc; | |
| 790 | − } | |
| 791 | − if (iTotalMb > 0) | |
| 792 | − pWelsSvcRc->iAverageFrameQp = WELS_DIV_ROUND (INT_MULTIPLY * iTotalQp, iTotalMb * INT_MULTIPLY); | |
| 793 | − else | |
| 794 | − pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; | |
| 795 | − } else { | |
| 796 | − pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; | |
| 797 | − } | |
| 798 | − pWelsSvcRc->iFrameDqBits = iCodedBits; | |
| 799 | − pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId].iGopBitsDq += pWelsSvcRc->iFrameDqBits; | |
| 781 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 782 | +SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[0]; | |
| 783 | +SSliceCtx* pCurSliceCtx = pEncCtx->pCurDqLayer->pSliceEncCtx; | |
| 784 | +int32_t iTotalQp = 0, iTotalMb = 0; | |
| 785 | +int32_t i; | |
| 786 | + | |
| 787 | +if (pEncCtx->eSliceType == P_SLICE) { | |
| 788 | +for (i = 0; i < pCurSliceCtx->iSliceNumInFrame; i++) { | |
| 789 | +iTotalQp += pSOverRc->iTotalQpSlice; | |
| 790 | +iTotalMb += pSOverRc->iTotalMbSlice; | |
| 791 | +++ pSOverRc; | |
| 800 | 792 | } |
| 801 | − | |
| 793 | +if (iTotalMb > 0) | |
| 794 | +pWelsSvcRc->iAverageFrameQp = WELS_DIV_ROUND (INT_MULTIPLY * iTotalQp, iTotalMb * INT_MULTIPLY); | |
| 795 | +else | |
| 796 | +pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; | |
| 797 | +} else { | |
| 798 | +pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; | |
| 799 | +} | |
| 800 | +pWelsSvcRc->iFrameDqBits = iCodedBits; | |
| 801 | +pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId].iGopBitsDq += pWelsSvcRc->iFrameDqBits; | |
| 802 | +} | |
| 803 | + | |
| 802 | 804 | void RcUpdateIntraComplexity (sWelsEncCtx* pEncCtx) { |
| 803 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 804 | − int32_t iAlpha = WELS_DIV_ROUND (INT_MULTIPLY, (1 + pWelsSvcRc->iIdrNum)); | |
| 805 | − if (iAlpha < (INT_MULTIPLY / 4)) iAlpha = INT_MULTIPLY / 4; | |
| 806 | − | |
| 807 | − int64_t iIntraCmplx = pWelsSvcRc->iQStep * pWelsSvcRc->iFrameDqBits; | |
| 808 | − pWelsSvcRc->iIntraComplexity = WELS_DIV_ROUND (((INT_MULTIPLY - iAlpha) * pWelsSvcRc->iIntraComplexity + iAlpha * | |
| 809 | − iIntraCmplx), INT_MULTIPLY); | |
| 810 | − pWelsSvcRc->iIntraMbCount = pWelsSvcRc->iNumberMbFrame; | |
| 811 | − | |
| 812 | − pWelsSvcRc->iIdrNum++; | |
| 813 | − if (pWelsSvcRc->iIdrNum > 255) | |
| 814 | − pWelsSvcRc->iIdrNum = 255; | |
| 805 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 806 | +int32_t iAlpha = WELS_DIV_ROUND (INT_MULTIPLY, (1 + pWelsSvcRc->iIdrNum)); | |
| 807 | +if (iAlpha < (INT_MULTIPLY / 4)) iAlpha = INT_MULTIPLY / 4; | |
| 808 | + | |
| 809 | +int64_t iIntraCmplx = pWelsSvcRc->iQStep * pWelsSvcRc->iFrameDqBits; | |
| 810 | +pWelsSvcRc->iIntraComplexity = WELS_DIV_ROUND (((INT_MULTIPLY - iAlpha) * pWelsSvcRc->iIntraComplexity + iAlpha * | |
| 811 | +iIntraCmplx), INT_MULTIPLY); | |
| 812 | +pWelsSvcRc->iIntraMbCount = pWelsSvcRc->iNumberMbFrame; | |
| 813 | + | |
| 814 | +pWelsSvcRc->iIdrNum++; | |
| 815 | +if (pWelsSvcRc->iIdrNum > 255) | |
| 816 | +pWelsSvcRc->iIdrNum = 255; | |
| 815 | 817 | } |
| 816 | − | |
| 818 | + | |
| 817 | 819 | void RcUpdateFrameComplexity (sWelsEncCtx* pEncCtx) { |
| 818 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 819 | − const int32_t kiTl = pEncCtx->uiTemporalId; | |
| 820 | − SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[kiTl]; | |
| 821 | − | |
| 822 | − if (0 == pTOverRc->iPFrameNum) { | |
| 823 | − pTOverRc->iLinearCmplx = ((int64_t)pWelsSvcRc->iFrameDqBits) * pWelsSvcRc->iQStep; | |
| 824 | − } else { | |
| 825 | − pTOverRc->iLinearCmplx = WELS_DIV_ROUND64 ((LINEAR_MODEL_DECAY_FACTOR * (int64_t)pTOverRc->iLinearCmplx | |
| 826 | − + (INT_MULTIPLY - LINEAR_MODEL_DECAY_FACTOR) * (int64_t) (pWelsSvcRc->iFrameDqBits * pWelsSvcRc->iQStep)), | |
| 827 | − INT_MULTIPLY); | |
| 828 | − } | |
| 829 | − int32_t iAlpha = WELS_DIV_ROUND (INT_MULTIPLY, (1 + pTOverRc->iPFrameNum)); | |
| 830 | − if (iAlpha < SMOOTH_FACTOR_MIN_VALUE) | |
| 831 | − iAlpha = SMOOTH_FACTOR_MIN_VALUE; | |
| 832 | − pTOverRc->iFrameCmplxMean = WELS_DIV_ROUND (((INT_MULTIPLY - iAlpha) * pTOverRc->iFrameCmplxMean + iAlpha * | |
| 833 | − pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity), INT_MULTIPLY); | |
| 834 | − | |
| 835 | − pTOverRc->iPFrameNum++; | |
| 836 | − if (pTOverRc->iPFrameNum > 255) | |
| 837 | − pTOverRc->iPFrameNum = 255; | |
| 820 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 821 | +const int32_t kiTl = pEncCtx->uiTemporalId; | |
| 822 | +SRCTemporal* pTOverRc = &pWelsSvcRc->pTemporalOverRc[kiTl]; | |
| 823 | + | |
| 824 | +if (0 == pTOverRc->iPFrameNum) { | |
| 825 | +pTOverRc->iLinearCmplx = ((int64_t)pWelsSvcRc->iFrameDqBits) * pWelsSvcRc->iQStep; | |
| 826 | +} else { | |
| 827 | +pTOverRc->iLinearCmplx = WELS_DIV_ROUND64 ((LINEAR_MODEL_DECAY_FACTOR * (int64_t)pTOverRc->iLinearCmplx | |
| 828 | ++ (INT_MULTIPLY - LINEAR_MODEL_DECAY_FACTOR) * (int64_t) (pWelsSvcRc->iFrameDqBits * pWelsSvcRc->iQStep)), | |
| 829 | +INT_MULTIPLY); | |
| 838 | 830 | } |
| 839 | − | |
| 831 | +int32_t iAlpha = WELS_DIV_ROUND (INT_MULTIPLY, (1 + pTOverRc->iPFrameNum)); | |
| 832 | +if (iAlpha < SMOOTH_FACTOR_MIN_VALUE) | |
| 833 | +iAlpha = SMOOTH_FACTOR_MIN_VALUE; | |
| 834 | +pTOverRc->iFrameCmplxMean = WELS_DIV_ROUND (((INT_MULTIPLY - iAlpha) * pTOverRc->iFrameCmplxMean + iAlpha * | |
| 835 | +pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity), INT_MULTIPLY); | |
| 836 | + | |
| 837 | +pTOverRc->iPFrameNum++; | |
| 838 | +if (pTOverRc->iPFrameNum > 255) | |
| 839 | +pTOverRc->iPFrameNum = 255; | |
| 840 | +} | |
| 841 | + | |
| 840 | 842 | int32_t RcCalculateCascadingQp (struct TagWelsEncCtx* pEncCtx, int32_t iQp) { |
| 841 | − int32_t iTemporalQp = 0; | |
| 842 | − if (pEncCtx->pSvcParam->iDecompStages) { | |
| 843 | − if (pEncCtx->uiTemporalId == 0) | |
| 844 | − iTemporalQp = iQp - 3 - (pEncCtx->pSvcParam->iDecompStages - 1); | |
| 845 | − else | |
| 846 | − iTemporalQp = iQp - (pEncCtx->pSvcParam->iDecompStages - pEncCtx->uiTemporalId); | |
| 847 | − iTemporalQp = WELS_CLIP3 (iTemporalQp, 1, 51); | |
| 848 | − } else | |
| 849 | − iTemporalQp = iQp; | |
| 850 | − return iTemporalQp; | |
| 843 | +int32_t iTemporalQp = 0; | |
| 844 | +if (pEncCtx->pSvcParam->iDecompStages) { | |
| 845 | +if (pEncCtx->uiTemporalId == 0) | |
| 846 | +iTemporalQp = iQp - 3 - (pEncCtx->pSvcParam->iDecompStages - 1); | |
| 847 | +else | |
| 848 | +iTemporalQp = iQp - (pEncCtx->pSvcParam->iDecompStages - pEncCtx->uiTemporalId); | |
| 849 | +iTemporalQp = WELS_CLIP3 (iTemporalQp, 1, 51); | |
| 850 | +} else | |
| 851 | +iTemporalQp = iQp; | |
| 852 | +return iTemporalQp; | |
| 851 | 853 | } |
| 852 | − | |
| 854 | + | |
| 853 | 855 | void WelsRcPictureInitGom (void* pCtx) { |
| 854 | − sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 855 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 856 | − | |
| 857 | − if (pEncCtx->eSliceType == I_SLICE) { | |
| 858 | − if (0 == pWelsSvcRc->iIdrNum) { //iIdrNum == 0 means encoder has been initialed | |
| 859 | − RcInitRefreshParameter (pEncCtx); | |
| 860 | − } | |
| 861 | − } | |
| 862 | − if (RcJudgeBitrateFpsUpdate (pEncCtx)) { | |
| 863 | − RcUpdateBitrateFps (pEncCtx); | |
| 864 | − } | |
| 865 | − if (pEncCtx->uiTemporalId == 0) { | |
| 866 | − RcUpdateTemporalZero (pEncCtx); | |
| 867 | − } | |
| 868 | − RcDecideTargetBits (pEncCtx); | |
| 869 | − //decide globe_qp | |
| 870 | − if (pEncCtx->eSliceType == I_SLICE) { | |
| 871 | − if (0 == pWelsSvcRc->iIdrNum) | |
| 872 | − RcInitIdrQp (pEncCtx); | |
| 873 | − else { | |
| 874 | − RcCalculateIdrQp (pEncCtx); | |
| 875 | − } | |
| 876 | − } else { | |
| 877 | − RcCalculatePictureQp (pEncCtx); | |
| 878 | − } | |
| 879 | − RcInitSliceInformation (pEncCtx); | |
| 880 | − RcInitGomParameters (pEncCtx); | |
| 881 | − | |
| 856 | +sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 857 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 858 | + | |
| 859 | +if (pEncCtx->eSliceType == I_SLICE) { | |
| 860 | +if (0 == pWelsSvcRc->iIdrNum) { //iIdrNum == 0 means encoder has been initialed | |
| 861 | +RcInitRefreshParameter (pEncCtx); | |
| 882 | 862 | } |
| 883 | − | |
| 884 | − | |
| 885 | − | |
| 863 | +} | |
| 864 | +if (RcJudgeBitrateFpsUpdate (pEncCtx)) { | |
| 865 | +RcUpdateBitrateFps (pEncCtx); | |
| 866 | +} | |
| 867 | +if (pEncCtx->uiTemporalId == 0) { | |
| 868 | +RcUpdateTemporalZero (pEncCtx); | |
| 869 | +} | |
| 870 | +RcDecideTargetBits (pEncCtx); | |
| 871 | +//decide globe_qp | |
| 872 | +if (pEncCtx->eSliceType == I_SLICE) { | |
| 873 | +if (0 == pWelsSvcRc->iIdrNum) | |
| 874 | +RcInitIdrQp (pEncCtx); | |
| 875 | +else { | |
| 876 | +RcCalculateIdrQp (pEncCtx); | |
| 877 | +} | |
| 878 | +} else { | |
| 879 | +RcCalculatePictureQp (pEncCtx); | |
| 880 | +} | |
| 881 | +RcInitSliceInformation (pEncCtx); | |
| 882 | +RcInitGomParameters (pEncCtx); | |
| 883 | + | |
| 884 | +} | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 886 | 888 | void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t iLayerSize) { |
| 887 | − sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 888 | − SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 889 | − int32_t iCodedBits = (iLayerSize << 3); | |
| 890 | − | |
| 891 | − RcUpdatePictureQpBits (pEncCtx, iCodedBits); | |
| 892 | − | |
| 893 | − if (pEncCtx->eSliceType == P_SLICE) { | |
| 894 | − RcUpdateFrameComplexity (pEncCtx); | |
| 895 | − } else { | |
| 896 | − RcUpdateIntraComplexity (pEncCtx); | |
| 897 | − } | |
| 898 | − pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits; | |
| 899 | − | |
| 900 | − if (pEncCtx->pSvcParam->bEnableFrameSkip /*&& | |
| 889 | +sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | |
| 890 | +SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | |
| 891 | +int32_t iCodedBits = (iLayerSize << 3); | |
| 892 | + | |
| 893 | +RcUpdatePictureQpBits (pEncCtx, iCodedBits); | |
| 894 | + | |
| 895 | +if (pEncCtx->eSliceType == P_SLICE) { | |
| 896 | +RcUpdateFrameComplexity (pEncCtx); | |
| 897 | +} else { | |
| 898 | +RcUpdateIntraComplexity (pEncCtx); | |
| 899 | +} | |
| 900 | +pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits; | |
| 901 | + | |
| 902 | +if (pEncCtx->pSvcParam->bEnableFrameSkip /*&& | |
| 901 | 903 | pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iSpatialLayerNum - 1*/) { |
| 902 | − RcVBufferCalculationSkip (pEncCtx); | |
| 903 | − } | |
| 904 | +RcVBufferCalculationSkip (pEncCtx); | |
| 905 | +} | |
| 904 | 906 | |
| 905 | − if (pEncCtx->pSvcParam->iPaddingFlag) | |
| 906 | − RcVBufferCalculationPadding (pEncCtx); | |
| 907 | − pWelsSvcRc->iFrameCodedInVGop++; | |
| 907 | +if (pEncCtx->pSvcParam->iPaddingFlag) | |
| 908 | + RcVBufferCalculationPadding (pEncCtx); | |
| 909 | +pWelsSvcRc->iFrameCodedInVGop++; | |
| 908 | 910 | #ifdef _TEST_TEMP_Rc_ |
| 909 | − fprintf (fp_test_rc, "%d\n", pWelsSvcRc->iFrameDqBits); | |
| 910 | − if (pEncCtx->iSkipFrameFlag) | |
| 911 | − fprintf (fp_test_rc, "0\n"); | |
| 912 | − fflush (fp_test_rc); | |
| 911 | +fprintf (fp_test_rc, "%d\n", pWelsSvcRc->iFrameDqBits); | |
| 912 | +if (pEncCtx->iSkipFrameFlag) | |
| 913 | + fprintf (fp_test_rc, "0\n"); | |
| 914 | +fflush (fp_test_rc); | |
| 913 | 915 | #endif |
| 914 | 916 | } |
| 915 | 917 | |
| @@ -955,8 +957,8 @@ void WelsRcMbInfoUpdateGom (void* pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice* · 39 unmodified lines | ||
| 955 | 957 | |
| 956 | 958 | pWelsSvcRc->pGomCost[kiComplexityIndex] += iCostLuma; |
| 957 | 959 | |
| 958 | − pWelsSvcRc->iMinFrameQp = WELS_MIN(pWelsSvcRc->iMinFrameQp,pCurMb->uiLumaQp); | |
| 959 | − pWelsSvcRc->iMaxFrameQp = WELS_MAX(pWelsSvcRc->iMaxFrameQp,pCurMb->uiLumaQp); | |
| 960 | + pWelsSvcRc->iMinFrameQp = WELS_MIN (pWelsSvcRc->iMinFrameQp, pCurMb->uiLumaQp); | |
| 961 | + pWelsSvcRc->iMaxFrameQp = WELS_MAX (pWelsSvcRc->iMaxFrameQp, pCurMb->uiLumaQp); | |
| 960 | 962 | if (iCurMbBits > 0) { |
| 961 | 963 | pSOverRc->iTotalQpSlice += pCurMb->uiLumaQp; |
| 962 | 964 | pSOverRc->iTotalMbSlice++; |
| @@ -1054,7 +1056,7 @@ void WelRcPictureInitScc (void* pCtx) { · 91 unmodified lines | ||
| 1054 | 1056 | pEncCtx->iGlobalQp = WELS_CLIP3 (iQp, MIN_IDR_QP, MAX_IDR_QP); |
| 1055 | 1057 | } else { |
| 1056 | 1058 | int32_t iTargetBits = WELS_ROUND (((float)iBitRate / pDLayerConfig->fFrameRate)); //iBitRate / 10; |
| 1057 | − int32_t iQstep = (int32_t)(WELS_DIV_ROUND64 (iFrameCplx * pWelsSvcRc->iAvgCost2Bits, iTargetBits)); | |
| 1059 | + int32_t iQstep = (int32_t) (WELS_DIV_ROUND64 (iFrameCplx * pWelsSvcRc->iAvgCost2Bits, iTargetBits)); | |
| 1058 | 1060 | int32_t iQp = RcConvertQStep2Qp (iQstep); |
| 1059 | 1061 | iDeltaQp = iQp - iBaseQp; |
| 1060 | 1062 | if (pWelsSvcRc->iBufferFullnessSkip > iBitRate) { |
| @@ -1108,7 +1110,7 @@ void WelsRcFrameDelayJudgeScc (void* pCtx, EVideoFrameType eFrameType, long long · 47 unmodified lines | ||
| 1108 | 1110 | iSentBits = WELS_MAX (iSentBits, 0); |
| 1109 | 1111 | |
| 1110 | 1112 | const int32_t iVbufferThRatio = (eFrameType == videoFrameTypeI |
| 1111 | − || eFrameType == videoFrameTypeIDR) ? VIRTUAL_BUFFER_HIGH_TH : VIRTUAL_BUFFER_LOW_TH; | |
| 1113 | + || eFrameType == videoFrameTypeIDR) ? VIRTUAL_BUFFER_HIGH_TH : VIRTUAL_BUFFER_LOW_TH; | |
| 1112 | 1114 | const int32_t iVbufferTh = WELS_DIV_ROUND ((((int64_t)iBitRate) * iVbufferThRatio), INT_MULTIPLY); |
| 1113 | 1115 | |
| 1114 | 1116 | pWelsSvcRc->iBufferFullnessSkip -= iSentBits; |
| @@ -1120,7 +1122,9 @@ void WelsRcFrameDelayJudgeScc (void* pCtx, EVideoFrameType eFrameType, long long · 5 unmodified lines | ||
| 1120 | 1122 | } |
| 1121 | 1123 | if (pWelsSvcRc->bSkipFlag) { |
| 1122 | 1124 | pWelsSvcRc->iSkipFrameNum++; |
| 1123 | − WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "SCC iSkipFrameNum = %d,buffer = %d,threadhold = %d,bitrate = %d,timestamp=%lld\n", pWelsSvcRc->iSkipFrameNum,pWelsSvcRc->iBufferFullnessSkip,iVbufferTh,iBitRate,uiTimeStamp); | |
| 1125 | + WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, | |
| 1126 | + "SCC iSkipFrameNum = %d,buffer = %d,threadhold = %d,bitrate = %d,timestamp=%lld\n", pWelsSvcRc->iSkipFrameNum, | |
| 1127 | + pWelsSvcRc->iBufferFullnessSkip, iVbufferTh, iBitRate, uiTimeStamp); | |
| 1124 | 1128 | } |
| 1125 | 1129 | pWelsSvcRc->uiLastTimeStamp = uiTimeStamp; |
| 1126 | 1130 | } |