source: SHVCSoftware/branches/0.1.1-bugfix/source/Lib/TLibEncoder/TEncRateCtrl.cpp @ 1497

Last change on this file since 1497 was 2, checked in by seregin, 12 years ago

Initial import by Vadim Seregin <vseregin@…>

File size: 20.3 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2012, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TEncRateCtrl.cpp
35    \brief    Rate control manager class
36*/
37#include "TEncRateCtrl.h"
38#include "../TLibCommon/TComPic.h"
39
40#include <cmath>
41
42using namespace std;
43
44#define ADJUSTMENT_FACTOR       0.60
45#define HIGH_QSTEP_THRESHOLD    9.5238
46#define HIGH_QSTEP_ALPHA        4.9371
47#define HIGH_QSTEP_BETA         0.0922
48#define LOW_QSTEP_ALPHA         16.7429
49#define LOW_QSTEP_BETA          -1.1494
50
51#define MAD_PRED_Y1             1.0
52#define MAD_PRED_Y2             0.0
53
54enum MAD_HISOTRY {
55  MAD_PPPrevious = 0,
56  MAD_PPrevious  = 1,
57  MAD_Previous   = 2
58};
59
60Void    MADLinearModel::initMADLinearModel()
61{
62  m_activeOn = false;
63  m_paramY1  = 1.0;
64  m_paramY2  = 0.0;
65  m_costMADs[0] = m_costMADs[1] = m_costMADs[2] = 0.0;
66}
67
68Double  MADLinearModel::getMAD()
69{
70  Double costPredMAD = m_paramY1 * m_costMADs[MAD_Previous] + m_paramY2;
71
72  if(costPredMAD < 0)
73  {
74    costPredMAD = m_costMADs[MAD_Previous];
75    m_paramY1   = MAD_PRED_Y1;
76    m_paramY2   = MAD_PRED_Y2;
77  } 
78  return costPredMAD;
79}
80
81Void    MADLinearModel::updateMADLiearModel()
82{
83  Double dNewY1 = ((m_costMADs[MAD_Previous] - m_costMADs[MAD_PPrevious]) / (m_costMADs[MAD_PPrevious] - m_costMADs[MAD_PPPrevious]));
84  Double dNewY2 =  (m_costMADs[MAD_Previous] - (dNewY1*m_costMADs[MAD_PPrevious]));
85 
86  m_paramY1 = 0.70+0.20*m_paramY1+ 0.10*dNewY1;
87  m_paramY2 =      0.20*m_paramY2+ 0.10*dNewY2;
88}
89
90Void    MADLinearModel::updateMADHistory(Double dMAD)
91{
92  m_costMADs[MAD_PPPrevious] = m_costMADs[MAD_PPrevious];
93  m_costMADs[MAD_PPrevious ] = m_costMADs[MAD_Previous ];
94  m_costMADs[MAD_Previous  ] = dMAD;
95  m_activeOn = (m_costMADs[MAD_Previous  ] && m_costMADs[MAD_PPrevious ] && m_costMADs[MAD_PPPrevious]);
96}
97
98
99Void    PixelBaseURQQuadraticModel::initPixelBaseQuadraticModel()
100{
101  m_paramHighX1 = HIGH_QSTEP_ALPHA;
102  m_paramHighX2 = HIGH_QSTEP_BETA;
103  m_paramLowX1  = LOW_QSTEP_ALPHA;
104  m_paramLowX2  = LOW_QSTEP_BETA;
105}
106
107Int     PixelBaseURQQuadraticModel::getQP(Int qp, Int targetBits, Int numberOfPixels, Double costPredMAD)
108{
109  Double qStep;
110  Double bppPerMAD = (Double)(targetBits/(numberOfPixels*costPredMAD));
111 
112  if(xConvertQP2QStep(qp) >= HIGH_QSTEP_THRESHOLD)
113  {
114#if J0260
115    qStep = 1/( sqrt((bppPerMAD/m_paramHighX1)+((m_paramHighX2*m_paramHighX2)/(4*m_paramHighX1*m_paramHighX1))) - (m_paramHighX2/(2*m_paramHighX1)));
116#else
117    qStep = 1/( sqrt((bppPerMAD/m_paramHighX1)+((m_paramHighX2*m_paramHighX2)/(4*m_paramHighX1*m_paramHighX1*m_paramHighX1))) - (m_paramHighX2/(2*m_paramHighX1)));
118#endif
119  }
120  else
121  {
122#if J0260
123    qStep = 1/( sqrt((bppPerMAD/m_paramLowX1)+((m_paramLowX2*m_paramLowX2)/(4*m_paramLowX1*m_paramLowX1))) - (m_paramLowX2/(2*m_paramLowX1)));
124#else
125    qStep = 1/( sqrt((bppPerMAD/m_paramLowX1)+((m_paramLowX2*m_paramLowX2)/(4*m_paramLowX1*m_paramLowX1*m_paramLowX1))) - (m_paramLowX2/(2*m_paramLowX1)));
126#endif
127  }
128 
129  return xConvertQStep2QP(qStep);
130}
131
132Void    PixelBaseURQQuadraticModel::updatePixelBasedURQQuadraticModel (Int qp, Int bits, Int numberOfPixels, Double costMAD)
133{
134  Double qStep     = xConvertQP2QStep(qp);
135  Double invqStep = (1/qStep);
136  Double paramNewX1, paramNewX2;
137 
138  if(qStep >= HIGH_QSTEP_THRESHOLD)
139  {
140    paramNewX2    = (((bits/(numberOfPixels*costMAD))-(23.3772*invqStep*invqStep))/((1-200*invqStep)*invqStep));
141    paramNewX1    = (23.3772-200*paramNewX2);
142    m_paramHighX1 = 0.70*HIGH_QSTEP_ALPHA + 0.20 * m_paramHighX1 + 0.10 * paramNewX1;
143    m_paramHighX2 = 0.70*HIGH_QSTEP_BETA  + 0.20 * m_paramHighX2 + 0.10 * paramNewX2;
144  }
145  else
146  {
147    paramNewX2   = (((bits/(numberOfPixels*costMAD))-(5.8091*invqStep*invqStep))/((1-9.5455*invqStep)*invqStep));
148    paramNewX1   = (5.8091-9.5455*paramNewX2);
149    m_paramLowX1 = 0.90*LOW_QSTEP_ALPHA + 0.09 * m_paramLowX1 + 0.01 * paramNewX1;
150    m_paramLowX2 = 0.90*LOW_QSTEP_BETA  + 0.09 * m_paramLowX2 + 0.01 * paramNewX2;
151  }
152}
153
154Bool    PixelBaseURQQuadraticModel::checkUpdateAvailable(Int qpReference )
155{ 
156  Double qStep = xConvertQP2QStep(qpReference);
157
158  if (qStep > xConvertQP2QStep(MAX_QP) 
159    ||qStep < xConvertQP2QStep(MIN_QP) )
160  {
161    return false;
162  }
163
164  return true;
165}
166
167Double  PixelBaseURQQuadraticModel::xConvertQP2QStep(Int qp )
168{
169  Int i;
170  Double qStep;
171  static const Double mapQP2QSTEP[6] = { 0.625, 0.703, 0.797, 0.891, 1.000, 1.125 };
172
173  qStep = mapQP2QSTEP[qp % 6];
174  for( i=0; i<(qp/6); i++)
175  {
176    qStep *= 2;
177  }
178
179  return qStep;
180}
181
182Int     PixelBaseURQQuadraticModel::xConvertQStep2QP(Double qStep )
183{
184  Int per = 0, rem = 0;
185
186  if( qStep < xConvertQP2QStep(MIN_QP))
187  {
188    return MIN_QP;
189  }
190  else if (qStep > xConvertQP2QStep(MAX_QP) )
191  {
192    return MAX_QP;
193  }
194
195  while( qStep > xConvertQP2QStep(5) )
196  {
197    qStep /= 2.0;
198    per++;
199  }
200
201  if (qStep <= 0.625)
202  {
203    rem = 0;
204  }
205  else if (qStep <= 0.703)
206  {
207    rem = 1;
208  }
209  else if (qStep <= 0.797)
210  {
211    rem = 2;
212  }
213  else if (qStep <= 0.891)
214  {
215    rem = 3;
216  }
217  else if (qStep <= 1.000)
218  {
219    rem = 4;
220  }
221  else
222  {
223    rem = 5;
224  }
225  return (per * 6 + rem);
226}
227
228
229Void  TEncRateCtrl::create(Int sizeIntraPeriod, Int sizeGOP, Int frameRate, Int targetKbps, Int qp, Int numLCUInBasicUnit, Int sourceWidth, Int sourceHeight, Int maxCUWidth, Int maxCUHeight)
230{
231  Int leftInHeight, leftInWidth;
232
233  m_sourceWidthInLCU         = (sourceWidth  / maxCUWidth  ) + (( sourceWidth  %  maxCUWidth ) ? 1 : 0);
234  m_sourceHeightInLCU        = (sourceHeight / maxCUHeight) + (( sourceHeight %  maxCUHeight) ? 1 : 0); 
235  m_isLowdelay               = (sizeIntraPeriod == -1) ? true : false;
236#if !BUFFERING_PERIOD_AND_TIMING_SEI
237  m_prevBitrate              = targetKbps*1000;
238  m_currBitrate              = targetKbps*1000;
239#else
240  m_prevBitrate              = ( targetKbps << 10 );  // in units of 1,024 bps
241  m_currBitrate              = ( targetKbps << 10 );
242#endif
243  m_frameRate                = frameRate;
244  m_refFrameNum              = m_isLowdelay ? (sizeGOP) : (sizeGOP>>1);
245  m_nonRefFrameNum           = sizeGOP-m_refFrameNum;
246  m_sizeGOP                  = sizeGOP;
247  m_numOfPixels              = ((sourceWidth*sourceHeight*3)>>1);
248  m_indexGOP                 = 0;
249  m_indexFrame               = 0;
250  m_indexLCU                 = 0;
251  m_indexUnit                = 0;
252  m_indexRefFrame            = 0;
253  m_indexNonRefFrame         = 0;
254  m_occupancyVB              = 0;
255  m_initialOVB               = 0;
256  m_targetBufLevel           = 0;
257  m_initialTBL               = 0;
258  m_occupancyVBInFrame       = 0;
259  m_remainingBitsInGOP       = (m_currBitrate*sizeGOP/m_frameRate);
260  m_remainingBitsInFrame     = 0;
261  m_numUnitInFrame           = m_sourceWidthInLCU*m_sourceHeightInLCU;
262  m_cMADLinearModel.        initMADLinearModel();
263  m_cPixelURQQuadraticModel.initPixelBaseQuadraticModel();
264
265  m_costRefAvgWeighting      = 0.0;
266  m_costNonRefAvgWeighting   = 0.0;
267  m_costAvgbpp               = 0.0; 
268  m_activeUnitLevelOn        = false;
269
270  m_pcFrameData              = new FrameData   [sizeGOP+1];         initFrameData(qp);
271  m_pcLCUData                = new LCUData     [m_numUnitInFrame];  initUnitData (qp);
272
273  for(Int i = 0, addressUnit = 0; i < m_sourceHeightInLCU*maxCUHeight; i += maxCUHeight) 
274  {
275    leftInHeight = sourceHeight - i;
276    leftInHeight = min(leftInHeight, maxCUHeight);
277    for(Int j = 0; j < m_sourceWidthInLCU*maxCUWidth; j += maxCUWidth, addressUnit++)
278    {
279      leftInWidth = sourceWidth - j;
280      leftInWidth = min(leftInWidth, maxCUWidth);
281      m_pcLCUData[addressUnit].m_widthInPixel = leftInWidth;
282      m_pcLCUData[addressUnit].m_heightInPixel= leftInHeight;
283      m_pcLCUData[addressUnit].m_pixels       = ((leftInHeight*leftInWidth*3)>>1);
284    }
285  }
286}
287
288Void  TEncRateCtrl::destroy()
289{
290  if(m_pcFrameData)
291  {
292    delete [] m_pcFrameData;
293    m_pcFrameData = NULL;
294  }
295  if(m_pcLCUData)
296  {
297    delete [] m_pcLCUData;
298    m_pcLCUData = NULL;
299  }
300}
301
302Void  TEncRateCtrl::initFrameData   (Int qp)
303{
304  for(Int i = 0 ; i <= m_sizeGOP; i++)
305  {
306    m_pcFrameData[i].m_isReferenced = false;
307    m_pcFrameData[i].m_costMAD      = 0.0;
308    m_pcFrameData[i].m_bits         = 0;
309    m_pcFrameData[i].m_qp           = qp;
310  }
311}
312
313Void  TEncRateCtrl::initUnitData    (Int qp)
314{
315  for(Int i = 1 ; i < m_numUnitInFrame; i++)
316  {
317    m_pcLCUData[i].m_qp            = qp;
318    m_pcLCUData[i].m_bits          = 0;
319    m_pcLCUData[i].m_pixels        = 0;
320    m_pcLCUData[i].m_widthInPixel  = 0;
321    m_pcLCUData[i].m_heightInPixel = 0;
322    m_pcLCUData[i].m_costMAD       = 0.0;
323  }
324}
325
326Int  TEncRateCtrl::getFrameQP(Bool isReferenced, Int POC)
327{
328  Int numofReferenced = 0;
329  Int finalQP = 0;
330  FrameData* pcFrameData;
331
332  m_indexPOCInGOP = (POC%m_sizeGOP) == 0 ? m_sizeGOP : (POC%m_sizeGOP);
333  pcFrameData     = &m_pcFrameData[m_indexPOCInGOP];
334   
335  if(m_indexFrame != 0)
336  {
337    if(isReferenced)
338    {
339      Double gamma = m_isLowdelay ? 0.5 : 0.25;
340      Double beta  = m_isLowdelay ? 0.9 : 0.6;
341      Int    numRemainingRefFrames  = m_refFrameNum    - m_indexRefFrame;
342      Int    numRemainingNRefFrames = m_nonRefFrameNum - m_indexNonRefFrame;
343     
344      Double targetBitsOccupancy  = (m_currBitrate/(Double)m_frameRate) + gamma*(m_targetBufLevel-m_occupancyVB - (m_initialOVB/(Double)m_frameRate));
345      Double targetBitsLeftBudget = ((m_costRefAvgWeighting*m_remainingBitsInGOP)/((m_costRefAvgWeighting*numRemainingRefFrames)+(m_costNonRefAvgWeighting*numRemainingNRefFrames)));
346
347      m_targetBits = (Int)(beta * targetBitsLeftBudget + (1-beta) * targetBitsOccupancy);
348 
349      if(m_targetBits <= 0 || m_remainingBitsInGOP <= 0)
350      {
351        finalQP = m_pcFrameData[m_indexPrevPOCInGOP].m_qp + 2;
352      }
353      else
354      {
355        Double costPredMAD   = m_cMADLinearModel.getMAD();
356        Int    qpLowerBound = m_pcFrameData[m_indexPrevPOCInGOP].m_qp-2;
357        Int    qpUpperBound = m_pcFrameData[m_indexPrevPOCInGOP].m_qp+2;
358        finalQP = m_cPixelURQQuadraticModel.getQP(m_pcFrameData[m_indexPrevPOCInGOP].m_qp, m_targetBits, m_numOfPixels, costPredMAD);
359        finalQP = max(qpLowerBound, min(qpUpperBound, finalQP));
360        m_activeUnitLevelOn    = true;
361        m_remainingBitsInFrame = m_targetBits;
362        m_costAvgbpp           = (m_targetBits/(Double)m_numOfPixels);
363      }
364
365      m_indexRefFrame++;
366    }
367    else
368    {
369      Int bwdQP = m_pcFrameData[m_indexPOCInGOP-1].m_qp;
370      Int fwdQP = m_pcFrameData[m_indexPOCInGOP+1].m_qp;
371       
372      if( (fwdQP+bwdQP) == m_pcFrameData[m_indexPOCInGOP-1].m_qp
373        ||(fwdQP+bwdQP) == m_pcFrameData[m_indexPOCInGOP+1].m_qp)
374      {
375        finalQP = (fwdQP+bwdQP);
376      }
377      else if(bwdQP != fwdQP)
378      {
379        finalQP = ((bwdQP+fwdQP+2)>>1);
380      }
381      else
382      {
383        finalQP = bwdQP+2;
384      }
385      m_indexNonRefFrame++;
386    }
387  }
388  else
389  {
390    Int lastQPminus2 = m_pcFrameData[0].m_qp - 2;
391    Int lastQPplus2  = m_pcFrameData[0].m_qp + 2;
392
393    for(Int idx = 1; idx <= m_sizeGOP; idx++)
394    {
395      if(m_pcFrameData[idx].m_isReferenced)
396      {
397        finalQP += m_pcFrameData[idx].m_qp;
398        numofReferenced++;
399      }
400    }
401   
402    finalQP = (numofReferenced == 0) ? m_pcFrameData[0].m_qp : ((finalQP + (1<<(numofReferenced>>1)))/numofReferenced);
403    finalQP = max( lastQPminus2, min( lastQPplus2, finalQP));
404
405    Double costAvgFrameBits = m_remainingBitsInGOP/(Double)m_sizeGOP;
406    Int    bufLevel  = m_occupancyVB + m_initialOVB;
407
408    if(abs(bufLevel) > costAvgFrameBits)
409    {
410      if(bufLevel < 0)
411      {
412        finalQP -= 2;
413      }
414      else
415      {
416        finalQP += 2;
417      }
418    }
419    m_indexRefFrame++;
420  }
421  finalQP = max(MIN_QP, min(MAX_QP, finalQP));
422
423  for(Int indexLCU = 0 ; indexLCU < m_numUnitInFrame; indexLCU++)
424  {
425    m_pcLCUData[indexLCU].m_qp = finalQP;
426  }
427
428  pcFrameData->m_isReferenced = isReferenced;
429  pcFrameData->m_qp           = finalQP;
430
431  return finalQP;
432}
433
434Bool  TEncRateCtrl::calculateUnitQP ()
435{
436  if(!m_activeUnitLevelOn || m_indexLCU == 0)
437  {
438    return false;
439  }
440  Int upperQPBound, lowerQPBound, finalQP;
441  Int    colQP        = m_pcLCUData[m_indexLCU].m_qp;
442  Double colMAD       = m_pcLCUData[m_indexLCU].m_costMAD;
443  Double budgetInUnit = m_pcLCUData[m_indexLCU].m_pixels*m_costAvgbpp;
444
445
446  Int targetBitsOccupancy = (Int)(budgetInUnit - (m_occupancyVBInFrame/(m_numUnitInFrame-m_indexUnit)));
447  Int targetBitsLeftBudget= (Int)((m_remainingBitsInFrame*m_pcLCUData[m_indexLCU].m_pixels)/(Double)(m_numOfPixels-m_codedPixels));
448  Int targetBits = (targetBitsLeftBudget>>1) + (targetBitsOccupancy>>1);
449 
450
451  if( m_indexLCU >= m_sourceWidthInLCU)
452  {
453    upperQPBound = ( (m_pcLCUData[m_indexLCU-1].m_qp + m_pcLCUData[m_indexLCU - m_sourceWidthInLCU].m_qp)>>1) + MAX_DELTA_QP;
454    lowerQPBound = ( (m_pcLCUData[m_indexLCU-1].m_qp + m_pcLCUData[m_indexLCU - m_sourceWidthInLCU].m_qp)>>1) - MAX_DELTA_QP;
455  }
456  else
457  {
458    upperQPBound = m_pcLCUData[m_indexLCU-1].m_qp + MAX_DELTA_QP;
459    lowerQPBound = m_pcLCUData[m_indexLCU-1].m_qp - MAX_DELTA_QP;
460  }
461
462  if(targetBits < 0)
463  {
464    finalQP = m_pcLCUData[m_indexLCU-1].m_qp + 1;
465  }
466  else
467  {
468    finalQP = m_cPixelURQQuadraticModel.getQP(colQP, targetBits, m_pcLCUData[m_indexLCU].m_pixels, colMAD);
469  }
470 
471  finalQP = max(lowerQPBound, min(upperQPBound, finalQP));
472  m_pcLCUData[m_indexLCU].m_qp = max(MIN_QP, min(MAX_QP, finalQP));
473 
474  return true;
475}
476
477Void  TEncRateCtrl::updateRCGOPStatus()
478{
479  m_remainingBitsInGOP = ((m_currBitrate/m_frameRate)*m_sizeGOP) - m_occupancyVB;
480 
481  FrameData cFrameData = m_pcFrameData[m_sizeGOP];
482  initFrameData();
483
484  m_pcFrameData[0]   = cFrameData;
485  m_indexGOP++;
486  m_indexFrame       = 0;
487  m_indexRefFrame    = 0;
488  m_indexNonRefFrame = 0;
489}
490
491Void  TEncRateCtrl::updataRCFrameStatus(Int frameBits, SliceType eSliceType)
492{
493  FrameData* pcFrameData = &m_pcFrameData[m_indexPOCInGOP];
494  Int occupancyBits;
495  Double adjustmentBits;
496
497  m_remainingBitsInGOP = m_remainingBitsInGOP + ( ((m_currBitrate-m_prevBitrate)/m_frameRate)*(m_sizeGOP-m_indexFrame) ) - frameBits;
498  occupancyBits        = (Int)((Double)frameBits - (m_currBitrate/(Double)m_frameRate));
499 
500  if( (occupancyBits < 0) && (m_initialOVB > 0) )
501  {
502    adjustmentBits = xAdjustmentBits(occupancyBits, m_initialOVB );
503
504    if(m_initialOVB < 0)
505    {
506      adjustmentBits = m_initialOVB;
507      occupancyBits += (Int)adjustmentBits;
508      m_initialOVB   =  0;
509    }
510  }
511  else if( (occupancyBits > 0) && (m_initialOVB < 0) )
512  {
513    adjustmentBits = xAdjustmentBits(m_initialOVB, occupancyBits );
514   
515    if(occupancyBits < 0)
516    {
517      adjustmentBits = occupancyBits;
518      m_initialOVB  += (Int)adjustmentBits;
519      occupancyBits  =  0;
520    }
521  }
522
523  if(m_indexGOP == 0)
524  {
525    m_initialOVB = occupancyBits;
526  }
527  else
528  {
529    m_occupancyVB= m_occupancyVB + occupancyBits;
530  }
531
532  if(pcFrameData->m_isReferenced)
533  {
534    m_costRefAvgWeighting  = ((pcFrameData->m_bits*pcFrameData->m_qp)/8.0) + (7.0*(m_costRefAvgWeighting)/8.0);
535
536    if(m_indexFrame == 0)
537    {
538      m_initialTBL = m_targetBufLevel  = (frameBits - (m_currBitrate/m_frameRate));
539    }
540    else
541    {
542      Int distance = (m_costNonRefAvgWeighting == 0) ? 0 : 1;
543      m_targetBufLevel =  m_targetBufLevel
544                            - (m_initialTBL/(m_refFrameNum-1)) 
545                            + (Int)((m_costRefAvgWeighting*(distance+1)*m_currBitrate)/(m_frameRate*(m_costRefAvgWeighting+(m_costNonRefAvgWeighting*distance)))) 
546                            - (m_currBitrate/m_frameRate);
547    }
548
549    if(m_cMADLinearModel.IsUpdateAvailable())
550    {
551      m_cMADLinearModel.updateMADLiearModel();
552    }
553
554    if(eSliceType != I_SLICE &&
555       m_cPixelURQQuadraticModel.checkUpdateAvailable(pcFrameData->m_qp))
556    {
557      m_cPixelURQQuadraticModel.updatePixelBasedURQQuadraticModel(pcFrameData->m_qp, pcFrameData->m_bits, m_numOfPixels, pcFrameData->m_costMAD);
558    }
559  }
560  else
561  {
562    m_costNonRefAvgWeighting = ((pcFrameData->m_bits*pcFrameData->m_qp)/8.0) + (7.0*(m_costNonRefAvgWeighting)/8.0);
563  }
564
565  m_indexFrame++;
566  m_indexLCU             = 0;
567  m_indexUnit            = 0;
568  m_occupancyVBInFrame   = 0;
569  m_remainingBitsInFrame = 0;
570  m_codedPixels          = 0;
571  m_activeUnitLevelOn    = false;
572  m_costAvgbpp           = 0.0;
573}
574Void  TEncRateCtrl::updataRCUnitStatus ()
575{
576  if(!m_activeUnitLevelOn || m_indexLCU == 0)
577  {
578    return;
579  }
580
581  m_codedPixels  += m_pcLCUData[m_indexLCU-1].m_pixels;
582  m_remainingBitsInFrame = m_remainingBitsInFrame - m_pcLCUData[m_indexLCU-1].m_bits;
583  m_occupancyVBInFrame   = (Int)(m_occupancyVBInFrame + m_pcLCUData[m_indexLCU-1].m_bits - m_pcLCUData[m_indexLCU-1].m_pixels*m_costAvgbpp);
584
585  if( m_cPixelURQQuadraticModel.checkUpdateAvailable(m_pcLCUData[m_indexLCU-1].m_qp) )
586  {
587    m_cPixelURQQuadraticModel.updatePixelBasedURQQuadraticModel(m_pcLCUData[m_indexLCU-1].m_qp, m_pcLCUData[m_indexLCU-1].m_bits, m_pcLCUData[m_indexLCU-1].m_pixels, m_pcLCUData[m_indexLCU-1].m_costMAD);
588  }
589
590  m_indexUnit++;
591}
592
593Void  TEncRateCtrl::updateFrameData(UInt64 actualFrameBits)
594{
595  Double costMAD = 0.0;
596 
597  for(Int i = 0; i < m_numUnitInFrame; i++)
598  {
599    costMAD    += m_pcLCUData[i].m_costMAD;
600  }
601 
602  m_pcFrameData[m_indexPOCInGOP].m_costMAD = (costMAD/(Double)m_numUnitInFrame);
603  m_pcFrameData[m_indexPOCInGOP].m_bits    = (Int)actualFrameBits;
604 
605  if(m_pcFrameData[m_indexPOCInGOP].m_isReferenced)
606  {
607    m_indexPrevPOCInGOP = m_indexPOCInGOP;
608    m_cMADLinearModel.updateMADHistory(m_pcFrameData[m_indexPOCInGOP].m_costMAD);
609  }
610}
611
612Void  TEncRateCtrl::updateLCUData(TComDataCU* pcCU, UInt64 actualLCUBits, Int qp)
613{
614  Int     x, y;
615  double  costMAD = 0.0;
616
617  Pel*  pOrg   = pcCU->getPic()->getPicYuvOrg()->getLumaAddr(pcCU->getAddr(), 0);
618  Pel*  pRec   = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), 0);
619  Int   stride = pcCU->getPic()->getStride();
620
621  Int   width  = m_pcLCUData[m_indexLCU].m_widthInPixel;
622  Int   height = m_pcLCUData[m_indexLCU].m_heightInPixel;
623
624  for( y = 0; y < height; y++ )
625  {
626    for( x = 0; x < width; x++ )
627    {
628      costMAD += abs( pOrg[x] - pRec[x] );
629    }
630    pOrg += stride;
631    pRec += stride;
632  }
633  m_pcLCUData[m_indexLCU  ].m_qp      = qp;
634  m_pcLCUData[m_indexLCU  ].m_costMAD = (costMAD /(Double)(width*height));
635  m_pcLCUData[m_indexLCU++].m_bits    = (Int)actualLCUBits;
636}
637
638Double TEncRateCtrl::xAdjustmentBits(Int& reductionBits, Int& compensationBits)
639{
640  Double adjustment  = ADJUSTMENT_FACTOR*reductionBits;
641  reductionBits     -= (Int)adjustment;
642  compensationBits  += (Int)adjustment;
643
644  return adjustment;
645}
646
Note: See TracBrowser for help on using the repository browser.