Showing the changes to codec/encoder/core/src/ratectl.cpp (1 of 6 files). Show all
Unified · Split
| @@ -49,6 +49,14 @@ · 48 unmodified lines | |||
| 49 | 49 | ||
| 50 | namespace WelsEnc { | 50 | namespace WelsEnc { |
| 51 | 51 | ||
| 52 | #define COST2BITS_INIT 0.33 | ||
| 53 | #define COMPRESS_RATIO_I_P 3 | ||
| 54 | #define COST2BITS_INIT_P (COST2BITS_INIT/COMPRESS_RATIO_I_P) | ||
| 55 | |||
| 56 | |||
| 57 | #define VIRTUAL_BUFFER_LOW_TH 0.1 | ||
| 58 | #define VIRTUAL_BUFFER_HIGH_TH 2.5 | ||
| 59 | |||
| 52 | //#define _TEST_TEMP_RC_ | 60 | //#define _TEST_TEMP_RC_ |
| 53 | #ifdef _TEST_TEMP_RC_ | 61 | #ifdef _TEST_TEMP_RC_ |
| 54 | //#define _NOT_USE_AQ_FOR_TEST_ | 62 | //#define _NOT_USE_AQ_FOR_TEST_ |
| @@ -720,7 +728,7 @@ void RcVBufferCalculationSkip (sWelsEncCtx* pEncCtx) { · 665 unmodified lines | |||
| 720 | } | 728 | } |
| 721 | } | 729 | } |
| 722 | 730 | ||
| 723 | void WelsRcFrameDelayJudge (void* pCtx) { | 731 | void WelsRcFrameDelayJudge (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp) { |
| 724 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | 732 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; |
| 725 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | 733 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; |
| 726 | SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | 734 | SSpatialLayerConfig* pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; |
| @@ -872,10 +880,10 @@ void WelsRcPictureInitGom (void* pCtx) { · 145 unmodified lines | |||
| 872 | 880 | ||
| 873 | 881 | ||
| 874 | 882 | ||
| 875 | void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t layer_size) { | 883 | void WelsRcPictureInfoUpdateGom (void* pCtx, int32_t iLayerSize) { |
| 876 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | 884 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; |
| 877 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | 885 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; |
| 878 | int32_t iCodedBits = (layer_size << 3); | 886 | int32_t iCodedBits = (iLayerSize << 3); |
| 879 | 887 | ||
| 880 | RcUpdatePictureQpBits (pEncCtx, iCodedBits); | 888 | RcUpdatePictureQpBits (pEncCtx, iCodedBits); |
| 881 | 889 | ||
| @@ -970,7 +978,7 @@ void WelsRcPictureInitDisable (void* pCtx) { · 88 unmodified lines | |||
| 970 | pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; | 978 | pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; |
| 971 | } | 979 | } |
| 972 | 980 | ||
| 973 | void WelsRcPictureInfoUpdateDisable (void* pCtx, int32_t layer_size) { | 981 | void WelsRcPictureInfoUpdateDisable (void* pCtx, int32_t iLayerSize) { |
| 974 | } | 982 | } |
| 975 | 983 | ||
| 976 | void WelsRcMbInitDisable (void* pCtx, SMB* pCurMb, SSlice* pSlice) { | 984 | void WelsRcMbInitDisable (void* pCtx, SMB* pCurMb, SSlice* pSlice) { |
| @@ -1011,6 +1019,146 @@ void WelRcPictureInitBufferBasedQp (void* pCtx) { · 34 unmodified lines | |||
| 1011 | pEncCtx->iGlobalQp += 2; | 1019 | pEncCtx->iGlobalQp += 2; |
| 1012 | pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, iMinQp, MAX_SCREEN_QP); | 1020 | pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, iMinQp, MAX_SCREEN_QP); |
| 1013 | } | 1021 | } |
| 1022 | |||
| 1023 | void InitRcModuleScc (void* pCtx) { | ||
| 1024 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | ||
| 1025 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | ||
| 1026 | pWelsSvcRc->iBaseQp = 30; | ||
| 1027 | |||
| 1028 | pWelsSvcRc->iBufferFullnessSkip = 0; | ||
| 1029 | pWelsSvcRc->uiLastTimeStamp = 0; | ||
| 1030 | |||
| 1031 | SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[0]; | ||
| 1032 | double dResoRatio = (pDLayerConfig->iVideoWidth * pDLayerConfig->iVideoHeight / 1024.0) / 768.0 * 0.8; | ||
| 1033 | |||
| 1034 | pWelsSvcRc->dCost2BitsIntra = COST2BITS_INIT * dResoRatio; | ||
| 1035 | pWelsSvcRc->dAvgCost2Bits = COST2BITS_INIT_P * dResoRatio; | ||
| 1036 | } | ||
| 1037 | void WelRcPictureInitScc (void* pCtx) { | ||
| 1038 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | ||
| 1039 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId]; | ||
| 1040 | SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa); | ||
| 1041 | SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | ||
| 1042 | int32_t iFrameCplx = pVaa->sComplexityScreenParam.iFrameComplexity; | ||
| 1043 | int32_t iBitRate = pDLayerConfig->iSpatialBitrate;// pEncCtx->pSvcParam->target_bitrate; | ||
| 1044 | |||
| 1045 | int32_t iBaseQp = pWelsSvcRc->iBaseQp; | ||
| 1046 | pEncCtx->iGlobalQp = iBaseQp; | ||
| 1047 | int32_t iDeltaQp = 0; | ||
| 1048 | if (pEncCtx->eSliceType == I_SLICE) { | ||
| 1049 | int32_t iTargetBits = iBitRate * 2 - pWelsSvcRc->iBufferFullnessSkip; | ||
| 1050 | iTargetBits = WELS_MAX (1, iTargetBits); | ||
| 1051 | double Qstep = iFrameCplx * pWelsSvcRc->dCost2BitsIntra / iTargetBits; | ||
| 1052 | int32_t iQp = RcConvertQStep2Qp ((int32_t)Qstep); | ||
| 1053 | |||
| 1054 | pEncCtx->iGlobalQp = WELS_CLIP3 (iQp, MIN_IDR_QP, MAX_IDR_QP); | ||
| 1055 | } else { | ||
| 1056 | int32_t iTargetBits = (int32_t) ((float)iBitRate / pDLayerConfig->fFrameRate); //iBitRate / 10; | ||
| 1057 | double Qstep = iFrameCplx * pWelsSvcRc->dAvgCost2Bits / iTargetBits; | ||
| 1058 | int32_t iQp = RcConvertQStep2Qp ((int32_t)Qstep); | ||
| 1059 | iDeltaQp = iQp - iBaseQp; | ||
| 1060 | if (pWelsSvcRc->iBufferFullnessSkip > iBitRate) { | ||
| 1061 | if (iDeltaQp > 0) { | ||
| 1062 | ++iBaseQp; | ||
| 1063 | } | ||
| 1064 | } else if (pWelsSvcRc->iBufferFullnessSkip == 0) { | ||
| 1065 | if (iDeltaQp < 0) { | ||
| 1066 | --iBaseQp; | ||
| 1067 | } | ||
| 1068 | } | ||
| 1069 | if (iDeltaQp >= 6) { | ||
| 1070 | iBaseQp += 3; | ||
| 1071 | } else if ((iDeltaQp <= -6)) { | ||
| 1072 | --iBaseQp; | ||
| 1073 | } | ||
| 1074 | iBaseQp = WELS_CLIP3 (iBaseQp, MIN_IDR_QP, MAX_IDR_QP); | ||
| 1075 | |||
| 1076 | pEncCtx->iGlobalQp = iBaseQp; | ||
| 1077 | |||
| 1078 | |||
| 1079 | if (iDeltaQp < -6) { | ||
| 1080 | pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp - 6, MIN_SCREEN_QP, MAX_SCREEN_QP); | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | if (iDeltaQp > 5) { | ||
| 1084 | if (LARGE_CHANGED_SCENE == pEncCtx->pVaa->eSceneChangeIdc || pWelsSvcRc->iBufferFullnessSkip > 2 * iBitRate | ||
| 1085 | || iDeltaQp > 10) { | ||
| 1086 | pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp + iDeltaQp, MIN_SCREEN_QP, MAX_SCREEN_QP); | ||
| 1087 | } else if (MEDIUM_CHANGED_SCENE == pEncCtx->pVaa->eSceneChangeIdc || pWelsSvcRc->iBufferFullnessSkip > iBitRate) { | ||
| 1088 | pEncCtx->iGlobalQp = WELS_CLIP3 (pWelsSvcRc->iBaseQp + 5, MIN_SCREEN_QP, MAX_SCREEN_QP); | ||
| 1089 | } | ||
| 1090 | } | ||
| 1091 | pWelsSvcRc->iBaseQp = iBaseQp; | ||
| 1092 | } | ||
| 1093 | pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp; | ||
| 1094 | WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG, "WelRcPictureInitScc iLumaQp = %d\n", pEncCtx->iGlobalQp); | ||
| 1095 | |||
| 1096 | } | ||
| 1097 | void WelsRcFrameDelayJudgeScc (void* pCtx, EVideoFrameType eFrameType, long long uiTimeStamp) { | ||
| 1098 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | ||
| 1099 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0]; | ||
| 1100 | SSpatialLayerConfig* pDLayerConfig = &pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId]; | ||
| 1101 | |||
| 1102 | if (pDLayerConfig->iSpatialBitrate > pDLayerConfig->iMaxSpatialBitrate) | ||
| 1103 | pDLayerConfig->iSpatialBitrate = pDLayerConfig->iMaxSpatialBitrate; | ||
| 1104 | |||
| 1105 | int32_t iBitRate = pDLayerConfig->iSpatialBitrate; | ||
| 1106 | int32_t iEncTimeInv = (pWelsSvcRc->uiLastTimeStamp == 0) ? 0 : (int32_t) (uiTimeStamp - pWelsSvcRc->uiLastTimeStamp); | ||
| 1107 | int32_t iSentBits = (int32_t) ((double)iBitRate * iEncTimeInv * (1.0E-3) + 0.5); | ||
| 1108 | iSentBits = WELS_MAX (iSentBits, 0); | ||
| 1109 | |||
| 1110 | const double dVbufferThRatio = (eFrameType == videoFrameTypeI | ||
| 1111 | || eFrameType == videoFrameTypeIDR) ? VIRTUAL_BUFFER_LOW_TH : VIRTUAL_BUFFER_HIGH_TH; | ||
| 1112 | const int32_t iVbufferTh = (int32_t) (iBitRate * dVbufferThRatio + 0.5); | ||
| 1113 | |||
| 1114 | pWelsSvcRc->iBufferFullnessSkip -= iSentBits; | ||
| 1115 | pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip); | ||
| 1116 | |||
| 1117 | pWelsSvcRc->bSkipFlag = true; | ||
| 1118 | if (pWelsSvcRc->iBufferFullnessSkip < iVbufferTh) { | ||
| 1119 | pWelsSvcRc->bSkipFlag = false; | ||
| 1120 | } | ||
| 1121 | pWelsSvcRc->uiLastTimeStamp = uiTimeStamp; | ||
| 1122 | } | ||
| 1123 | |||
| 1124 | void WelsRcDropFrameUpdate (void* pCtx, uint32_t iDropSize) { | ||
| 1125 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | ||
| 1126 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0]; | ||
| 1127 | |||
| 1128 | pWelsSvcRc->iBufferFullnessSkip -= (int32_t)iDropSize; | ||
| 1129 | pWelsSvcRc->iBufferFullnessSkip = WELS_MAX (0, pWelsSvcRc->iBufferFullnessSkip); | ||
| 1130 | WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "[WelsRcDropFrameUpdate:\tdrop:%d\t%d\n", iDropSize, | ||
| 1131 | pWelsSvcRc->iBufferFullnessSkip); | ||
| 1132 | } | ||
| 1133 | |||
| 1134 | void WelsRcPictureInfoUpdateScc (void* pCtx, int32_t iNalSize) { | ||
| 1135 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | ||
| 1136 | |||
| 1137 | SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[0]; | ||
| 1138 | int32_t iFrameBits = (iNalSize << 3); | ||
| 1139 | pWelsSvcRc->iBufferFullnessSkip += iFrameBits; | ||
| 1140 | |||
| 1141 | SVAAFrameInfoExt* pVaa = static_cast<SVAAFrameInfoExt*> (pEncCtx->pVaa); | ||
| 1142 | |||
| 1143 | double Qstep = RcConvertQp2QStep (pEncCtx->iGlobalQp); | ||
| 1144 | double dCost2Bits = (iFrameBits * Qstep) / (double) (pVaa->sComplexityScreenParam.iFrameComplexity + 1.0); | ||
| 1145 | |||
| 1146 | if (pEncCtx->eSliceType == P_SLICE) { | ||
| 1147 | pWelsSvcRc->dAvgCost2Bits = 0.95 * pWelsSvcRc->dAvgCost2Bits + 0.05 * dCost2Bits; | ||
| 1148 | } else { | ||
| 1149 | pWelsSvcRc->dCost2BitsIntra = 0.9 * pWelsSvcRc->dCost2BitsIntra + 0.1 * dCost2Bits; | ||
| 1150 | } | ||
| 1151 | } | ||
| 1152 | |||
| 1153 | |||
| 1154 | void WelsRcMbInitScc (void* pCtx, SMB* pCurMb, SSlice* pSlice) { | ||
| 1155 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | ||
| 1156 | |||
| 1157 | /* Get delta iQp of this MB */ | ||
| 1158 | pCurMb->uiLumaQp = pEncCtx->iGlobalQp; | ||
| 1159 | pCurMb->uiChromaQp = g_kuiChromaQpTable[WELS_CLIP3 (pCurMb->uiLumaQp + pEncCtx->pPps->uiChromaQpIndexOffset, 0, 51)]; | ||
| 1160 | } | ||
| 1161 | |||
| 1014 | void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) { | 1162 | void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) { |
| 1015 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; | 1163 | sWelsEncCtx* pEncCtx = (sWelsEncCtx*)pCtx; |
| 1016 | SWelsRcFunc* pRcf = &pEncCtx->pFuncList->pfRc; | 1164 | SWelsRcFunc* pRcf = &pEncCtx->pFuncList->pfRc; |
| @@ -1030,8 +1178,24 @@ void WelsRcInitModule (void* pCtx, RC_MODES iRcMode) { · 13 unmodified lines | |||
| 1030 | pRcf->pfWelsRcMbInit = WelsRcMbInitDisable; | 1178 | pRcf->pfWelsRcMbInit = WelsRcMbInitDisable; |
| 1031 | pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable; | 1179 | pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable; |
| 1032 | break; | 1180 | break; |
| 1033 | case RC_QUALITY_MODE: | ||
| 1034 | case RC_BITRATE_MODE: | 1181 | case RC_BITRATE_MODE: |
| 1182 | if (pEncCtx->pSvcParam->iUsageType == SCREEN_CONTENT_REAL_TIME) { | ||
| 1183 | pRcf->pfWelsRcPictureInit = WelRcPictureInitScc; | ||
| 1184 | pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudgeScc; | ||
| 1185 | pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateScc; | ||
| 1186 | pRcf->pfWelsRcMbInit = WelsRcMbInitScc; | ||
| 1187 | pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable; | ||
| 1188 | InitRcModuleScc(pEncCtx); | ||
| 1189 | |||
| 1190 | } else { | ||
| 1191 | pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom; | ||
| 1192 | pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge; | ||
| 1193 | pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateGom; | ||
| 1194 | pRcf->pfWelsRcMbInit = WelsRcMbInitGom; | ||
| 1195 | pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateGom; | ||
| 1196 | } | ||
| 1197 | break; | ||
| 1198 | case RC_QUALITY_MODE: | ||
| 1035 | default: | 1199 | default: |
| 1036 | pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom; | 1200 | pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom; |
| 1037 | pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge; | 1201 | pRcf->pfWelsRcPicDelayJudge = WelsRcFrameDelayJudge; |