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