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