History

Initial Commit

Ethan Hugg committed 12 years ago

Commit 70e5e621 parent bd509b2308 files · +97095 −-5Browse files

Showing the changes to codec/encoder/core/src/ratectl.cpp (1 of 308 files). Show all

Unified · Split

codec/encoder/core/src/ratectl.cpp+1049−0
@@ -0,0 +1,1049 @@
1+/*!
2+ * \copy
3+ * Copyright (c) 2009-2013, Cisco Systems
4+ * All rights reserved.
5+ *
6+ * Redistribution and use in source and binary forms, with or without
7+ * modification, are permitted provided that the following conditions
8+ * are met:
9+ *
10+ * * Redistributions of source code must retain the above copyright
11+ * notice, this list of conditions and the following disclaimer.
12+ *
13+ * * Redistributions in binary form must reproduce the above copyright
14+ * notice, this list of conditions and the following disclaimer in
15+ * the documentation and/or other materials provided with the
16+ * distribution.
17+ *
18+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+ * POSSIBILITY OF SUCH DAMAGE.
30+ *
31+ *
32+ * ratectl.c
33+ *
34+ * Abstract
35+ * Rate Control
36+ *
37+ * History
38+ * 9/8/2009 Created
39+ * 12/26/2011 Modified
40+ *
41+ *
42+ *
43+ *************************************************************************/
44+#include <stdlib.h>
45+#include <stdio.h>
46+#include <math.h>
47+#include "rc.h"
48+#include "encoder_context.h"
49+#include "utils.h"
50+#include "svc_enc_golomb.h"
51+
52+
53+namespace WelsSVCEnc {
54+
55+//#define _TEST_TEMP_RC_
56+#ifdef _TEST_TEMP_RC_
57+//#define _NOT_USE_AQ_FOR_TEST_
58+FILE *fp_test_rc = NULL;
59+FILE *fp_vgop = NULL;
60+#endif
61+#define _BITS_RANGE 0
62+
63+void RcInitLayerMemory(SWelsSvcRc *pWelsSvcRc, CMemoryAlign *pMA, const int32_t kiMaxTl)
64+{
65+ const int32_t kiSliceNum = pWelsSvcRc->iSliceNum;
66+ const int32_t kiGomSize = pWelsSvcRc->iGomSize;
67+ const int32_t kiGomSizeD = kiGomSize * sizeof(double);
68+ const int32_t kiGomSizeI = kiGomSize * sizeof(int32_t);
69+ const int32_t kiLayerRcSize = kiGomSizeD + (kiGomSizeI*3) + sizeof(SRCSlicing)*kiSliceNum + sizeof(SRCTemporal)*kiMaxTl;
70+ uint8_t *pBaseMem = (uint8_t *)pMA->WelsMalloc(kiLayerRcSize, "rc_layer_memory");
71+
72+ if (NULL == pBaseMem)
73+ return;
74+
75+ pWelsSvcRc->pGomComplexity = (double *)pBaseMem;
76+ pBaseMem += kiGomSizeD;
77+ pWelsSvcRc->pGomForegroundBlockNum = (int32_t *)pBaseMem;
78+ pBaseMem += kiGomSizeI;
79+ pWelsSvcRc->pCurrentFrameGomSad = (int32_t *)pBaseMem;
80+ pBaseMem += kiGomSizeI;
81+ pWelsSvcRc->pGomCost = (int32_t *)pBaseMem;
82+ pBaseMem += kiGomSizeI;
83+ pWelsSvcRc->pSlicingOverRc = (SRCSlicing *)pBaseMem;
84+ pBaseMem += sizeof(SRCSlicing)*kiSliceNum;
85+ pWelsSvcRc->pTemporalOverRc = (SRCTemporal *)pBaseMem;
86+}
87+
88+void RcFreeLayerMemory(SWelsSvcRc *pWelsSvcRc, CMemoryAlign *pMA)
89+{
90+ if (pWelsSvcRc != NULL && pWelsSvcRc->pGomComplexity != NULL)
91+ {
92+ pMA->WelsFree(pWelsSvcRc->pGomComplexity, "rc_layer_memory");
93+ pWelsSvcRc->pGomComplexity = NULL;
94+ pWelsSvcRc->pGomForegroundBlockNum = NULL;
95+ pWelsSvcRc->pCurrentFrameGomSad = NULL;
96+ pWelsSvcRc->pGomCost = NULL;
97+ pWelsSvcRc->pSlicingOverRc = NULL;
98+ pWelsSvcRc->pTemporalOverRc = NULL;
99+ }
100+}
101+
102+static inline double RcConvertQp2QStep(double dQP)
103+{
104+ return pow( 2.0, (dQP-4.0)/6.0 );
105+}
106+static inline double RcConvertQStep2Qp(double dQpStep)
107+{
108+ return (6 * log(dQpStep) / log(2.0) + 4.0);
109+}
110+
111+void RcInitSequenceParameter(sWelsEncCtx *pEncCtx)
112+{
113+ SWelsSvcRc *pWelsSvcRc = NULL;
114+ SDLayerParam *pDLayerParam = NULL;
115+
116+ int32_t j = 0;
117+ int32_t iMbWidth = 0;
118+
119+ BOOL_T bMultiSliceMode = FALSE;
120+ int32_t iGomRowMode0 = 1, iGomRowMode1 = 1;
121+#ifdef _TEST_TEMP_RC_
122+ fp_test_rc = fopen("testRC.dat","w");
123+ fp_vgop = fopen("vgop.dat","w");
124+#endif
125+ for( j=0; j<pEncCtx->pSvcParam->iNumDependencyLayer; j++ )
126+ {
127+ SSliceCtx *pSliceCtx = &pEncCtx->pSliceCtxList[j];
128+ pWelsSvcRc = &pEncCtx->pWelsSvcRc[j];
129+ pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[j];
130+ iMbWidth = (pDLayerParam->iFrameWidth>>4);
131+ pWelsSvcRc->iNumberMbFrame = iMbWidth*(pDLayerParam->iFrameHeight>>4);
132+ pWelsSvcRc->iSliceNum= pSliceCtx->iSliceNumInFrame;
133+
134+ pWelsSvcRc->iRcVaryPercentage = _BITS_RANGE; // % -- for temp
135+ pWelsSvcRc->dRcVaryRatio = (double)pWelsSvcRc->iRcVaryPercentage/MAX_BITS_VARY_PERCENTAGE;
136+
137+ pWelsSvcRc->dSkipBufferRatio = SKIP_RATIO;
138+
139+ pWelsSvcRc->iQpRangeUpperInFrame = QP_RANGE_UPPER_MODE1 - (int32_t)((QP_RANGE_UPPER_MODE1 - QP_RANGE_MODE0)*pWelsSvcRc->dRcVaryRatio + 0.5);
140+ pWelsSvcRc->iQpRangeLowerInFrame = QP_RANGE_LOWER_MODE1 - (int32_t)((QP_RANGE_LOWER_MODE1 - QP_RANGE_MODE0)*pWelsSvcRc->dRcVaryRatio + 0.5);
141+
142+ if( iMbWidth<=MB_WIDTH_THRESHOLD_90P )
143+ {
144+ pWelsSvcRc->iSkipQpValue = SKIP_QP_90P;
145+ iGomRowMode0 = GOM_ROW_MODE0_90P;
146+ iGomRowMode1 = GOM_ROW_MODE1_90P;
147+ }
148+ else if( iMbWidth<=MB_WIDTH_THRESHOLD_180P )
149+ {
150+ pWelsSvcRc->iSkipQpValue = SKIP_QP_180P;
151+ iGomRowMode0 = GOM_ROW_MODE0_180P;
152+ iGomRowMode1 = GOM_ROW_MODE1_180P;
153+ }
154+ else if( iMbWidth<=MB_WIDTH_THRESHOLD_360P )
155+ {
156+ pWelsSvcRc->iSkipQpValue = SKIP_QP_360P;
157+ iGomRowMode0 = GOM_ROW_MODE0_360P;
158+ iGomRowMode1 = GOM_ROW_MODE1_360P;
159+ }
160+ else
161+ {
162+ pWelsSvcRc->iSkipQpValue = SKIP_QP_720P;
163+ iGomRowMode0 = GOM_ROW_MODE0_720P;
164+ iGomRowMode1 = GOM_ROW_MODE1_720P;
165+ }
166+ iGomRowMode0 = iGomRowMode1 + (int32_t)((iGomRowMode0 - iGomRowMode1)*pWelsSvcRc->dRcVaryRatio + 0.5);
167+
168+ pWelsSvcRc->iNumberMbGom = iMbWidth*iGomRowMode0;
169+
170+ pWelsSvcRc->iMinQp = GOM_MIN_QP_MODE;
171+ pWelsSvcRc->iMaxQp = GOM_MAX_QP_MODE;
172+
173+ pWelsSvcRc->iFrameDeltaQpUpper = LAST_FRAME_QP_RANGE_UPPER_MODE1 - (int32_t)((LAST_FRAME_QP_RANGE_UPPER_MODE1 - LAST_FRAME_QP_RANGE_UPPER_MODE0)*pWelsSvcRc->dRcVaryRatio + 0.5);
174+ pWelsSvcRc->iFrameDeltaQpLower = LAST_FRAME_QP_RANGE_LOWER_MODE1 - (int32_t)((LAST_FRAME_QP_RANGE_LOWER_MODE1 - LAST_FRAME_QP_RANGE_LOWER_MODE0)*pWelsSvcRc->dRcVaryRatio + 0.5);
175+
176+ pWelsSvcRc->iSkipFrameNum = 0;
177+ pWelsSvcRc->iGomSize = (pWelsSvcRc->iNumberMbFrame+pWelsSvcRc->iNumberMbGom-1)/pWelsSvcRc->iNumberMbGom;
178+
179+
180+ RcInitLayerMemory( pWelsSvcRc, pEncCtx->pMemAlign, 1+pDLayerParam->iHighestTemporalId );
181+
182+ bMultiSliceMode = ( (SM_RASTER_SLICE == pDLayerParam->sMso.uiSliceMode) ||
183+ (SM_ROWMB_SLICE == pDLayerParam->sMso.uiSliceMode) ||
184+ (SM_DYN_SLICE == pDLayerParam->sMso.uiSliceMode) );
185+ if( bMultiSliceMode )
186+ pWelsSvcRc->iNumberMbGom = pWelsSvcRc->iNumberMbFrame;
187+ }
188+}
189+
190+
191+void RcInitTlWeight(sWelsEncCtx *pEncCtx)
192+{
193+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
194+ SRCTemporal *pTOverRc = pWelsSvcRc->pTemporalOverRc;
195+ SDLayerParam *pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
196+ const int32_t kiDecompositionStages = pDLayerParam->iDecompositionStages;
197+ const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId;
198+
199+ //Index 0:Virtual GOP size, Index 1:Frame rate
200+ 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}};
201+ const int32_t kiGopSize = (1<<kiDecompositionStages);
202+ int32_t i, k, n;
203+
204+ n = 0;
205+ while (n <= kiHighestTid)
206+ {
207+ pTOverRc[n].dTlayerWeight = WeightArray[kiDecompositionStages][n];
208+ ++ n;
209+ }
210+ //Calculate the frame index for the current frame and its reference frame
211+ for( n=0; n<VGOP_SIZE; n+=kiGopSize )
212+ {
213+ pWelsSvcRc->iTlOfFrames[n] = 0;
214+ for( i=1; i<=kiDecompositionStages; i++ )
215+ {
216+ for( k=1<<(kiDecompositionStages-i); k<kiGopSize; k+=(kiGopSize>>(i-1)) )
217+ {
218+ pWelsSvcRc->iTlOfFrames[k+n]=i;
219+ }
220+ }
221+ }
222+ pWelsSvcRc->iPreviousGopSize = kiGopSize;
223+ pWelsSvcRc->iGopNumberInVGop = VGOP_SIZE/kiGopSize;
224+}
225+
226+void RcUpdateBitrateFps(sWelsEncCtx *pEncCtx)
227+{
228+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
229+ SRCTemporal *pTOverRc = pWelsSvcRc->pTemporalOverRc;
230+ SDLayerParam *pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
231+ const int32_t kiGopSize = (1<<pDLayerParam->iDecompositionStages);
232+ const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId;
233+ double input_dBitsPerFrame = pDLayerParam->iSpatialBitrate / pDLayerParam->fInputFrameRate;
234+ const int32_t kiGopBits = (int32_t)(input_dBitsPerFrame*kiGopSize);
235+ int32_t i;
236+
237+ pWelsSvcRc->iBitRate = pDLayerParam->iSpatialBitrate;
238+ pWelsSvcRc->fFrameRate = pDLayerParam->fInputFrameRate;
239+
240+ double dTargetVaryRange = FRAME_iTargetBits_VARY_RANGE*(1.0 - pWelsSvcRc->dRcVaryRatio);
241+ double dMinBitsRatio = 1.0 - dTargetVaryRange;
242+ double dMaxBitsRatio = 1.0 + FRAME_iTargetBits_VARY_RANGE;//dTargetVaryRange;
243+
244+ for( i=0; i<=kiHighestTid; i++)
245+ {
246+ const double kdConstraitBits = kiGopBits*pTOverRc[i].dTlayerWeight;
247+ pTOverRc[i].iMinBitsTl = (int32_t)(kdConstraitBits*dMinBitsRatio);
248+ pTOverRc[i].iMaxBitsTl = (int32_t)(kdConstraitBits*dMaxBitsRatio);
249+ }
250+ //When bitrate is changed, pBuffer size should be updated
251+ pWelsSvcRc->iBufferSizeSkip = (int32_t)(pWelsSvcRc->iBitRate * pWelsSvcRc->dSkipBufferRatio);
252+ pWelsSvcRc->iBufferSizePadding = (int32_t)(pWelsSvcRc->iBitRate * PADDING_BUFFER_RATIO);
253+
254+ //change remaining bits
255+ if(pWelsSvcRc->dBitsPerFrame > 0.1)
256+ pWelsSvcRc->iRemainingBits = (int32_t)(pWelsSvcRc->iRemainingBits*input_dBitsPerFrame/pWelsSvcRc->dBitsPerFrame);
257+ pWelsSvcRc->dBitsPerFrame = input_dBitsPerFrame;
258+}
259+
260+
261+void RcInitVGop(sWelsEncCtx *pEncCtx)
262+{
263+ const int32_t kiDid = pEncCtx->uiDependencyId;
264+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid];
265+ SRCTemporal *pTOverRc = pWelsSvcRc->pTemporalOverRc;
266+ const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId;
267+
268+ pWelsSvcRc->iRemainingBits = (int32_t)(VGOP_SIZE*pWelsSvcRc->dBitsPerFrame);
269+ pWelsSvcRc->dRemainingWeights = pWelsSvcRc->iGopNumberInVGop;
270+
271+ pWelsSvcRc->iFrameCodedInVGop = 0;
272+ pWelsSvcRc->iGopIndexInVGop = 0;
273+
274+ for (int32_t i = 0; i <= kiHighestTid; ++ i)
275+ pTOverRc[i].iGopBitsDq = 0;
276+ pWelsSvcRc->iSkipFrameInVGop=0;
277+}
278+
279+void RcInitRefreshParameter(sWelsEncCtx *pEncCtx)
280+{
281+ const int32_t kiDid = pEncCtx->uiDependencyId;
282+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid];
283+ SRCTemporal *pTOverRc = pWelsSvcRc->pTemporalOverRc;
284+ SDLayerParam *pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[kiDid];
285+ const int32_t kiHighestTid = pDLayerParam->iHighestTemporalId;
286+ int32_t i;
287+
288+ //I frame R-Q Model
289+ pWelsSvcRc->iIntraComplexity = 0;
290+ pWelsSvcRc->iIntraMbCount = 0;
291+
292+ //P frame R-Q Model
293+ for(i=0; i<=kiHighestTid; i++)
294+ {
295+ pTOverRc[i].iPFrameNum = 0;
296+ pTOverRc[i].dLinearCmplx = 0.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->dBitsPerFrame = 0.0;
306+
307+ //Backup the initial bitrate and fps
308+ pWelsSvcRc->iPreviousBitrate = pDLayerParam->iSpatialBitrate;
309+ pWelsSvcRc->dPreviousFps = pDLayerParam->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_t RcJudgeBitrateFpsUpdate(sWelsEncCtx *pEncCtx)
319+{
320+ int32_t iCurDid = pEncCtx->uiDependencyId;
321+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[iCurDid];
322+ SDLayerParam *pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[iCurDid];
323+
324+ if((pWelsSvcRc->iPreviousBitrate != pDLayerParam->iSpatialBitrate) ||
325+ (pWelsSvcRc->dPreviousFps-pDLayerParam->fInputFrameRate)>EPSN ||
326+ (pWelsSvcRc->dPreviousFps-pDLayerParam->fInputFrameRate)<-EPSN)
327+ {
328+ pWelsSvcRc->iPreviousBitrate = pDLayerParam->iSpatialBitrate;
329+ pWelsSvcRc->dPreviousFps = pDLayerParam->fInputFrameRate;
330+ return true;
331+ }
332+ else
333+ return false;
334+}
335+
336+#if GOM_TRACE_FLAG
337+void RcTraceVGopBitrate(sWelsEncCtx *pEncCtx)
338+{
339+ const int32_t kiDid = pEncCtx->uiDependencyId;
340+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid];
341+
342+ if( pWelsSvcRc->iFrameCodedInVGop )
343+ {
344+ const int32_t kiHighestTid = pEncCtx->pSvcParam->sDependencyLayers[kiDid].iHighestTemporalId;
345+ SRCTemporal *pTOverRc = pWelsSvcRc->pTemporalOverRc;
346+ int32_t iVGopBitrate;
347+ int32_t iTotalBits = pWelsSvcRc->iPaddingBitrateStat;
348+ int32_t iTid = 0;
349+ while (iTid <= kiHighestTid)
350+ {
351+ iTotalBits += pTOverRc[iTid].iGopBitsDq;
352+ ++ iTid;
353+ }
354+ int32_t iFrameInVGop = pWelsSvcRc->iFrameCodedInVGop+pWelsSvcRc->iSkipFrameInVGop;
355+ if(0 != iFrameInVGop)
356+ iVGopBitrate = (int32_t)( iTotalBits/iFrameInVGop *pWelsSvcRc->fFrameRate );
357+#ifdef _TEST_TEMP_Rc_
358+ fprintf(fp_vgop,"%d\n",(int32_t)((double)iTotalBits/iFrameInVGop));
359+#endif
360+ WelsLog( pEncCtx, WELS_LOG_INFO,"[Rc] VGOPbitrate%d: %d \n", kiDid, iVGopBitrate);
361+ if ( iTotalBits > 0 )
362+ {
363+ iTid = 0;
364+ while (iTid <= kiHighestTid)
365+ {
366+ WelsLog( pEncCtx, WELS_LOG_INFO,"T%d=%8.3f \n", iTid, (double)(pTOverRc[iTid].iGopBitsDq/iTotalBits) );
367+ ++ iTid;
368+ }
369+ }
370+ }
371+}
372+#endif
373+
374+void RcUpdateTemporalZero(sWelsEncCtx *pEncCtx)
375+{
376+ const int32_t kiDid = pEncCtx->uiDependencyId;
377+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[kiDid];
378+ SDLayerParam *pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[kiDid];
379+ const int32_t kiGopSize = (1<<pDLayerParam->iDecompositionStages);
380+
381+ if( pWelsSvcRc->iPreviousGopSize != kiGopSize )
382+ {
383+#if GOM_TRACE_FLAG
384+ RcTraceVGopBitrate(pEncCtx);
385+#endif
386+ RcInitTlWeight(pEncCtx);
387+ RcInitVGop(pEncCtx);
388+ }
389+ else if( pWelsSvcRc->iGopIndexInVGop == pWelsSvcRc->iGopNumberInVGop || pEncCtx->eSliceType == I_SLICE)
390+ {
391+#if GOM_TRACE_FLAG
392+ RcTraceVGopBitrate(pEncCtx);
393+#endif
394+ RcInitVGop(pEncCtx);
395+ }
396+ pWelsSvcRc->iGopIndexInVGop++;
397+}
398+
399+
400+void RcInitIdrQp(sWelsEncCtx *pEncCtx)
401+{
402+ double dBpp = 0;
403+ int32_t i;
404+
405+ //64k@6fps for 90p: bpp 0.74 QP:24
406+ //192k@12fps for 180p: bpp 0.28 QP:26
407+ //512k@24fps for 360p: bpp 0.09 QP:30
408+ //1500k@30fps for 720p: bpp 0.05 QP:32
409+ 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}};
410+ int32_t dInitialQPArray[4][4] = {{28, 26, 24, 22}, {30, 28, 26, 24}, {32, 30, 28, 26}, {34, 32, 30, 28}};
411+ int32_t iBppIndex = 0;
412+
413+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
414+ SDLayerParam *pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
415+
416+ if (pDLayerParam->fOutputFrameRate > EPSN && pDLayerParam->iFrameWidth && pDLayerParam->iFrameHeight)
417+ dBpp=(double)(pDLayerParam->iSpatialBitrate) / (double)(pDLayerParam->fOutputFrameRate * pDLayerParam->iFrameWidth * pDLayerParam->iFrameHeight);
418+ else
419+ dBpp = 0.1;
420+
421+ //Area*2
422+ if ( pDLayerParam->iFrameWidth*pDLayerParam->iFrameHeight <= 28800 ) // 90p video:160*90
423+ iBppIndex = 0;
424+ else if ( pDLayerParam->iFrameWidth*pDLayerParam->iFrameHeight <= 115200 ) // 180p video:320*180
425+ iBppIndex = 1;
426+ else if ( pDLayerParam->iFrameWidth*pDLayerParam->iFrameHeight <= 460800 ) // 360p video:640*360
427+ iBppIndex = 2;
428+ else
429+ iBppIndex = 3;
430+
431+ //Search
432+ for( i=0; i<3; i++ )
433+ {
434+ if ( dBpp<=dBppArray[iBppIndex][i] )
435+ break;
436+ }
437+ pWelsSvcRc->iInitialQp = dInitialQPArray[iBppIndex][i];
438+ pWelsSvcRc->iInitialQp = (int32_t)WELS_CLIP3( pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP );
439+ pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
440+ pWelsSvcRc->dQStep = RcConvertQp2QStep(pEncCtx->iGlobalQp);
441+ pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
442+}
443+
444+void RcCalculateIdrQp(sWelsEncCtx *pEncCtx)
445+{
446+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
447+ //obtain the idr qp using previous idr complexity
448+ if(pWelsSvcRc->iNumberMbFrame != pWelsSvcRc->iIntraMbCount){
449+ pWelsSvcRc->iIntraComplexity = (int32_t)((double)pWelsSvcRc->iIntraComplexity*pWelsSvcRc->iNumberMbFrame/pWelsSvcRc->iIntraMbCount + 0.5);
450+ }
451+ pWelsSvcRc->iInitialQp = (int32_t)RcConvertQStep2Qp( (double)pWelsSvcRc->iIntraComplexity/pWelsSvcRc->iTargetBits);
452+ pWelsSvcRc->iInitialQp = (int32_t)WELS_CLIP3( pWelsSvcRc->iInitialQp, MIN_IDR_QP, MAX_IDR_QP );
453+ pEncCtx->iGlobalQp = pWelsSvcRc->iInitialQp;
454+ pWelsSvcRc->dQStep = RcConvertQp2QStep(pEncCtx->iGlobalQp);
455+ pWelsSvcRc->iLastCalculatedQScale = pEncCtx->iGlobalQp;
456+}
457+
458+
459+void RcCalculatePictureQp(sWelsEncCtx *pEncCtx)
460+{
461+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
462+ int32_t iTl = pEncCtx->uiTemporalId;
463+ SRCTemporal *pTOverRc = &pWelsSvcRc->pTemporalOverRc[iTl];
464+ int32_t iLumaQp = 0;
465+
466+ if(0 == pTOverRc->iPFrameNum)
467+ {
468+ iLumaQp = pWelsSvcRc->iInitialQp;
469+ }
470+ else{
471+ double dCmplxRatio = (double)pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity/pTOverRc->iFrameCmplxMean;
472+ dCmplxRatio = WELS_CLIP3(dCmplxRatio, 1.0-FRAME_CMPLX_RATIO_RANGE, 1.0+FRAME_CMPLX_RATIO_RANGE);
473+
474+ pWelsSvcRc->dQStep = pTOverRc->dLinearCmplx*dCmplxRatio / pWelsSvcRc->iTargetBits;
475+ iLumaQp = (int32_t)( RcConvertQStep2Qp( pWelsSvcRc->dQStep )+0.5 );
476+
477+ //limit QP
478+ int32_t iLastIdxCodecInVGop = pWelsSvcRc->iFrameCodedInVGop - 1;
479+ if(iLastIdxCodecInVGop < 0)
480+ iLastIdxCodecInVGop += VGOP_SIZE;
481+ int32_t iTlLast = pWelsSvcRc->iTlOfFrames[iLastIdxCodecInVGop];
482+ int32_t iDeltaQpTemporal = iTl - iTlLast;
483+ if(0 == iTlLast && iTl > 0)
484+ iDeltaQpTemporal += 3;
485+ else if(0 == iTl && iTlLast > 0)
486+ iDeltaQpTemporal -= 3;
487+
488+ iLumaQp = WELS_CLIP3(iLumaQp,
489+ pWelsSvcRc->iLastCalculatedQScale - pWelsSvcRc->iFrameDeltaQpLower +iDeltaQpTemporal, pWelsSvcRc->iLastCalculatedQScale + pWelsSvcRc->iFrameDeltaQpUpper + iDeltaQpTemporal);
490+ }
491+
492+ iLumaQp = WELS_CLIP3(iLumaQp, GOM_MIN_QP_MODE, GOM_MAX_QP_MODE);
493+
494+ pWelsSvcRc->dQStep = RcConvertQp2QStep(iLumaQp);
495+ pWelsSvcRc->iLastCalculatedQScale = iLumaQp;
496+#ifndef _NOT_USE_AQ_FOR_TEST_
497+ if(pEncCtx->pSvcParam->bEnableAdaptiveQuant)
498+ {
499+
500+ iLumaQp = (int32_t)WELS_CLIP3(iLumaQp - pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
501+ }
502+#endif
503+ pEncCtx->iGlobalQp = iLumaQp;
504+}
505+
506+void RcInitSliceInformation(sWelsEncCtx *pEncCtx)
507+{
508+ SSliceCtx *pCurSliceCtx = pEncCtx->pCurDqLayer->pSliceEncCtx;
509+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
510+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[0];
511+ const int32_t kiSliceNum = pCurSliceCtx->iSliceNumInFrame;
512+ const double kdBitsPerMb = (double)pWelsSvcRc->iTargetBits / pWelsSvcRc->iNumberMbFrame;
513+
514+ for(int32_t i=0; i<kiSliceNum; i++ )
515+ {
516+ pSOverRc->iStartMbSlice =
517+ pSOverRc->iEndMbSlice = pCurSliceCtx->pFirstMbInSlice[i];
518+ pSOverRc->iEndMbSlice += (pCurSliceCtx->pCountMbNumInSlice[i]-1);
519+ pSOverRc->iTotalQpSlice = 0;
520+ pSOverRc->iTotalMbSlice = 0;
521+ pSOverRc->iTargetBitsSlice = (int32_t)(kdBitsPerMb * pCurSliceCtx->pCountMbNumInSlice[i]);
522+ pSOverRc->iFrameBitsSlice = 0;
523+ pSOverRc->iGomBitsSlice = 0;
524+ ++ pSOverRc;
525+ }
526+}
527+
528+void RcDecideTargetBits(sWelsEncCtx *pEncCtx)
529+{
530+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
531+ SRCTemporal *pTOverRc = &pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId];
532+ //allocate bits
533+ if(pEncCtx->eSliceType == I_SLICE)
534+ {
535+ pWelsSvcRc->iTargetBits = (int32_t)( pWelsSvcRc->dBitsPerFrame * IDR_BITRATE_RATIO );
536+ }
537+ else
538+ {
539+ pWelsSvcRc->iTargetBits = (int32_t)( pWelsSvcRc->iRemainingBits*pTOverRc->dTlayerWeight/pWelsSvcRc->dRemainingWeights );
540+ pWelsSvcRc->iTargetBits = WELS_CLIP3( pWelsSvcRc->iTargetBits, pTOverRc->iMinBitsTl, pTOverRc->iMaxBitsTl);
541+ }
542+ pWelsSvcRc->dRemainingWeights -= pTOverRc->dTlayerWeight;
543+}
544+
545+
546+void RcInitGoomParameters(sWelsEncCtx *pEncCtx)
547+{
548+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
549+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[0];
550+ const int32_t kiSliceNum = pWelsSvcRc->iSliceNum;
551+ const int32_t kiGlobalQp = pEncCtx->iGlobalQp;
552+
553+ pWelsSvcRc->iAverageFrameQp = 0;
554+ for(int32_t i=0; i<kiSliceNum; ++i )
555+ {
556+ pSOverRc->iComplexityIndexSlice = 0;
557+ pSOverRc->iCalculatedQpSlice = kiGlobalQp;
558+ ++ pSOverRc;
559+ }
560+ memset( pWelsSvcRc->pGomComplexity, 0, pWelsSvcRc->iGomSize*sizeof(double) );
561+ memset( pWelsSvcRc->pGomCost, 0, pWelsSvcRc->iGomSize*sizeof(int32_t) );
562+}
563+
564+void RcCalculateMbQp(sWelsEncCtx *pEncCtx,SMB* pCurMb, const int32_t kiSliceId)
565+{
566+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
567+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[kiSliceId];
568+ int32_t iLumaQp = pSOverRc->iCalculatedQpSlice;
569+
570+#ifndef _NOT_USE_AQ_FOR_TEST_
571+ if ( pEncCtx->pSvcParam->bEnableAdaptiveQuant )
572+ {
573+ iLumaQp = (int8_t)WELS_CLIP3(iLumaQp +
574+ pEncCtx->pVaa->sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[pCurMb->iMbXY], pWelsSvcRc->iMinQp, 51);
575+ }
576+#endif
577+ pCurMb->uiChromaQp = g_kuiChromaQpTable[iLumaQp];
578+ pCurMb->uiLumaQp = iLumaQp;
579+}
580+
581+SWelsSvcRc* RcJudgeBaseUsability(sWelsEncCtx *pEncCtx)
582+{
583+ SWelsSvcRc *pWelsSvcRc = NULL, *pWelsSvcRc_Base = NULL;
584+ SDLayerParam *pDlpBase = NULL, *pDLayerParam = NULL;
585+
586+ if( pEncCtx->uiDependencyId<=0 )
587+ return NULL;
588+
589+ pDlpBase = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId-1];
590+ pWelsSvcRc_Base = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId-1];
591+ if( pEncCtx->uiTemporalId<=pDlpBase->iDecompositionStages )
592+ {
593+ pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
594+ pWelsSvcRc_Base = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId-1];
595+ pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
596+ pDlpBase = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId-1];
597+ if( (pDLayerParam->iFrameWidth*pDLayerParam->iFrameHeight/pWelsSvcRc->iNumberMbGom) ==
598+ (pDlpBase->iFrameWidth*pDlpBase->iFrameHeight/pWelsSvcRc_Base->iNumberMbGom) )
599+ return pWelsSvcRc_Base;
600+ else
601+ return NULL;
602+ }
603+ else
604+ return NULL;
605+}
606+
607+void RcGomTargetBits(sWelsEncCtx *pEncCtx, const int32_t kiSliceId)
608+{
609+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
610+ SWelsSvcRc *pWelsSvcRc_Base = NULL;
611+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[kiSliceId];
612+
613+ double dAllocateBits = 0;
614+ int32_t iSumSad = 0;
615+ int32_t iLastGomIndex = 0;
616+ int32_t iLeftBits = 0;
617+ const int32_t kiComplexityIndex = pSOverRc->iComplexityIndexSlice;
618+ int32_t i;
619+
620+ iLastGomIndex = pSOverRc->iEndMbSlice/pWelsSvcRc->iNumberMbGom;
621+ iLeftBits = pSOverRc->iTargetBitsSlice-pSOverRc->iFrameBitsSlice;
622+
623+ if(iLeftBits <= 0)
624+ {
625+ pSOverRc->iGomTargetBits = 0;
626+ return;
627+ }
628+ else if( kiComplexityIndex >= iLastGomIndex)
629+ {
630+ dAllocateBits = iLeftBits;
631+ }
632+ else
633+ {
634+ pWelsSvcRc_Base = RcJudgeBaseUsability(pEncCtx);
635+ pWelsSvcRc_Base = (pWelsSvcRc_Base) ? pWelsSvcRc_Base : pWelsSvcRc;
636+ for( i=kiComplexityIndex; i<=iLastGomIndex; i++ )
637+ {
638+ iSumSad += pWelsSvcRc_Base->pCurrentFrameGomSad[i];
639+ }
640+ if(0 == iSumSad)
641+ dAllocateBits = (double)iLeftBits/(iLastGomIndex-kiComplexityIndex);
642+ else
643+ dAllocateBits = (double)iLeftBits*pWelsSvcRc_Base->pCurrentFrameGomSad[kiComplexityIndex+1]/iSumSad;
644+
645+ }
646+ pSOverRc->iGomTargetBits = int32_t(dAllocateBits + 0.5);
647+}
648+
649+
650+
651+void RcCalculateGomQp(sWelsEncCtx *pEncCtx, SMB* pCurMb, int32_t iSliceId)
652+{
653+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
654+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[iSliceId];
655+ double dBitsRatio = 1.0;
656+
657+ int32_t iLeftBits = pSOverRc->iTargetBitsSlice - pSOverRc->iFrameBitsSlice;
658+ int32_t iTargetLeftBits = iLeftBits + pSOverRc->iGomBitsSlice - pSOverRc->iGomTargetBits;
659+
660+ if(iLeftBits <= 0)
661+ {
662+ pSOverRc->iCalculatedQpSlice += 2;
663+ }
664+ else
665+ {
666+ //globe decision
667+ dBitsRatio = iLeftBits / (iTargetLeftBits + 0.1);
668+ if(dBitsRatio < 0.8409) //2^(-1.5/6)
669+ pSOverRc->iCalculatedQpSlice += 2;
670+ else if(dBitsRatio < 0.9439) //2^(-0.5/6)
671+ pSOverRc->iCalculatedQpSlice += 1;
672+ else if(dBitsRatio > 1.06) //2^(0.5/6)
673+ pSOverRc->iCalculatedQpSlice -= 1;
674+ else if(dBitsRatio > 1.19) //2^(1.5/6)
675+ pSOverRc->iCalculatedQpSlice -= 2;
676+ }
677+
678+ pSOverRc->iCalculatedQpSlice = WELS_CLIP3( pSOverRc->iCalculatedQpSlice,
679+ pEncCtx->iGlobalQp-pWelsSvcRc->iQpRangeLowerInFrame, pEncCtx->iGlobalQp+pWelsSvcRc->iQpRangeUpperInFrame );
680+ pSOverRc->iCalculatedQpSlice = WELS_CLIP3(pSOverRc->iCalculatedQpSlice, pWelsSvcRc->iMinQp, pWelsSvcRc->iMaxQp);
681+
682+ pSOverRc->iGomBitsSlice = 0;
683+
684+}
685+
686+void RcVBufferCalculationSkip(sWelsEncCtx *pEncCtx)
687+{
688+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
689+ SRCTemporal *pTOverRc = pWelsSvcRc->pTemporalOverRc;
690+ const int32_t kiOutputBits = (int32_t)(pWelsSvcRc->dBitsPerFrame + 0.5);
691+ //condition 1: whole pBuffer fullness
692+ pWelsSvcRc->iBufferFullnessSkip += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
693+ //condition 2: VGOP bits constraint
694+ const int32_t kiVGopBits = (int32_t)(pWelsSvcRc->dBitsPerFrame * VGOP_SIZE);
695+ int32_t iVGopBitsPred = 0;
696+ for(int32_t i = pWelsSvcRc->iFrameCodedInVGop+1; i<VGOP_SIZE; i++ )
697+ iVGopBitsPred += pTOverRc[pWelsSvcRc->iTlOfFrames[i]].iMinBitsTl;
698+ iVGopBitsPred -= pWelsSvcRc->iRemainingBits;
699+ double dIncPercent = iVGopBitsPred*100.0/kiVGopBits - (double)VGOP_BITS_PERCENTAGE_DIFF;
700+
701+ if( (pWelsSvcRc->iBufferFullnessSkip > pWelsSvcRc->iBufferSizeSkip && pWelsSvcRc->iAverageFrameQp > pWelsSvcRc->iSkipQpValue)
702+ || (dIncPercent > pWelsSvcRc->iRcVaryPercentage))
703+ {
704+ pEncCtx->iSkipFrameFlag=1;
705+ pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip-kiOutputBits;
706+#ifdef FRAME_INFO_OUTPUT
707+ fprintf(stderr, "skip one frame\n");
708+#endif
709+ }
710+
711+ if( pWelsSvcRc->iBufferFullnessSkip<0 )
712+ pWelsSvcRc->iBufferFullnessSkip = 0;
713+
714+ if( pEncCtx->iSkipFrameFlag==1 )
715+ {
716+ pWelsSvcRc->iRemainingBits += (int32_t)(pWelsSvcRc->dBitsPerFrame + 0.5);
717+ pWelsSvcRc->iSkipFrameNum++;
718+ pWelsSvcRc->iSkipFrameInVGop++;
719+ }
720+}
721+
722+void RcVBufferCalculationPadding(sWelsEncCtx *pEncCtx)
723+{
724+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
725+ const int32_t kiOutputBits = (int32_t)(pWelsSvcRc->dBitsPerFrame + 0.5);
726+ const int32_t kiBufferThreshold = (int32_t)(PADDING_THRESHOLD*(-pWelsSvcRc->iBufferSizePadding));
727+
728+ pWelsSvcRc->iBufferFullnessPadding += (pWelsSvcRc->iFrameDqBits - kiOutputBits);
729+
730+ if( pWelsSvcRc->iBufferFullnessPadding < kiBufferThreshold )
731+ {
732+ pWelsSvcRc->iPaddingSize = -pWelsSvcRc->iBufferFullnessPadding;
733+ pWelsSvcRc->iPaddingSize >>= 3; // /8
734+ pWelsSvcRc->iBufferFullnessPadding = 0;
735+ }
736+ else
737+ pWelsSvcRc->iPaddingSize=0;
738+}
739+
740+
741+void RcTraceFrameBits(sWelsEncCtx *pEncCtx)
742+{
743+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
744+
745+ WelsLog( pEncCtx, WELS_LOG_INFO,"[Rc] encoding_qp%d, qp = %3d, index = %8d, iTid = %1d, used = %8d, target = %8d, remaingbits = %8d\n",
746+ pEncCtx->uiDependencyId, pWelsSvcRc->iAverageFrameQp, pEncCtx->uiFrameIdxRc, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits,
747+ pWelsSvcRc->iTargetBits,pWelsSvcRc->iRemainingBits);
748+}
749+
750+void RcUpdatePictureQpBits(sWelsEncCtx *pEncCtx, int32_t iCodedBits)
751+{
752+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
753+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[0];
754+ SSliceCtx *pCurSliceCtx = pEncCtx->pCurDqLayer->pSliceEncCtx;
755+ int32_t iTotalQp = 0, iTotalMb = 0;
756+ int32_t i;
757+
758+ if(pEncCtx->eSliceType == P_SLICE)
759+ {
760+ for( i=0; i<pCurSliceCtx->iSliceNumInFrame; i++ )
761+ {
762+ iTotalQp += pSOverRc->iTotalQpSlice;
763+ iTotalMb += pSOverRc->iTotalMbSlice;
764+ ++ pSOverRc;
765+ }
766+ if(iTotalMb > 0)
767+ pWelsSvcRc->iAverageFrameQp = (int32_t)(1.0*iTotalQp/iTotalMb+0.5);
768+ else
769+ pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
770+ }
771+ else
772+ {
773+ pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
774+ }
775+ pWelsSvcRc->iFrameDqBits = iCodedBits;
776+ pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId].iGopBitsDq += pWelsSvcRc->iFrameDqBits;
777+}
778+
779+void RcUpdateIntraComplexity(sWelsEncCtx *pEncCtx)
780+{
781+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
782+ double iAlpha = 1.0/(1+pWelsSvcRc->iIdrNum);
783+ if(iAlpha < 0.25) iAlpha = 0.25;
784+
785+ double dIntraCmplx = pWelsSvcRc->dQStep*pWelsSvcRc->iFrameDqBits;
786+ dIntraCmplx = (1.0-iAlpha)*pWelsSvcRc->iIntraComplexity + iAlpha*dIntraCmplx;
787+ pWelsSvcRc->iIntraComplexity = (int32_t)(dIntraCmplx + 0.5);
788+ pWelsSvcRc->iIntraMbCount = pWelsSvcRc->iNumberMbFrame;
789+
790+ pWelsSvcRc->iIdrNum++;
791+ if(pWelsSvcRc->iIdrNum > 255)
792+ pWelsSvcRc->iIdrNum = 255;
793+}
794+
795+void RcUpdateFrameComplexity(sWelsEncCtx *pEncCtx)
796+{
797+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
798+ const int32_t kiTl = pEncCtx->uiTemporalId;
799+ SRCTemporal *pTOverRc = &pWelsSvcRc->pTemporalOverRc[kiTl];
800+
801+ if(0 == pTOverRc->iPFrameNum){
802+ pTOverRc->dLinearCmplx = pWelsSvcRc->iFrameDqBits * pWelsSvcRc->dQStep;
803+ }
804+ else{
805+ pTOverRc->dLinearCmplx = LINEAR_MODEL_DECAY_FACTOR*pTOverRc->dLinearCmplx
806+ + (1.0-LINEAR_MODEL_DECAY_FACTOR)*(pWelsSvcRc->iFrameDqBits * pWelsSvcRc->dQStep);
807+ }
808+ double iAlpha = 1.0/(1+pTOverRc->iPFrameNum);
809+ if(iAlpha < SMOOTH_FACTOR_MIN_VALUE)
810+ iAlpha = SMOOTH_FACTOR_MIN_VALUE;
811+ pTOverRc->iFrameCmplxMean = (int32_t)((1.0-iAlpha)*pTOverRc->iFrameCmplxMean + iAlpha*pEncCtx->pVaa->sComplexityAnalysisParam.iFrameComplexity + 0.5);
812+
813+ pTOverRc->iPFrameNum++;
814+ if(pTOverRc->iPFrameNum > 255)
815+ pTOverRc->iPFrameNum = 255;
816+}
817+
818+int32_t RcCalculateCascadingQp(struct TagWelsEncCtx *pEncCtx, int32_t iQp)
819+{
820+ int32_t iTemporalQp = 0;
821+ if( pEncCtx->pSvcParam->iDecompStages )
822+ {
823+ if( pEncCtx->uiTemporalId==0 )
824+ iTemporalQp = iQp - 3 - (pEncCtx->pSvcParam->iDecompStages-1);
825+ else
826+ iTemporalQp = iQp - (pEncCtx->pSvcParam->iDecompStages - pEncCtx->uiTemporalId);
827+ iTemporalQp = WELS_CLIP3( iTemporalQp, 1, 51 );
828+ }
829+ else
830+ iTemporalQp = iQp;
831+ return iTemporalQp;
832+}
833+
834+void WelsRcPictureInitGom(void *pCtx)
835+{
836+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
837+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
838+
839+ if ( pEncCtx->eSliceType == I_SLICE )
840+ {
841+ if(0 == pWelsSvcRc->iIdrNum) //iIdrNum == 0 means encoder has been initialed
842+ {
843+ RcInitRefreshParameter(pEncCtx);
844+ }
845+ }
846+ if( RcJudgeBitrateFpsUpdate(pEncCtx))
847+ {
848+ RcUpdateBitrateFps(pEncCtx);
849+ }
850+ if( pEncCtx->uiTemporalId == 0 )
851+ {
852+ RcUpdateTemporalZero(pEncCtx);
853+ }
854+ RcDecideTargetBits(pEncCtx);
855+ //decide globe_qp
856+ if(pEncCtx->eSliceType == I_SLICE)
857+ {
858+ if(0 == pWelsSvcRc->iIdrNum)
859+ RcInitIdrQp(pEncCtx);
860+ else
861+ {
862+ RcCalculateIdrQp(pEncCtx);
863+ }
864+ }
865+ else
866+ {
867+ RcCalculatePictureQp(pEncCtx);
868+ }
869+ RcInitSliceInformation(pEncCtx);
870+ RcInitGoomParameters(pEncCtx);
871+
872+}
873+
874+
875+
876+void WelsRcPictureInfoUpdateGom(void *pCtx, int32_t layer_size)
877+{
878+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
879+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
880+ int32_t iCodedBits = (layer_size<<3);
881+
882+ RcUpdatePictureQpBits(pEncCtx, iCodedBits);
883+
884+ if ( pEncCtx->eSliceType == P_SLICE )
885+ {
886+ RcUpdateFrameComplexity(pEncCtx);
887+ }
888+ else
889+ {
890+ RcUpdateIntraComplexity(pEncCtx);
891+ }
892+ pWelsSvcRc->iRemainingBits -= pWelsSvcRc->iFrameDqBits;
893+
894+#if GOM_TRACE_FLAG
895+ RcTraceFrameBits(pEncCtx);
896+#endif
897+
898+
899+#if SKIP_FRAME_FLAG
900+ if ( pEncCtx->uiDependencyId == pEncCtx->pSvcParam->iNumDependencyLayer - 1 )
901+ {
902+ RcVBufferCalculationSkip(pEncCtx);
903+ }
904+#endif
905+
906+ if ( pEncCtx->pSvcParam->iPaddingFlag )
907+ RcVBufferCalculationPadding(pEncCtx);
908+ pWelsSvcRc->iFrameCodedInVGop++;
909+#ifdef _TEST_TEMP_Rc_
910+ fprintf(fp_test_rc, "%d\n", pWelsSvcRc->iFrameDqBits);
911+ if(pEncCtx->iSkipFrameFlag)
912+ fprintf(fp_test_rc, "0\n");
913+ fflush(fp_test_rc);
914+#endif
915+}
916+
917+void WelsRcMbInitGom(void *pCtx, SMB* pCurMb, SSlice *pSlice)
918+{
919+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
920+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
921+ const int32_t kiSliceId = pSlice->uiSliceIdx;
922+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[kiSliceId];
923+ SBitStringAux * bs = pSlice->pSliceBsa;
924+
925+
926+ pSOverRc->iBsPosSlice = BsGetBitsPos(bs);
927+
928+ if(pEncCtx->eSliceType==I_SLICE)
929+ return;
930+ //calculate gom qp and target bits at the beginning of gom
931+ if(0 == (pCurMb->iMbXY%pWelsSvcRc->iNumberMbGom)){
932+ if(pCurMb->iMbXY != pSOverRc->iStartMbSlice){
933+ pSOverRc->iComplexityIndexSlice++;
934+ RcCalculateGomQp(pEncCtx, pCurMb, kiSliceId);
935+ }
936+ RcGomTargetBits(pEncCtx, kiSliceId);
937+ }
938+
939+ RcCalculateMbQp(pEncCtx,pCurMb,kiSliceId);
940+}
941+
942+void WelsRcMbInfoUpdateGom(void *pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice *pSlice)
943+{
944+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
945+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
946+ SBitStringAux * bs = pSlice->pSliceBsa;
947+ int32_t iSliceId = pSlice->uiSliceIdx;
948+ SRCSlicing *pSOverRc = &pWelsSvcRc->pSlicingOverRc[iSliceId];
949+ const int32_t kiComplexityIndex = pSOverRc->iComplexityIndexSlice;
950+
951+ int32_t cur_mb_bits = BsGetBitsPos(bs) - pSOverRc->iBsPosSlice;
952+ pSOverRc->iFrameBitsSlice += cur_mb_bits;
953+ pSOverRc->iGomBitsSlice += cur_mb_bits;
954+
955+ pWelsSvcRc->pGomCost[kiComplexityIndex] += iCostLuma;
956+
957+ if(cur_mb_bits > 0){
958+ pSOverRc->iTotalQpSlice += pCurMb->uiLumaQp;
959+ pSOverRc->iTotalMbSlice++;
960+ }
961+}
962+
963+void WelsRcPictureInitDisable(void *pCtx)
964+{
965+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
966+ SWelsSvcRc *pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
967+ SDLayerParam *pDLayerParam = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
968+
969+ const int32_t kiQp = pDLayerParam->iDLayerQp;
970+
971+ pEncCtx->iGlobalQp = RcCalculateCascadingQp( pEncCtx, kiQp );
972+
973+ if ( pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE) )
974+ {
975+ pEncCtx->iGlobalQp = (int32_t)WELS_CLIP3(pEncCtx->iGlobalQp -
976+ pEncCtx->pVaa->sAdaptiveQuantParam.dAverMotionTextureIndexToDeltaQp, GOM_MIN_QP_MODE, GOM_MAX_QP_MODE);
977+ }
978+ pWelsSvcRc->iAverageFrameQp = pEncCtx->iGlobalQp;
979+}
980+
981+void WelsRcPictureInfoUpdateDisable(void *pCtx, int32_t layer_size)
982+{
983+}
984+
985+void WelsRcMbInitDisable(void *pCtx, SMB* pCurMb, SSlice *pSlice)
986+{
987+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
988+ int32_t iLumaQp = pEncCtx->iGlobalQp;
989+
990+ if ( pEncCtx->pSvcParam->bEnableAdaptiveQuant && (pEncCtx->eSliceType == P_SLICE) )
991+ {
992+ iLumaQp = (int8_t)WELS_CLIP3(iLumaQp +
993+ pEncCtx->pVaa->sAdaptiveQuantParam.pMotionTextureIndexToDeltaQp[pCurMb->iMbXY], GOM_MIN_QP_MODE, 51);
994+ }
995+ pCurMb->uiChromaQp = g_kuiChromaQpTable[iLumaQp];
996+ pCurMb->uiLumaQp = iLumaQp;
997+}
998+
999+void WelsRcMbInfoUpdateDisable(void *pCtx, SMB* pCurMb, int32_t iCostLuma, SSlice *pSlice)
1000+{
1001+}
1002+
1003+
1004+void WelsRcInitModule(void *pCtx, int32_t iModule)
1005+{
1006+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
1007+ SWelsRcFunc * pRcf = &pEncCtx->pFuncList->pfRc;
1008+
1009+ switch(iModule)
1010+ {
1011+ case WELS_RC_DISABLE:
1012+ pRcf->pfWelsRcPictureInit = WelsRcPictureInitDisable;
1013+ pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateDisable;
1014+ pRcf->pfWelsRcMbInit = WelsRcMbInitDisable;
1015+ pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateDisable;
1016+ break;
1017+ case WELS_RC_GOM:
1018+ default:
1019+ pRcf->pfWelsRcPictureInit = WelsRcPictureInitGom;
1020+ pRcf->pfWelsRcPictureInfoUpdate = WelsRcPictureInfoUpdateGom;
1021+ pRcf->pfWelsRcMbInit = WelsRcMbInitGom;
1022+ pRcf->pfWelsRcMbInfoUpdate = WelsRcMbInfoUpdateGom;
1023+ break;
1024+ }
1025+
1026+ RcInitSequenceParameter(pEncCtx);
1027+}
1028+
1029+void WelsRcFreeMemory(void *pCtx)
1030+{
1031+ sWelsEncCtx *pEncCtx = (sWelsEncCtx*)pCtx;
1032+ SWelsSvcRc *pWelsSvcRc = NULL;
1033+ int32_t i = 0;
1034+#ifdef _TEST_TEMP_Rc_
1035+ if(fp_test_rc)
1036+ fclose(fp_test_rc);
1037+ fp_test_rc = NULL;
1038+ if(fp_vgop)
1039+ fclose(fp_vgop);
1040+ fp_vgop = NULL;
1041+#endif
1042+ for( i=0; i<pEncCtx->pSvcParam->iNumDependencyLayer; i++ )
1043+ {
1044+ pWelsSvcRc = &pEncCtx->pWelsSvcRc[i];
1045+ RcFreeLayerMemory(pWelsSvcRc, pEncCtx->pMemAlign);
1046+ }
1047+}
1048+
1049+}//end of namespace

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t