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