1*53ee8cc1Swenshuai.xi //<MStar Software>
2*53ee8cc1Swenshuai.xi //******************************************************************************
3*53ee8cc1Swenshuai.xi // MStar Software
4*53ee8cc1Swenshuai.xi // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5*53ee8cc1Swenshuai.xi // All software, firmware and related documentation herein ("MStar Software") are
6*53ee8cc1Swenshuai.xi // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7*53ee8cc1Swenshuai.xi // law, including, but not limited to, copyright law and international treaties.
8*53ee8cc1Swenshuai.xi // Any use, modification, reproduction, retransmission, or republication of all
9*53ee8cc1Swenshuai.xi // or part of MStar Software is expressly prohibited, unless prior written
10*53ee8cc1Swenshuai.xi // permission has been granted by MStar.
11*53ee8cc1Swenshuai.xi //
12*53ee8cc1Swenshuai.xi // By accessing, browsing and/or using MStar Software, you acknowledge that you
13*53ee8cc1Swenshuai.xi // have read, understood, and agree, to be bound by below terms ("Terms") and to
14*53ee8cc1Swenshuai.xi // comply with all applicable laws and regulations:
15*53ee8cc1Swenshuai.xi //
16*53ee8cc1Swenshuai.xi // 1. MStar shall retain any and all right, ownership and interest to MStar
17*53ee8cc1Swenshuai.xi // Software and any modification/derivatives thereof.
18*53ee8cc1Swenshuai.xi // No right, ownership, or interest to MStar Software and any
19*53ee8cc1Swenshuai.xi // modification/derivatives thereof is transferred to you under Terms.
20*53ee8cc1Swenshuai.xi //
21*53ee8cc1Swenshuai.xi // 2. You understand that MStar Software might include, incorporate or be
22*53ee8cc1Swenshuai.xi // supplied together with third party`s software and the use of MStar
23*53ee8cc1Swenshuai.xi // Software may require additional licenses from third parties.
24*53ee8cc1Swenshuai.xi // Therefore, you hereby agree it is your sole responsibility to separately
25*53ee8cc1Swenshuai.xi // obtain any and all third party right and license necessary for your use of
26*53ee8cc1Swenshuai.xi // such third party`s software.
27*53ee8cc1Swenshuai.xi //
28*53ee8cc1Swenshuai.xi // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29*53ee8cc1Swenshuai.xi // MStar`s confidential information and you agree to keep MStar`s
30*53ee8cc1Swenshuai.xi // confidential information in strictest confidence and not disclose to any
31*53ee8cc1Swenshuai.xi // third party.
32*53ee8cc1Swenshuai.xi //
33*53ee8cc1Swenshuai.xi // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34*53ee8cc1Swenshuai.xi // kind. Any warranties are hereby expressly disclaimed by MStar, including
35*53ee8cc1Swenshuai.xi // without limitation, any warranties of merchantability, non-infringement of
36*53ee8cc1Swenshuai.xi // intellectual property rights, fitness for a particular purpose, error free
37*53ee8cc1Swenshuai.xi // and in conformity with any international standard. You agree to waive any
38*53ee8cc1Swenshuai.xi // claim against MStar for any loss, damage, cost or expense that you may
39*53ee8cc1Swenshuai.xi // incur related to your use of MStar Software.
40*53ee8cc1Swenshuai.xi // In no event shall MStar be liable for any direct, indirect, incidental or
41*53ee8cc1Swenshuai.xi // consequential damages, including without limitation, lost of profit or
42*53ee8cc1Swenshuai.xi // revenues, lost or damage of data, and unauthorized system use.
43*53ee8cc1Swenshuai.xi // You agree that this Section 4 shall still apply without being affected
44*53ee8cc1Swenshuai.xi // even if MStar Software has been modified by MStar in accordance with your
45*53ee8cc1Swenshuai.xi // request or instruction for your use, except otherwise agreed by both
46*53ee8cc1Swenshuai.xi // parties in writing.
47*53ee8cc1Swenshuai.xi //
48*53ee8cc1Swenshuai.xi // 5. If requested, MStar may from time to time provide technical supports or
49*53ee8cc1Swenshuai.xi // services in relation with MStar Software to you for your use of
50*53ee8cc1Swenshuai.xi // MStar Software in conjunction with your or your customer`s product
51*53ee8cc1Swenshuai.xi // ("Services").
52*53ee8cc1Swenshuai.xi // You understand and agree that, except otherwise agreed by both parties in
53*53ee8cc1Swenshuai.xi // writing, Services are provided on an "AS IS" basis and the warranty
54*53ee8cc1Swenshuai.xi // disclaimer set forth in Section 4 above shall apply.
55*53ee8cc1Swenshuai.xi //
56*53ee8cc1Swenshuai.xi // 6. Nothing contained herein shall be construed as by implication, estoppels
57*53ee8cc1Swenshuai.xi // or otherwise:
58*53ee8cc1Swenshuai.xi // (a) conferring any license or right to use MStar name, trademark, service
59*53ee8cc1Swenshuai.xi // mark, symbol or any other identification;
60*53ee8cc1Swenshuai.xi // (b) obligating MStar or any of its affiliates to furnish any person,
61*53ee8cc1Swenshuai.xi // including without limitation, you and your customers, any assistance
62*53ee8cc1Swenshuai.xi // of any kind whatsoever, or any information; or
63*53ee8cc1Swenshuai.xi // (c) conferring any license or right under any intellectual property right.
64*53ee8cc1Swenshuai.xi //
65*53ee8cc1Swenshuai.xi // 7. These terms shall be governed by and construed in accordance with the laws
66*53ee8cc1Swenshuai.xi // of Taiwan, R.O.C., excluding its conflict of law rules.
67*53ee8cc1Swenshuai.xi // Any and all dispute arising out hereof or related hereto shall be finally
68*53ee8cc1Swenshuai.xi // settled by arbitration referred to the Chinese Arbitration Association,
69*53ee8cc1Swenshuai.xi // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70*53ee8cc1Swenshuai.xi // Rules of the Association by three (3) arbitrators appointed in accordance
71*53ee8cc1Swenshuai.xi // with the said Rules.
72*53ee8cc1Swenshuai.xi // The place of arbitration shall be in Taipei, Taiwan and the language shall
73*53ee8cc1Swenshuai.xi // be English.
74*53ee8cc1Swenshuai.xi // The arbitration award shall be final and binding to both parties.
75*53ee8cc1Swenshuai.xi //
76*53ee8cc1Swenshuai.xi //******************************************************************************
77*53ee8cc1Swenshuai.xi //<MStar Software>
78*53ee8cc1Swenshuai.xi
79*53ee8cc1Swenshuai.xi //#include <math.h>
80*53ee8cc1Swenshuai.xi //#include <stdio.h>
81*53ee8cc1Swenshuai.xi #include "mfe_h263_rc.h"
82*53ee8cc1Swenshuai.xi #include "ms_dprintf.h"
83*53ee8cc1Swenshuai.xi #include "mdrv_mfe_math.h"
84*53ee8cc1Swenshuai.xi #include "mfe_type.h"
85*53ee8cc1Swenshuai.xi #include "mfe_common.h"
86*53ee8cc1Swenshuai.xi
87*53ee8cc1Swenshuai.xi //! How many seconds of frames are responsible for compensation of bitrate usage.
88*53ee8cc1Swenshuai.xi #define CBR_DEPUTY_SECOND (1UL)
89*53ee8cc1Swenshuai.xi #define CVBR_DEPUTY_SECOND (5UL)
90*53ee8cc1Swenshuai.xi #define VBR_DEPUTY_SECOND (10UL)
91*53ee8cc1Swenshuai.xi
92*53ee8cc1Swenshuai.xi #define MIN_DEPUTY_FACTOR 10UL
93*53ee8cc1Swenshuai.xi
94*53ee8cc1Swenshuai.xi //! Default I-frame weighting over inter-frame
95*53ee8cc1Swenshuai.xi #define IFRAME_WEIGHT (3UL)
96*53ee8cc1Swenshuai.xi
97*53ee8cc1Swenshuai.xi //! Dynamic-framerate mechanism
98*53ee8cc1Swenshuai.xi // Minimal QP when STRICT_CONST_BITRATE
99*53ee8cc1Swenshuai.xi #define SCBR_BEST_QP (4UL)
100*53ee8cc1Swenshuai.xi // Bad-frame QP-thr
101*53ee8cc1Swenshuai.xi #define BAD_FRAME_QP_THR (12UL)
102*53ee8cc1Swenshuai.xi // Too-good-frame QP-thr
103*53ee8cc1Swenshuai.xi #define GOOD_FRAME_QP_THR (SCBR_BEST_QP+0UL)
104*53ee8cc1Swenshuai.xi
105*53ee8cc1Swenshuai.xi
106*53ee8cc1Swenshuai.xi // Prototypes
107*53ee8cc1Swenshuai.xi static MS_S32 _rc_ComputeFrameQP(RateCtrl_t* rcctx, MS_S8 chFrameType);
108*53ee8cc1Swenshuai.xi
rc_Create(RateCtrl_t * rcctx)109*53ee8cc1Swenshuai.xi void rc_Create(RateCtrl_t* rcctx)
110*53ee8cc1Swenshuai.xi {
111*53ee8cc1Swenshuai.xi rcctx->m_nFrameCount = 0;
112*53ee8cc1Swenshuai.xi }
113*53ee8cc1Swenshuai.xi
rc_Destroy(RateCtrl_t * rcctx)114*53ee8cc1Swenshuai.xi void rc_Destroy(RateCtrl_t* rcctx)
115*53ee8cc1Swenshuai.xi {
116*53ee8cc1Swenshuai.xi
117*53ee8cc1Swenshuai.xi }
118*53ee8cc1Swenshuai.xi
rc_Init(RateCtrl_t * rcctx,H263RCInfo * pRCInfo)119*53ee8cc1Swenshuai.xi void rc_Init(RateCtrl_t* rcctx, H263RCInfo* pRCInfo)
120*53ee8cc1Swenshuai.xi {
121*53ee8cc1Swenshuai.xi MS_U32 i;
122*53ee8cc1Swenshuai.xi MS_FLOAT A;
123*53ee8cc1Swenshuai.xi
124*53ee8cc1Swenshuai.xi #ifdef DROP_FRAME
125*53ee8cc1Swenshuai.xi rcctx->bitrate_count = 0;
126*53ee8cc1Swenshuai.xi #endif
127*53ee8cc1Swenshuai.xi // Copy parameters, no error checking yet.
128*53ee8cc1Swenshuai.xi rcctx->m_nWidth = pRCInfo->nWidth;
129*53ee8cc1Swenshuai.xi rcctx->m_nHeight = pRCInfo->nHeight;
130*53ee8cc1Swenshuai.xi rcctx->m_fTargetFrameRate = pRCInfo->fTargetFrameRate;
131*53ee8cc1Swenshuai.xi if (rcctx->m_fTargetFrameRate>MAX_FRAMERATE)
132*53ee8cc1Swenshuai.xi rcctx->m_fTargetFrameRate = MAX_FRAMERATE; // For m_SkipFrameHistory[]
133*53ee8cc1Swenshuai.xi rcctx->m_fMinFrameRate = pRCInfo->fMinFrameRate;
134*53ee8cc1Swenshuai.xi if (rcctx->m_fMinFrameRate>rcctx->m_fTargetFrameRate)
135*53ee8cc1Swenshuai.xi rcctx->m_fMinFrameRate = rcctx->m_fTargetFrameRate;
136*53ee8cc1Swenshuai.xi rcctx->m_nBitrate = pRCInfo->m_nBitrate;
137*53ee8cc1Swenshuai.xi rcctx->m_nPCount = pRCInfo->nPCount;
138*53ee8cc1Swenshuai.xi if(rcctx->m_nPCount < 0)
139*53ee8cc1Swenshuai.xi rcctx->m_nPCount = 0x7FFFFFFF; // nP_is_infinite
140*53ee8cc1Swenshuai.xi rcctx->m_rcGranularity = pRCInfo->rcGranularity;
141*53ee8cc1Swenshuai.xi rcctx->m_rcMethod = pRCInfo->rcMethod;
142*53ee8cc1Swenshuai.xi
143*53ee8cc1Swenshuai.xi // Bitrate usage monitoring
144*53ee8cc1Swenshuai.xi A = (MS_FLOAT)0.5; /* delay requirements */
145*53ee8cc1Swenshuai.xi rcctx->m_nMinDeputyCount = (MS_S32)(rcctx->m_fTargetFrameRate*CBR_DEPUTY_SECOND);
146*53ee8cc1Swenshuai.xi rcctx->m_nTargetFullness = (MS_S32)(A * rcctx->m_fAvgBitsPerFrame);
147*53ee8cc1Swenshuai.xi switch (rcctx->m_rcMethod) {
148*53ee8cc1Swenshuai.xi case VARIABLE_BITRATE:
149*53ee8cc1Swenshuai.xi rcctx->m_nDeputyCount = (MS_S32)(rcctx->m_fTargetFrameRate*VBR_DEPUTY_SECOND);
150*53ee8cc1Swenshuai.xi break;
151*53ee8cc1Swenshuai.xi case CONSTRAINED_VARIABLE_BITRATE:
152*53ee8cc1Swenshuai.xi rcctx->m_nDeputyCount = (MS_S32)(rcctx->m_fTargetFrameRate*CVBR_DEPUTY_SECOND);
153*53ee8cc1Swenshuai.xi break;
154*53ee8cc1Swenshuai.xi case STRICT_CONST_BITRATE:
155*53ee8cc1Swenshuai.xi rcctx->m_nWinIndex = 0;
156*53ee8cc1Swenshuai.xi rcctx->m_nWinIndexMax = (MS_S32)rcctx->m_fTargetFrameRate;
157*53ee8cc1Swenshuai.xi for (i=0; i<rcctx->m_nWinIndexMax; i++)
158*53ee8cc1Swenshuai.xi rcctx->m_SkipFrameHistory[i] = 0; // Not skipped.
159*53ee8cc1Swenshuai.xi rcctx->m_nSkipCount = 0;
160*53ee8cc1Swenshuai.xi rcctx->m_nContSkipCount = 0;
161*53ee8cc1Swenshuai.xi rcctx->m_nBitrateOverUsage = 0;
162*53ee8cc1Swenshuai.xi rcctx->m_nCompensateBitrate = 0;
163*53ee8cc1Swenshuai.xi rcctx->m_nCompensateFrame = 0;
164*53ee8cc1Swenshuai.xi // Treat original bitrate as ceiling, and create internal target bitrate.
165*53ee8cc1Swenshuai.xi rcctx->m_nBitrateMax = pRCInfo->m_nBitrate;
166*53ee8cc1Swenshuai.xi rcctx->m_nBitrate = rcctx->m_nBitrateMax * 9 / 10;
167*53ee8cc1Swenshuai.xi rcctx->m_nContGoodFrameCount = 0;
168*53ee8cc1Swenshuai.xi break;
169*53ee8cc1Swenshuai.xi case CONST_BITRATE:
170*53ee8cc1Swenshuai.xi default:
171*53ee8cc1Swenshuai.xi rcctx->m_nDeputyCount = (MS_S32)(rcctx->m_fTargetFrameRate*CBR_DEPUTY_SECOND);
172*53ee8cc1Swenshuai.xi break;
173*53ee8cc1Swenshuai.xi }
174*53ee8cc1Swenshuai.xi // Derived
175*53ee8cc1Swenshuai.xi rcctx->m_fAvgBitsPerFrame = (MS_FLOAT)rcctx->m_nBitrate / rcctx->m_fTargetFrameRate;
176*53ee8cc1Swenshuai.xi
177*53ee8cc1Swenshuai.xi // Adaptive frame-rate
178*53ee8cc1Swenshuai.xi if (rcctx->m_rcMethod == STRICT_CONST_BITRATE) {
179*53ee8cc1Swenshuai.xi rcctx->m_bDropFrameEnabled = rcctx->m_fMinFrameRate < rcctx->m_fTargetFrameRate ? 1 : 0;
180*53ee8cc1Swenshuai.xi rcctx->m_nSkipCountMax = (MS_S32)(rcctx->m_fTargetFrameRate - rcctx->m_fMinFrameRate);
181*53ee8cc1Swenshuai.xi }
182*53ee8cc1Swenshuai.xi else {
183*53ee8cc1Swenshuai.xi rcctx->m_fMinFrameRate = rcctx->m_fTargetFrameRate;
184*53ee8cc1Swenshuai.xi rcctx->m_bDropFrameEnabled = 0;
185*53ee8cc1Swenshuai.xi rcctx->m_nSkipCountMax = 0;
186*53ee8cc1Swenshuai.xi }
187*53ee8cc1Swenshuai.xi
188*53ee8cc1Swenshuai.xi rcctx->m_nFrameCount = 0;
189*53ee8cc1Swenshuai.xi rcctx->m_nTotalBits = 0;
190*53ee8cc1Swenshuai.xi rcctx->m_nLastFrameAvgQP = rcctx->m_nLastFrameBits = 0;
191*53ee8cc1Swenshuai.xi rcctx->m_nBufFullness = 0;
192*53ee8cc1Swenshuai.xi rcctx->m_fLongTermQP = 0;
193*53ee8cc1Swenshuai.xi rcctx->m_nNFrame = (rcctx->m_nWidth>>4)*(rcctx->m_nHeight>>4);
194*53ee8cc1Swenshuai.xi rcctx->m_nWidthInMb = rcctx->m_nWidth>>4;
195*53ee8cc1Swenshuai.xi
196*53ee8cc1Swenshuai.xi #if defined(CHECK_1SEC_BITRATE)
197*53ee8cc1Swenshuai.xi // Runtime bitrate
198*53ee8cc1Swenshuai.xi rcctx->m_nBrHistIndex = 0;
199*53ee8cc1Swenshuai.xi for (i=0; i<rcctx->m_fTargetFrameRate; i++)
200*53ee8cc1Swenshuai.xi rcctx->m_BitrateHistory[i] = (MS_S32)rcctx->m_fAvgBitsPerFrame;
201*53ee8cc1Swenshuai.xi rcctx->m_nUnsentBits = 0;
202*53ee8cc1Swenshuai.xi #endif
203*53ee8cc1Swenshuai.xi
204*53ee8cc1Swenshuai.xi ms_dprintf(DRV_L7,
205*53ee8cc1Swenshuai.xi "[SWVENC] rc_Init() w=%d, h=%d, FPS=%2.3f, MinFPS=%2.3f, Bitrate=%d, nSkipCountMax=%d\n",
206*53ee8cc1Swenshuai.xi (int)rcctx->m_nWidth, (int)rcctx->m_nHeight, rcctx->m_fTargetFrameRate, rcctx->m_fMinFrameRate,
207*53ee8cc1Swenshuai.xi (int)rcctx->m_nBitrate, (int)rcctx->m_nSkipCountMax);
208*53ee8cc1Swenshuai.xi ms_dprintf(DRV_L7,
209*53ee8cc1Swenshuai.xi "[SWVENC] rc_Init() PCount=%d, rcGranularity=%d\n",
210*53ee8cc1Swenshuai.xi (int)rcctx->m_nPCount, rcctx->m_rcGranularity);
211*53ee8cc1Swenshuai.xi }
212*53ee8cc1Swenshuai.xi
213*53ee8cc1Swenshuai.xi
rc_Finish(RateCtrl_t * rcctx)214*53ee8cc1Swenshuai.xi void rc_Finish(RateCtrl_t* rcctx)
215*53ee8cc1Swenshuai.xi {
216*53ee8cc1Swenshuai.xi #if 0
217*53ee8cc1Swenshuai.xi if (m_pfDev) {
218*53ee8cc1Swenshuai.xi free(m_pfDev);
219*53ee8cc1Swenshuai.xi m_pfDev = NULL;
220*53ee8cc1Swenshuai.xi }
221*53ee8cc1Swenshuai.xi if (m_pfAlpha) {
222*53ee8cc1Swenshuai.xi free(m_pfAlpha);
223*53ee8cc1Swenshuai.xi m_pfAlpha = NULL;
224*53ee8cc1Swenshuai.xi }
225*53ee8cc1Swenshuai.xi if (m_pfVar) {
226*53ee8cc1Swenshuai.xi free(m_pfVar);
227*53ee8cc1Swenshuai.xi m_pfVar = NULL;
228*53ee8cc1Swenshuai.xi }
229*53ee8cc1Swenshuai.xi #endif
230*53ee8cc1Swenshuai.xi }
231*53ee8cc1Swenshuai.xi
rc_CheckSkippedFrame(RateCtrl_t * rcctx)232*53ee8cc1Swenshuai.xi MS_S32 rc_CheckSkippedFrame(RateCtrl_t* rcctx)
233*53ee8cc1Swenshuai.xi {
234*53ee8cc1Swenshuai.xi if (!rcctx->m_bDropFrameEnabled)
235*53ee8cc1Swenshuai.xi return 0;
236*53ee8cc1Swenshuai.xi
237*53ee8cc1Swenshuai.xi return (rcctx->m_nContSkipCount>0 ? 1:0);
238*53ee8cc1Swenshuai.xi }
239*53ee8cc1Swenshuai.xi
rc_InitFrame(RateCtrl_t * rcctx,MS_S8 chFrameType)240*53ee8cc1Swenshuai.xi MS_S32 rc_InitFrame(RateCtrl_t* rcctx, MS_S8 chFrameType)
241*53ee8cc1Swenshuai.xi {
242*53ee8cc1Swenshuai.xi MS_S32 nDeputyCount, nInitQP;
243*53ee8cc1Swenshuai.xi
244*53ee8cc1Swenshuai.xi /* Target frame bitcount */
245*53ee8cc1Swenshuai.xi
246*53ee8cc1Swenshuai.xi if (rcctx->m_nFrameCount>0) {
247*53ee8cc1Swenshuai.xi MS_S32 delta = 0;
248*53ee8cc1Swenshuai.xi
249*53ee8cc1Swenshuai.xi // 1. Determine the number of future frame to compensate for current bitrate mismatch.
250*53ee8cc1Swenshuai.xi if (rcctx->m_nFrameCount>rcctx->m_nDeputyCount*MIN_DEPUTY_FACTOR)
251*53ee8cc1Swenshuai.xi nDeputyCount = rcctx->m_nDeputyCount;
252*53ee8cc1Swenshuai.xi else if (rcctx->m_nFrameCount<rcctx->m_nMinDeputyCount)
253*53ee8cc1Swenshuai.xi nDeputyCount = rcctx->m_nMinDeputyCount;
254*53ee8cc1Swenshuai.xi else
255*53ee8cc1Swenshuai.xi nDeputyCount = rcctx->m_nMinDeputyCount +
256*53ee8cc1Swenshuai.xi (rcctx->m_nFrameCount-rcctx->m_nMinDeputyCount)*(rcctx->m_nDeputyCount-rcctx->m_nMinDeputyCount)/(rcctx->m_nDeputyCount*MIN_DEPUTY_FACTOR-rcctx->m_nMinDeputyCount);
257*53ee8cc1Swenshuai.xi // 2. Calculate the bitcount that this frame should be compensate for.
258*53ee8cc1Swenshuai.xi if (rcctx->m_rcMethod==CONST_BITRATE) {
259*53ee8cc1Swenshuai.xi delta = (rcctx->m_nBufFullness>rcctx->m_nTargetFullness) ?
260*53ee8cc1Swenshuai.xi (MS_S32)((rcctx->m_nBufFullness-rcctx->m_nTargetFullness)/rcctx->m_fTargetFrameRate) : rcctx->m_nBufFullness-rcctx->m_nTargetFullness;
261*53ee8cc1Swenshuai.xi }
262*53ee8cc1Swenshuai.xi else if (rcctx->m_rcMethod==STRICT_CONST_BITRATE) {
263*53ee8cc1Swenshuai.xi MS_S32 d = rcctx->m_nBitrateOverUsage / (MS_S32)(rcctx->m_fTargetFrameRate);
264*53ee8cc1Swenshuai.xi //MS_S32 d = rcctx->m_nBitrateOverUsage / ((MS_S32)(rcctx->m_fTargetFrameRate)-rcctx->m_nSkipCount);
265*53ee8cc1Swenshuai.xi delta = d - rcctx->m_nCompensateBitrate;
266*53ee8cc1Swenshuai.xi }
267*53ee8cc1Swenshuai.xi else if (rcctx->m_rcMethod==VARIABLE_BITRATE) {
268*53ee8cc1Swenshuai.xi delta = (rcctx->m_nBufFullness-rcctx->m_nTargetFullness) / nDeputyCount;
269*53ee8cc1Swenshuai.xi if (delta>0 && (rcctx->m_nLastFrameAvgQP>rcctx->m_fLongTermQP))
270*53ee8cc1Swenshuai.xi delta = delta>>1; // Make it more variable bitrate to allow better quality
271*53ee8cc1Swenshuai.xi }
272*53ee8cc1Swenshuai.xi // 3. Finally, calculate the target bitcount.
273*53ee8cc1Swenshuai.xi if (rcctx->m_nPCount>0 && chFrameType=='I')
274*53ee8cc1Swenshuai.xi rcctx->m_nTargetBits = (MS_S32)((rcctx->m_fAvgBitsPerFrame*IFRAME_WEIGHT) - delta);
275*53ee8cc1Swenshuai.xi else {
276*53ee8cc1Swenshuai.xi rcctx->m_nTargetBits = (MS_S32)(rcctx->m_fAvgBitsPerFrame - delta);
277*53ee8cc1Swenshuai.xi }
278*53ee8cc1Swenshuai.xi if (rcctx->m_nTargetBits<rcctx->m_nNFrame)
279*53ee8cc1Swenshuai.xi rcctx->m_nTargetBits = rcctx->m_nNFrame; // At least one bit per MB. _rc_ComputeFrameQP() don't accept rcctx->m_nTargetBits<=0
280*53ee8cc1Swenshuai.xi }
281*53ee8cc1Swenshuai.xi else {
282*53ee8cc1Swenshuai.xi rcctx->m_nBufFullness = rcctx->m_nTargetFullness; // Initialization
283*53ee8cc1Swenshuai.xi rcctx->m_nTargetBits = (MS_S32)(rcctx->m_fAvgBitsPerFrame*IFRAME_WEIGHT); // Must be I-frame
284*53ee8cc1Swenshuai.xi }
285*53ee8cc1Swenshuai.xi
286*53ee8cc1Swenshuai.xi /* Return initial frame QP */
287*53ee8cc1Swenshuai.xi
288*53ee8cc1Swenshuai.xi nInitQP = _rc_ComputeFrameQP(rcctx, chFrameType);
289*53ee8cc1Swenshuai.xi rcctx->m_nLastFrameAvgQP = 0; // Will calculate average value later
290*53ee8cc1Swenshuai.xi ms_dprintf(DRV_L7,
291*53ee8cc1Swenshuai.xi "[SWVENC] %c#%5d rc_InitFrame() TargetBits=%7d InitQP=%2d Buffer=%7d Deputy=%d\n",
292*53ee8cc1Swenshuai.xi chFrameType, (int)rcctx->m_nFrameCount, (int)rcctx->m_nTargetBits, (int)nInitQP, (int)rcctx->m_nBufFullness, (int)nDeputyCount);
293*53ee8cc1Swenshuai.xi return nInitQP;
294*53ee8cc1Swenshuai.xi }
295*53ee8cc1Swenshuai.xi
rc_UpdateFrame(RateCtrl_t * rcctx,const MS_S32 totalUsedBits,const MS_S32 lastAvgQP,MS_BOOL bDummyFrame)296*53ee8cc1Swenshuai.xi void rc_UpdateFrame(RateCtrl_t* rcctx, const MS_S32 totalUsedBits,const MS_S32 lastAvgQP, MS_BOOL bDummyFrame)
297*53ee8cc1Swenshuai.xi {
298*53ee8cc1Swenshuai.xi MS_S32 nBufBits = totalUsedBits;
299*53ee8cc1Swenshuai.xi
300*53ee8cc1Swenshuai.xi // Update counter
301*53ee8cc1Swenshuai.xi rcctx->m_nFrameCount++;
302*53ee8cc1Swenshuai.xi rcctx->m_nTotalBits += totalUsedBits;
303*53ee8cc1Swenshuai.xi
304*53ee8cc1Swenshuai.xi if (!bDummyFrame) {
305*53ee8cc1Swenshuai.xi rcctx->m_nLastTargetBits = rcctx->m_nTargetBits;
306*53ee8cc1Swenshuai.xi rcctx->m_nLastFrameBits = totalUsedBits;
307*53ee8cc1Swenshuai.xi rcctx->m_nLastFrameAvgQP = lastAvgQP;
308*53ee8cc1Swenshuai.xi // Variable bitrate
309*53ee8cc1Swenshuai.xi if (rcctx->m_rcMethod==VARIABLE_BITRATE)
310*53ee8cc1Swenshuai.xi rcctx->m_fLongTermQP += (rcctx->m_nLastFrameAvgQP-rcctx->m_fLongTermQP) / rcctx->m_nFrameCount;
311*53ee8cc1Swenshuai.xi }
312*53ee8cc1Swenshuai.xi
313*53ee8cc1Swenshuai.xi // Update buffer status
314*53ee8cc1Swenshuai.xi rcctx->m_nBufFullness += (MS_S32)(nBufBits - rcctx->m_fAvgBitsPerFrame);
315*53ee8cc1Swenshuai.xi
316*53ee8cc1Swenshuai.xi // Skipped frame status update
317*53ee8cc1Swenshuai.xi if (rcctx->m_bDropFrameEnabled) {
318*53ee8cc1Swenshuai.xi if (bDummyFrame) {
319*53ee8cc1Swenshuai.xi if (rcctx->m_nContSkipCount>0)
320*53ee8cc1Swenshuai.xi rcctx->m_nContSkipCount--;
321*53ee8cc1Swenshuai.xi if (rcctx->m_nCompensateFrame>0) {
322*53ee8cc1Swenshuai.xi rcctx->m_nCompensateBitrate += (MS_S32)(rcctx->m_fAvgBitsPerFrame)-totalUsedBits;
323*53ee8cc1Swenshuai.xi rcctx->m_nCompensateFrame--;
324*53ee8cc1Swenshuai.xi }
325*53ee8cc1Swenshuai.xi rcctx->m_nBitrateOverUsage += (totalUsedBits-(MS_S32)rcctx->m_fAvgBitsPerFrame);
326*53ee8cc1Swenshuai.xi rcctx->m_nContGoodFrameCount = 0;
327*53ee8cc1Swenshuai.xi }
328*53ee8cc1Swenshuai.xi else {
329*53ee8cc1Swenshuai.xi rcctx->m_nBitrateOverUsage += (totalUsedBits-(MS_S32)rcctx->m_fAvgBitsPerFrame);
330*53ee8cc1Swenshuai.xi if (rcctx->m_nBitrateOverUsage < rcctx->m_nBitrate-rcctx->m_nBitrateMax) {
331*53ee8cc1Swenshuai.xi rcctx->m_nBitrateOverUsage = rcctx->m_nBitrate-rcctx->m_nBitrateMax;
332*53ee8cc1Swenshuai.xi ms_dprintf(DRV_L7, "m_nBitrateOverUsage under-run!\n");
333*53ee8cc1Swenshuai.xi }
334*53ee8cc1Swenshuai.xi rcctx->m_nContGoodFrameCount++;
335*53ee8cc1Swenshuai.xi }
336*53ee8cc1Swenshuai.xi
337*53ee8cc1Swenshuai.xi // Update skip history
338*53ee8cc1Swenshuai.xi rcctx->m_nSkipCount -= rcctx->m_SkipFrameHistory[rcctx->m_nWinIndex];
339*53ee8cc1Swenshuai.xi rcctx->m_nSkipCount += bDummyFrame;
340*53ee8cc1Swenshuai.xi if (rcctx->m_nSkipCount>rcctx->m_nSkipCountMax)
341*53ee8cc1Swenshuai.xi rcctx->m_nSkipCount = rcctx->m_nSkipCountMax;
342*53ee8cc1Swenshuai.xi rcctx->m_SkipFrameHistory[rcctx->m_nWinIndex++] = bDummyFrame;
343*53ee8cc1Swenshuai.xi if (rcctx->m_nWinIndex==rcctx->m_nWinIndexMax)
344*53ee8cc1Swenshuai.xi rcctx->m_nWinIndex = 0;
345*53ee8cc1Swenshuai.xi
346*53ee8cc1Swenshuai.xi // Obeying the minimal framerate; trying to avoid too long continuous skip-frame duration.
347*53ee8cc1Swenshuai.xi if (rcctx->m_nSkipCount<rcctx->m_nSkipCountMax && !bDummyFrame) {
348*53ee8cc1Swenshuai.xi rcctx->m_nContSkipCount = 0;
349*53ee8cc1Swenshuai.xi rcctx->m_nCompensateBitrate = 0;
350*53ee8cc1Swenshuai.xi rcctx->m_nCompensateFrame = 0;
351*53ee8cc1Swenshuai.xi // Determine how many next frames need to be skipped.
352*53ee8cc1Swenshuai.xi if (rcctx->m_nLastFrameAvgQP > BAD_FRAME_QP_THR) {
353*53ee8cc1Swenshuai.xi // Below equation: Min=0, Max=m_nSkipCountMax-m_nSkipCount
354*53ee8cc1Swenshuai.xi rcctx->m_nContSkipCount = (rcctx->m_nLastFrameAvgQP-BAD_FRAME_QP_THR)*(rcctx->m_nSkipCountMax-rcctx->m_nSkipCount) / (SPEC_MAX_QP-BAD_FRAME_QP_THR);
355*53ee8cc1Swenshuai.xi rcctx->m_nCompensateFrame = rcctx->m_nContSkipCount;
356*53ee8cc1Swenshuai.xi }
357*53ee8cc1Swenshuai.xi else if (rcctx->m_nContGoodFrameCount>=4 && rcctx->m_nLastFrameAvgQP<=GOOD_FRAME_QP_THR) {
358*53ee8cc1Swenshuai.xi rcctx->m_nContSkipCount = 1;
359*53ee8cc1Swenshuai.xi rcctx->m_nCompensateFrame = rcctx->m_nContSkipCount;
360*53ee8cc1Swenshuai.xi rcctx->m_nContGoodFrameCount = 0;
361*53ee8cc1Swenshuai.xi }
362*53ee8cc1Swenshuai.xi if (rcctx->m_nFrameCount>0 && rcctx->m_nBitrateOverUsage>(rcctx->m_nBitrateMax-rcctx->m_nBitrate)) {
363*53ee8cc1Swenshuai.xi // Below equation: Min=1
364*53ee8cc1Swenshuai.xi rcctx->m_nContSkipCount += (rcctx->m_nBitrateOverUsage-(rcctx->m_nBitrateMax-rcctx->m_nBitrate)) / (MS_S32)rcctx->m_fAvgBitsPerFrame;
365*53ee8cc1Swenshuai.xi // Marked-out means we do allow the minimal framerate be broken when accumulated bitrate over-usage is too large.
366*53ee8cc1Swenshuai.xi // if (rcctx->m_nContSkipCount > rcctx->m_nSkipCountMax-rcctx->m_nSkipCount)
367*53ee8cc1Swenshuai.xi // rcctx->m_nContSkipCount = rcctx->m_nSkipCountMax-rcctx->m_nSkipCount;
368*53ee8cc1Swenshuai.xi }
369*53ee8cc1Swenshuai.xi }
370*53ee8cc1Swenshuai.xi
371*53ee8cc1Swenshuai.xi ms_dprintf(DRV_L7, "[%d] LastAvgQP=%d, SkipCount=%d, ContSkipCount=%d, OverUsage=%d\n",
372*53ee8cc1Swenshuai.xi (int)rcctx->m_nFrameCount,
373*53ee8cc1Swenshuai.xi (int)rcctx->m_nLastFrameAvgQP,
374*53ee8cc1Swenshuai.xi (int)rcctx->m_nSkipCount,
375*53ee8cc1Swenshuai.xi (int)rcctx->m_nContSkipCount,
376*53ee8cc1Swenshuai.xi (int)rcctx->m_nBitrateOverUsage);
377*53ee8cc1Swenshuai.xi } // m_bDropFrameEnabled
378*53ee8cc1Swenshuai.xi
379*53ee8cc1Swenshuai.xi
380*53ee8cc1Swenshuai.xi
381*53ee8cc1Swenshuai.xi
382*53ee8cc1Swenshuai.xi #if defined(CHECK_1SEC_BITRATE)
383*53ee8cc1Swenshuai.xi {
384*53ee8cc1Swenshuai.xi MS_S32 i, nRuntimeBitrate;
385*53ee8cc1Swenshuai.xi // Runtime bitrate
386*53ee8cc1Swenshuai.xi rcctx->m_BitrateHistory[rcctx->m_nBrHistIndex++] = totalUsedBits;
387*53ee8cc1Swenshuai.xi if (rcctx->m_nBrHistIndex==(MS_S32)rcctx->m_fTargetFrameRate)
388*53ee8cc1Swenshuai.xi rcctx->m_nBrHistIndex = 0;
389*53ee8cc1Swenshuai.xi nRuntimeBitrate = 0;
390*53ee8cc1Swenshuai.xi for (i=0; i<(MS_S32)rcctx->m_fTargetFrameRate; i++)
391*53ee8cc1Swenshuai.xi nRuntimeBitrate += rcctx->m_BitrateHistory[i];
392*53ee8cc1Swenshuai.xi // Runtime delay
393*53ee8cc1Swenshuai.xi rcctx->m_nUnsentBits += totalUsedBits - (MS_S32)(rcctx->m_nBitrateMax/rcctx->m_fTargetFrameRate);
394*53ee8cc1Swenshuai.xi if (rcctx->m_nUnsentBits<0)
395*53ee8cc1Swenshuai.xi rcctx->m_nUnsentBits = 0;
396*53ee8cc1Swenshuai.xi ms_dprintf(DRV_L7,
397*53ee8cc1Swenshuai.xi "[SWVENC] rc_UpdateFrame(%7d bits, %3d%%) AvgQ=%2d LTQ=%2d LtBitrate=%8d, StBitrate=%8d, Delay=%dms\n",
398*53ee8cc1Swenshuai.xi totalUsedBits, bDummyFrame?0:(totalUsedBits-rcctx->m_nTargetBits)*100/rcctx->m_nTargetBits, rcctx->m_nLastFrameAvgQP,
399*53ee8cc1Swenshuai.xi (MS_S32)rcctx->m_fLongTermQP, (MS_S32)(rcctx->m_nTotalBits*rcctx->m_fTargetFrameRate/rcctx->m_nFrameCount),
400*53ee8cc1Swenshuai.xi nRuntimeBitrate, rcctx->m_nUnsentBits*1000/rcctx->m_nBitrateMax);
401*53ee8cc1Swenshuai.xi }
402*53ee8cc1Swenshuai.xi #else
403*53ee8cc1Swenshuai.xi #endif
404*53ee8cc1Swenshuai.xi }
405*53ee8cc1Swenshuai.xi
406*53ee8cc1Swenshuai.xi #define SMOOTH_PERIOD 1.0f
_rc_ComputeFrameQP(RateCtrl_t * rcctx,MS_S8 chFrameType)407*53ee8cc1Swenshuai.xi static MS_S32 _rc_ComputeFrameQP(RateCtrl_t* rcctx, MS_S8 chFrameType)
408*53ee8cc1Swenshuai.xi {
409*53ee8cc1Swenshuai.xi MS_S32 newQP=0, dQP;
410*53ee8cc1Swenshuai.xi MS_FLOAT buf_rest;
411*53ee8cc1Swenshuai.xi MS_S32 buf_rest_pic;
412*53ee8cc1Swenshuai.xi MS_S32 frames_left;
413*53ee8cc1Swenshuai.xi MS_S32 nAdjust;
414*53ee8cc1Swenshuai.xi
415*53ee8cc1Swenshuai.xi // For the very first frame, guess one qp!
416*53ee8cc1Swenshuai.xi if (rcctx->m_nFrameCount==0) {
417*53ee8cc1Swenshuai.xi MS_S32 nbpMb;
418*53ee8cc1Swenshuai.xi nbpMb = (MS_S32)(rcctx->m_nBitrate/(10*rcctx->m_nNFrame*rcctx->m_fTargetFrameRate));
419*53ee8cc1Swenshuai.xi if (nbpMb>100)
420*53ee8cc1Swenshuai.xi return 2;//1;
421*53ee8cc1Swenshuai.xi else if (nbpMb>20)
422*53ee8cc1Swenshuai.xi return 4;
423*53ee8cc1Swenshuai.xi else if (nbpMb>10)
424*53ee8cc1Swenshuai.xi return 8;
425*53ee8cc1Swenshuai.xi else if (nbpMb>6)
426*53ee8cc1Swenshuai.xi return 12;
427*53ee8cc1Swenshuai.xi else if (nbpMb>4)
428*53ee8cc1Swenshuai.xi return 16;
429*53ee8cc1Swenshuai.xi else
430*53ee8cc1Swenshuai.xi return 20;
431*53ee8cc1Swenshuai.xi }
432*53ee8cc1Swenshuai.xi
433*53ee8cc1Swenshuai.xi if (rcctx->m_rcMethod==STRICT_CONST_BITRATE) {
434*53ee8cc1Swenshuai.xi newQP = rcctx->m_nLastFrameAvgQP;
435*53ee8cc1Swenshuai.xi if (rcctx->m_nTargetBits > rcctx->m_nLastFrameBits)
436*53ee8cc1Swenshuai.xi newQP -= MFE_MIN(4, rcctx->m_nTargetBits/rcctx->m_nLastFrameBits);
437*53ee8cc1Swenshuai.xi else
438*53ee8cc1Swenshuai.xi newQP += MFE_MIN(4, rcctx->m_nLastFrameBits/rcctx->m_nTargetBits);
439*53ee8cc1Swenshuai.xi newQP = MFE_MIN (SPEC_MAX_QP, newQP);
440*53ee8cc1Swenshuai.xi newQP = MFE_MAX (/*SPEC_MIN_QP*/SCBR_BEST_QP, newQP);
441*53ee8cc1Swenshuai.xi }
442*53ee8cc1Swenshuai.xi else
443*53ee8cc1Swenshuai.xi if (rcctx->m_rcMethod==CONST_BITRATE/* || rcctx->m_rcMethod==STRICT_CONST_BITRATE*/) {
444*53ee8cc1Swenshuai.xi buf_rest = (((MS_FLOAT)(rcctx->m_nFrameCount)/rcctx->m_fTargetFrameRate+SMOOTH_PERIOD) * rcctx->m_nBitrate) - rcctx->m_nTotalBits;
445*53ee8cc1Swenshuai.xi newQP = rcctx->m_nLastFrameAvgQP;
446*53ee8cc1Swenshuai.xi frames_left = (MS_S32)(SMOOTH_PERIOD * rcctx->m_fTargetFrameRate);
447*53ee8cc1Swenshuai.xi //if (frames_left > 0)
448*53ee8cc1Swenshuai.xi {
449*53ee8cc1Swenshuai.xi buf_rest_pic = (MS_S32)(buf_rest / frames_left);
450*53ee8cc1Swenshuai.xi dQP = MFE_MAX (1, rcctx->m_nLastFrameAvgQP>>3);
451*53ee8cc1Swenshuai.xi if (rcctx->m_nLastFrameBits > (buf_rest_pic*9)>>3) {
452*53ee8cc1Swenshuai.xi newQP = MFE_MIN (SPEC_MAX_QP, rcctx->m_nLastFrameAvgQP+dQP);
453*53ee8cc1Swenshuai.xi }
454*53ee8cc1Swenshuai.xi else if (rcctx->m_nLastFrameBits < (buf_rest_pic*7)>>3) {
455*53ee8cc1Swenshuai.xi newQP = MFE_MAX (SPEC_MIN_QP, rcctx->m_nLastFrameAvgQP-dQP);
456*53ee8cc1Swenshuai.xi }
457*53ee8cc1Swenshuai.xi }
458*53ee8cc1Swenshuai.xi }
459*53ee8cc1Swenshuai.xi else if (rcctx->m_rcMethod==VARIABLE_BITRATE) {
460*53ee8cc1Swenshuai.xi MS_S32 nLowQ, nHighQ;
461*53ee8cc1Swenshuai.xi MS_S32 nLowBound, nHighBound;
462*53ee8cc1Swenshuai.xi if (rcctx->m_nPCount>0 && chFrameType=='I') {
463*53ee8cc1Swenshuai.xi newQP = (MS_S32)(rcctx->m_nLastFrameAvgQP-1);
464*53ee8cc1Swenshuai.xi newQP = MFE_MAX(SPEC_MIN_QP, newQP);
465*53ee8cc1Swenshuai.xi }
466*53ee8cc1Swenshuai.xi else {
467*53ee8cc1Swenshuai.xi MS_S32 nAdjLTQ;
468*53ee8cc1Swenshuai.xi if (rcctx->m_nFrameCount>=(MS_S32)(rcctx->m_fTargetFrameRate) || rcctx->m_nPCount==0) {
469*53ee8cc1Swenshuai.xi nAdjLTQ = (MS_S32)(rcctx->m_fLongTermQP * (rcctx->m_nTotalBits/rcctx->m_nFrameCount) / rcctx->m_fAvgBitsPerFrame);
470*53ee8cc1Swenshuai.xi nAdjLTQ = MFE_MIN(SPEC_MAX_QP, MFE_MAX(SPEC_MIN_QP, nAdjLTQ));
471*53ee8cc1Swenshuai.xi }
472*53ee8cc1Swenshuai.xi else {
473*53ee8cc1Swenshuai.xi nAdjLTQ = (MS_S32)(rcctx->m_fLongTermQP); // Wait for stabilization
474*53ee8cc1Swenshuai.xi }
475*53ee8cc1Swenshuai.xi MS_ASSERT(rcctx->m_nTargetBits>0);
476*53ee8cc1Swenshuai.xi newQP = (MS_S32)(nAdjLTQ * rcctx->m_fAvgBitsPerFrame / rcctx->m_nTargetBits);
477*53ee8cc1Swenshuai.xi
478*53ee8cc1Swenshuai.xi /*
479*53ee8cc1Swenshuai.xi nLowBound = nHighBound = 2;
480*53ee8cc1Swenshuai.xi if (rcctx->m_nLastFrameBits>rcctx->m_nLastTargetBits) {
481*53ee8cc1Swenshuai.xi nHighBound += MS_S32(rcctx->m_nLastFrameBits/rcctx->m_nLastTargetBits);
482*53ee8cc1Swenshuai.xi if (nHighBound>4) nHighBound=4;
483*53ee8cc1Swenshuai.xi }
484*53ee8cc1Swenshuai.xi if (rcctx->m_fAvgBitsPerFrame>rcctx->m_nTargetBits) {
485*53ee8cc1Swenshuai.xi nHighQ = MIN(31, MS_S32(nAdjLTQ)<<nHighBound);
486*53ee8cc1Swenshuai.xi newQP = MIN(nHighQ, newQP);
487*53ee8cc1Swenshuai.xi }
488*53ee8cc1Swenshuai.xi else {
489*53ee8cc1Swenshuai.xi nLowQ = MAX(1, MS_S32(nAdjLTQ)>>nLowBound);
490*53ee8cc1Swenshuai.xi newQP = MAX(nLowQ, newQP);
491*53ee8cc1Swenshuai.xi }
492*53ee8cc1Swenshuai.xi */
493*53ee8cc1Swenshuai.xi nAdjust = MFE_MAX(2, (MS_S32)(nAdjLTQ)>>2);
494*53ee8cc1Swenshuai.xi nLowBound = (MS_S32)nAdjLTQ - nAdjust;
495*53ee8cc1Swenshuai.xi nHighBound = (MS_S32)nAdjLTQ + nAdjust;
496*53ee8cc1Swenshuai.xi if (rcctx->m_nLastFrameBits>rcctx->m_nLastTargetBits) {
497*53ee8cc1Swenshuai.xi nAdjust = (MS_S32)(rcctx->m_nLastFrameBits/rcctx->m_nLastTargetBits);
498*53ee8cc1Swenshuai.xi if (nAdjust>2) nAdjust=2;
499*53ee8cc1Swenshuai.xi nHighBound += nAdjust;
500*53ee8cc1Swenshuai.xi }
501*53ee8cc1Swenshuai.xi if (rcctx->m_fAvgBitsPerFrame>rcctx->m_nTargetBits) {
502*53ee8cc1Swenshuai.xi nHighQ = MFE_MIN(SPEC_MAX_QP, nHighBound);
503*53ee8cc1Swenshuai.xi newQP = MFE_MIN(nHighQ, newQP);
504*53ee8cc1Swenshuai.xi }
505*53ee8cc1Swenshuai.xi else {
506*53ee8cc1Swenshuai.xi nLowQ = MFE_MAX(SPEC_MIN_QP, nLowBound);
507*53ee8cc1Swenshuai.xi newQP = MFE_MAX(nLowQ, newQP);
508*53ee8cc1Swenshuai.xi }
509*53ee8cc1Swenshuai.xi }
510*53ee8cc1Swenshuai.xi }
511*53ee8cc1Swenshuai.xi
512*53ee8cc1Swenshuai.xi return newQP;
513*53ee8cc1Swenshuai.xi }
514