www.pudn.com > wm2.5.zip > ratectl.c


 /* 
*********************************************************************** 
* 
************************************************************************ 
*/ 
 
/*! 
 *************************************************************************** 
 * \file ratectl.c 
 * 
 * \brief 
 *    Rate Control algorithm 
 * 
 * \major contributors:  Li Xiao  hawkhoodli@tom.com 
                                  zhanuo@yahoo.com 
 * 
 * \date 
 *   17 Sep. 2004 
 ************************************************************************** 
 */ 
#include  
#include  
#include "global.h" 
#include "ratectl.h"       // LX 0409  
 
 
const double THETA=1.3636; 
const int Switch=0; 
 
int Iprev_bits=0; 
int Pprev_bits=0; 
 
 
/* rate control variables */ 
int Xp, Xb; 
static int R,T_field; // R: GOP 可使用的比特数 
static int Np, Nb, bits_topfield, Q; // Np: GOP 中剩余的 P 帧数, 
                                     // Nb: GOP 中剩余的 B 帧数, 
long T,T1; // T 当前帧剩余的可分配的比特数 
 
double Wp,Wb; // Wp: P 帧复杂度 
int TotalPFrame; 
int DuantQp;  
int PDuantQp; // 相邻 QP 的最大差值, 设为常数 
FILE *BitRate; 
double DeltaP; // 相邻 P 帧目标缓冲区占用率的递减值 
 
/////////////////////////////////////////////////////////////////////////////// 
// Initiate rate control parameters 
// 初始化速率控制参数 
/////////////////////////////////////////////////////////////////////////////// 
void rc_init_seq() 
{ 
   double L1,L2,L3,bpp; 
   int qp; 
   int i; 
   
   Xp=0; 
   Xb=0; 
    
   bit_rate=input.bit_rate; 
 
   frame_rate = (float)(pgImage->framerate) / (float) (input.jumpd + 1); 
   PreviousBit_Rate=bit_rate; 
    
   /*compute the total number of MBs in a frame*/ 
   pgImage->Frame_Total_Number_MB=pgImage->img_height*pgImage->img_width/256; 
    
   MINVALUE = 4.0; 
   // initialize the parameters of fluid flow traffic model 
    
   BufferSize = bit_rate*2.56; 
   CurrentBufferFullness = 0; 
   // 记录缓冲区占用率 
   g_lfBuffleFullness[g_unFrameEncoded] = CurrentBufferFullness; 
   GOPTargetBufferLevel = CurrentBufferFullness; 
    
   // initialize the previous window size 
   m_windowSize = 0; 
   // MADm_windowSize=0; 
   pgImage->NumberofCodedBFrame = 0; 
   pgImage->NumberofCodedPFrame = 0; 
   pgImage->NumberofGOP = 0; 
   /*remaining # of bits in GOP */ 
   R = 0; 
   /*control parameter */ 
     GAMMAP=0.5; 
     BETAP=0.5; 
    
   /*quadratic rate-distortion model*/ 
   PPreHeader = 0; 
    
   Pm_X1 = bit_rate*1.0; 
   Pm_X2 = 0.0; 
   // linear prediction model for P picture 
   // my rate control 
   PLValidbitsPicC1 = 0.0; 
   PLValidbitsPicC2 = 0.0; 
    
   for(i=0;i<20;i++) 
   { 
     Pm_rgQp[i]=0; 
     Pm_rgRp[i]=0.0; 
     PPicLValidbits[i] = 0.0; 
   } 
   PPicLValidbits[20] = 0.0; 
    
   //Define the largest variation of quantization parameters 
   PDuantQp = 2; 
    
   /*basic unit layer rate control*/ 
    PAveHeaderBits1=0; 
    PAveHeaderBits3=0;   
    if(TotalNumberofBasicUnit >= 9 ) 
      DDquant=1; 
    else 
      DDquant=2; 
     
    MBPerRow=input.img_width/16; 
     
    /*adaptive field/frame coding*/ 
    pgImage->FieldControl=0; 
     
    RC_MAX_QUANT = 63;  // clipping 
    RC_MIN_QUANT = 0; // clipping 
     
    /*compute thei initial QP*/ 
    bpp = 1.0*bit_rate /(frame_rate*pgImage->img_height*pgImage->img_width); 
    if (pgImage->img_width == 176)  
    { 
      L1 = 0.1;            //frame_rate = 15 ;  bit_rate = 38016 
      L2 = 0.3;            //frame_rate = 15 ;  bit_rate = 114048 
      L3 = 0.6;            //frame_rate = 15 ;  bit_rate = 228096 
    }else if (pgImage->img_width == 352) 
    { 
      L1 = 0.2; 
      L2 = 0.6; 
      L3 = 1.2; 
    }else  
    { 
      L1 = 0.6; 
      L2 = 1.4; 
      L3 = 2.4; 
    } 
     
    if (input.SeinitialQP==0) 
    { 
      if(bpp<= L1) 
        qp = 40 ;  
	  else 
        if(bpp<=L2) 
          qp = 35 ;  
        else 
          if(bpp<=L3) 
            qp  = 30 ;  
          else 
            qp = 25 ;  
          input.SeinitialQP = qp; 
    } 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// Initiate one GOP 
/////////////////////////////////////////////////////////////////////////////// 
void rc_init_GOP(int np, int nb) 
{ 
	int AllocatedBits;  
	int GOPDquant; 
	 
	// 计算当前 GOP 分配的比特数 
	// compute the total number of bits for the current GOP 
	AllocatedBits = (int) floor((1 + np + nb) * bit_rate / frame_rate + 0.5); 
	R += AllocatedBits; 
	Np = np; 
	Nb = nb; 
	 
	GOPOverdue = 0; 
	 
	/*field coding*/ 
	pgImage->IFLAG = 1; 
	 
	// Compute InitialQp for each GOP 
	TotalPFrame = np; 
	pgImage->NumberofGOP++; 
	if(pgImage->NumberofGOP == 1) // 第一个 GOP, 初始 QP 由配置文件设定 
	{ 
		MyInitialQp = input.SeinitialQP; 
		PreviousQp2 = MyInitialQp - 1; //recent change -0; 
		QPLastGOP = MyInitialQp;		 
	} 
	else 
	{		 
		/////////////////////////////////////// 
		// 计算 GOP 初始 QP 
		// 计算前一个 GOP 中 P 帧的平均 QP 
		PAverageQp = (int)(1.0 * pgImage->TotalQpforPPicture / pgImage->NumberofPPicture+0.5); 
		 
		// GOP 长度每增加 15, 初始量化系数减小 1, 最多减 2 
		GOPDquant=(int)(0.5+1.0*(np+nb+1)/15); 
		if(GOPDquant>2) 
			GOPDquant = 2; 
		PAverageQp -= GOPDquant; 
		 
		if (PAverageQp > (QPLastPFrame - 2)) 
			PAverageQp--; 
		PAverageQp = MAX(QPLastGOP-2,  PAverageQp); 
		PAverageQp = MIN(QPLastGOP+2, PAverageQp); 
		PAverageQp = MIN(RC_MAX_QUANT, PAverageQp); 
		PAverageQp = MAX(RC_MIN_QUANT, PAverageQp);   
		 
		MyInitialQp = PAverageQp; 
		QPLastGOP = MyInitialQp; 
		Pm_Qp = PAverageQp; 
		PAveFrameQP = PAverageQp; 
		PreviousQp1 = PreviousQp2; 
		PreviousQp2 = MyInitialQp - 1; 
		// 计算 GOP 初始 QP 
		/////////////////////////////////////// 
		 
	} 
	 
	pgImage->TotalQpforPPicture = 0; 
	pgImage->NumberofPPicture = 0; 
	NumberofBFrames = 0;  
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// rc_init_pict 
// 计算当前图像的目标比特率 
// fieldpic: 1 frame 0 field 
// topfield: 1 topfield 0 bottomfield 
/////////////////////////////////////////////////////////////////////////////// 
void rc_init_pict(int fieldpic,int topfield,int targetcomputation) 
{ 
	if( input.channel_type == 1 ) // VBR, 自定义码率变化 
	{ 
		if(pgImage->NumberofCodedPFrame == 58) 
			bit_rate *= 1.5; 
		else if(pgImage->NumberofCodedPFrame == 59) 
			PreviousBit_Rate = bit_rate; 
	} 
	/////////////////////////////////////// 
	// fieldpic: 1 frame 0 field 
	// topfield: 1 topfield 0 bottomfield 
	// predefine a target buffer level for each frame 
	if((fieldpic||topfield)&&targetcomputation) 
	{ 
/////////////////////////////////////// 
//(1)   计算当前帧的目标缓冲区占用率 
		if(pgImage->type == INTER_IMG) 
		{ 
			// VBR: 更新当前 GOP 的可用比特数 
			// Since the available bandwidth may vary at any time, the total 
			// number of bits is updated picture by picture 
			if( PreviousBit_Rate != bit_rate ) 
				R += (int) floor((bit_rate-PreviousBit_Rate)*(Np+Nb)/frame_rate+0.5); 
			 
/////////////////////////////////////// 
// 计算目标缓冲区占用率 
			// Predefine the target buffer level for each picture 
			// frame layer rate control 
				if( pgImage->NumberofPPicture == 1 ) // 对第二个 P 帧编码 
				{ 
					TargetBufferLevel = CurrentBufferFullness; 
					DeltaP = (CurrentBufferFullness-GOPTargetBufferLevel)/(TotalPFrame-1); 
					TargetBufferLevel -= DeltaP; 
				} 
				else if( pgImage->NumberofPPicture >1 ) 
					TargetBufferLevel -= DeltaP; 
// 计算目标缓冲区占用率 
///////////////////////////////////////			 
			 
// 计算 P 帧复杂度 
			if(pgImage->NumberofCodedPFrame==1) 
				AWp=Wp; 
			if((pgImage->NumberofCodedPFrame<8)&&(pgImage->NumberofCodedPFrame>1)) 
				AWp=Wp*(pgImage->NumberofCodedPFrame-1)/pgImage->NumberofCodedPFrame + AWp/pgImage->NumberofCodedPFrame; 
			else if(pgImage->NumberofCodedPFrame>8) 
				AWp=Wp/8+7*AWp/8; 
		}  
// 计算当前帧的目标缓冲区占用率 
/////////////////////////////////////// 
//(2) 
	// 计算当前帧的目标比特率 
	// Compute the target bit for each frame 
	// frame layer rate control 
		if(pgImage->NumberofCodedPFrame>0) 
		{ 
			T = (long) floor(Wp*R/(Np*Wp+Nb*Wb) + 0.5); 
			T1 = (long) floor(bit_rate/frame_rate-GAMMAP*(CurrentBufferFullness-TargetBufferLevel) +0.5); 
			T1 = MAX(0,T1); 
			T = (long)(floor(BETAP*T+(1.0-BETAP)*T1+0.5)); 
		} 
  } 
 
  // 记录分配给当前帧的比特率 
  g_nAllocatedBits[g_unFrameEncoded] = T; 
    
  // frame layer rate control 
  pgImage->NumberofHeaderBits = 0; 
  pgImage->NumberofTextureBits = 0; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// update one picture after frame/field encoding 
/////////////////////////////////////////////////////////////////////////////// 
void rc_update_pict(int nbits) 
{ 
  R -= nbits; // remaining # of bits in GOP 
  // 更新缓冲区占用率 
  CurrentBufferFullness += nbits - bit_rate/frame_rate; 
 
  // 记录缓冲区占用率   
  g_lfBuffleFullness[g_unFrameEncoded] = CurrentBufferFullness;   
  return; 
} 
 
// update after frame encoding 
void rc_update_pict_frame(int nbits) 
{ 
 
/*update the complexity weight of I, P, B frame*/ 
  int X; 
     
/*frame layer rate control*/ 
    X = (int) floor(nbits*m_Qc+ 0.5); 
 
  if(pgImage->type == INTER_IMG) 
  { 
 /*filed coding*/ 
      if(((pgImage->IFLAG==0)&&(pgImage->FieldControl==1))||(pgImage->FieldControl==0)) 
      { 
        Xp = X; 
        Np--; 
        Wp=Xp; 
        Pm_Hp = pgImage->NumberofHeaderBits; 
        pgImage->NumberofCodedPFrame++; 
        pgImage->NumberofPPicture++; 
      } 
      else if((pgImage->IFLAG!=0)&&(pgImage->FieldControl==1)) 
        pgImage->IFLAG=0; 
    } 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// compute a  quantization parameter for each frame 
// 计算一个 Macroblock 的量化系数 
/////////////////////////////////////////////////////////////////////////////// 
int updateQuantizationParameter(int topfield) 
{ 
	double dtmp; 
	int m_Bits; // Macroblock 纹理编码使用的比特数 
	 
	/////////////////////////////////////// 
	// frame layer rate control 
	// fixed quantization parameter is used to coded I frame, the first 
	// P frame and the first B frame. The quantization parameter is adjusted 
	// according the available channel bandwidth and the type of video. 
		if((topfield)||(pgImage->FieldControl==0)) // 帧编码或者是 topfield 
		{ 
			// GOP 第一个 I 帧 和 P 帧用上一个 P 帧的 QP 
			if(pgImage->type == INTRA_IMG) // I 帧固定 QP 为 GOP 的初始 QPst 
			{ 
				m_Qc = MyInitialQp; 
				return m_Qc; 
			} 
///////////////////////////////////////////////////////////////////////////////////////////////////////// 
// 设定 GOP 中第一个 P 帧 的初始 QP 
			else if((pgImage->type == INTER_IMG)&&(pgImage->NumberofPPicture == 0))  
			{ 
				// QP 为I帧 的初始 QP+2 
				m_Qc = MyInitialQp + 2; 
				if(pgImage->FieldControl == 0) // 帧编码 
				{ 
					pgImage->TotalQpforPPicture += m_Qc; 
					PreviousQp1 = PreviousQp2; 
					PreviousQp2 = m_Qc; 
					Pm_Qp = m_Qc; 
				} 
				 
				return m_Qc;   
			} // end of else if((img->type == INTER_IMG)&&(img->NumberofPPicture == 0)) // GOP 中第一个 P 帧 
			else // GOP 中的其他 P 帧 
			{ 
				// my rate control 
				m_X1 = Pm_X1; 
				m_X2 = Pm_X2; 
				m_Hp = PPreHeader; 
				m_Qp = Pm_Qp; 
				DuantQp = PDuantQp; 
				LValidbitsPicC1 = PLValidbitsPicC1; 
				LValidbitsPicC2 = PLValidbitsPicC2; 
				PreviousPicLValidbits = PPicLValidbits[0]; 
				 
				// my rate control 
				// predict the 有效比特数 of current picture 
				PredictedFrameLValidbits = LValidbitsPicC1*PreviousPicLValidbits + LValidbitsPicC2; 
				 
				/////////////////////////////////////// 
				// 由 RD 模型计算量化系数 
				// compute the number of bits for the texture 
				if( T < 0 ) // 无剩余比特, 用一帧 ( QP + 常数 ) 
				{ 
					m_Qc = m_Qp + DuantQp; 
					m_Qc = MIN(m_Qc, RC_MAX_QUANT); // clipping 
				} 
				else 
				{ 
					m_Bits = T - m_Hp; 
					m_Bits = MAX(m_Bits, (int)(bit_rate/(MINVALUE*frame_rate))); 
					dtmp = PredictedFrameLValidbits * m_X1 * PredictedFrameLValidbits * m_X1 \ 
						+ 4 * m_X2 * PredictedFrameLValidbits * m_Bits; 
					if ((m_X2 == 0.0) || (dtmp < 0) || ((sqrt (dtmp) - m_X1 * PredictedFrameLValidbits) <= 0.0)) // fall back 1st order mode 
						m_Qstep = (float) (m_X1 * PredictedFrameLValidbits / (double) m_Bits); 
					else // 2nd order mode 
						m_Qstep = (float) ((2 * m_X2 * PredictedFrameLValidbits) / (sqrt (dtmp) - m_X1 * PredictedFrameLValidbits)); 
					 
										 
					// my rate control 
					m_Qc = Qstep2QP(m_Qstep); 
					 
					m_Qc = MIN(m_Qp+DuantQp, m_Qc); // control variation 
					m_Qc = MIN(m_Qc, RC_MAX_QUANT); // clipping 
					m_Qc = MAX(m_Qp-DuantQp, m_Qc); // control variation 
					m_Qc = MAX(RC_MIN_QUANT, m_Qc); 
				} 
				// 由 RD 模型计算量化系数 
				///////////////////////////////////////				 
				 
				if(pgImage->FieldControl == 0) // 帧编码 
				{ 
					pgImage->TotalQpforPPicture += m_Qc; 
					PreviousQp1 = PreviousQp2; 
					PreviousQp2 = m_Qc; 
					Pm_Qp = m_Qc;			 
				} 
				 
				return m_Qc; 
			} 
   } 
   // pass 
   else // bottom field 
   { 
	   if((pgImage->type==INTER_IMG)&&(pgImage->IFLAG==0)) 
		   FieldQPBuffer=m_Qc;      
	   return m_Qc; 
   } // pass 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// update the parameters of quadratic R-D model 
// 更新 RD 模型 
/////////////////////////////////////////////////////////////////////////////// 
void updateRCModel () 
{ 
  int n_windowSize; 
  int i; 
  double error[MaxWindowSize], std = 0.0, threshold; 
  int m_Nc; // 已编码的P帧的数目 
  int MADModelFlag = 0; 
    
  if(pgImage->type==INTER_IMG) 
  { 
    /*frame layer rate control*/ 
      m_Nc = pgImage->NumberofCodedPFrame; 
    // my rate control  
// 从第二个P帧开始 
    if( m_Nc > 1 ) 
		MADModelFlag=1; 
// 从第二个P帧开始	 
 
    PPreHeader = pgImage->NumberofHeaderBits; 
 
    /////////////////////////////////////// 
	// 更新参考数据缓冲区 
	for (i = MaxWindowSize-1; i > 0; i--)  
	{ 
		// update the history 
		Pm_rgQp[i] = Pm_rgQp[i - 1]; 
		m_rgQp[i] = Pm_rgQp[i]; 
        Pm_rgRp[i] = Pm_rgRp[i - 1]; 
		m_rgRp[i] = Pm_rgRp[i]; 
    } 
	// 保存当前 Macroblock 的 QPstep 
    Pm_rgQp[0] = QP2Qstep(m_Qc);  
	// 保存当前 Macroblock 的 (R-H)/(ValidBits) 
    // frame layer rate control 
///////////////////////////////////////////////////////////////////////////////////// 
		Pm_rgRp[0] = FrameActualBit * 1.0 / CurrentFrameLValidbits; 
////////////////////////////////////////////////////////////////////////////////////// 
 
    // my rate control 
	// basic unit layer rate control 
    m_rgQp[0] = Pm_rgQp[0]; 
     m_rgRp[0] = Pm_rgRp[0]; 
	// 更新参考数据缓冲区 
    ///////////////////////////////////////	 
     
	m_X1 = Pm_X1; 
	m_X2 = Pm_X2;   
 
    /////////////////////////////////////// 
	// compute the size of window 
 
    // my rate control 
	n_windowSize = (CurrentFrameLValidbits>PreviousFrameLValidbits)?(int)(PreviousFrameLValidbits/CurrentFrameLValidbits*20)\ 
      :(int)(CurrentFrameLValidbits/PreviousFrameLValidbits*20);     
    n_windowSize = MAX(n_windowSize, 1); 
    n_windowSize = MIN(n_windowSize, m_Nc); 
    n_windowSize = MIN(n_windowSize, m_windowSize + 1); 
    n_windowSize = MIN(n_windowSize, MaxWindowSize); 
    m_windowSize=n_windowSize; 
	 
	// compute the size of window 
	///////////////////////////////////////	 
 
 
	/////////////////////////////////////// 
	// 更新 RD 模型 
 
	// initial RD model estimator 
	for (i = 0; i < MaxWindowSize; i++) 
	{ 
		m_rgRejected[i] = 0; 
	} 
	RCModelEstimator (n_windowSize); 
	 
	n_windowSize = m_windowSize; 
 
	for (i = 0; i < (int) n_windowSize; i++) 
	{ 
		error[i] = m_X1 / m_rgQp[i] + m_X2 / (m_rgQp[i] * m_rgQp[i]) - m_rgRp[i]; 
		std += error[i] * error[i];  
	} 
	threshold = (n_windowSize == 2) ? 0 : sqrt (std / n_windowSize); 
	for (i = 0; i < (int) n_windowSize; i++) 
	{ 
		if (fabs(error[i]) > threshold) 
			m_rgRejected[i] = 1; 
	} 
 
    // always include the last data point 
	m_rgRejected[0] = 0; 
	 
	// second RD model estimator 
	RCModelEstimator (n_windowSize); 
 
	// 更新 RD 模型 
	/////////////////////////////////////// 
	 
	if(MADModelFlag) 
		updateValidbitsModel(); 
	else if(pgImage->type == INTER_IMG) 
		PPicLValidbits[0] = CurrentFrameLValidbits;	 
	}  
} 
 
 
/////////////////////////////////////////////////////////////////////////////// 
// RCModelEstimator 
// Update the parameter of the RD model using Sliding Window 
/////////////////////////////////////////////////////////////////////////////// 
void RCModelEstimator (int n_windowSize) 
{ 
  int n_realSize = n_windowSize; 
  int i; 
  double oneSampleQ; 
  double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0, b0 = 0.0, b1 = 0.0; 
  double MatrixValue; 
  int    estimateX2 = 0; 
 
  for (i = 0; i < n_windowSize; i++) {// find the number of samples which are not rejected 
    if (m_rgRejected[i]) 
      n_realSize--; 
  } 
  // default RD model estimation results 
 
  m_X1 = m_X2 = 0.0; 
 
  for (i = 0; i < n_windowSize; i++)  { 
    if (!m_rgRejected[i]) 
      oneSampleQ = m_rgQp[i]; 
  } 
  for (i = 0; i < n_windowSize; i++)  {// if all non-rejected Q are the same, take 1st order model 
    if ((m_rgQp[i] != oneSampleQ) && !m_rgRejected[i]) 
      estimateX2 = 1; 
    if (!m_rgRejected[i]) 
      m_X1 += (m_rgQp[i] * m_rgRp[i]) / n_realSize; 
  } 
  // take 2nd order model to estimate X1 and X2 
  if ((n_realSize >= 1) && estimateX2) { 
      for (i = 0; i < n_windowSize; i++) { 
      if (!m_rgRejected[i]) { 
        a00 = a00 + 1.0; 
        a01 += 1.0 / m_rgQp[i]; 
        a10 = a01; 
        a11 += 1.0 / (m_rgQp[i] * m_rgQp[i]); 
        b0 += m_rgQp[i] * m_rgRp[i]; 
        b1 += m_rgRp[i]; 
      } 
    } 
    // solve the equation of AX = B 
      MatrixValue=a00*a11-a01*a10; 
      if(fabs(MatrixValue)>0.000001) 
      { 
        m_X1=(b0*a11-b1*a01)/MatrixValue; 
        m_X2=(b1*a00-b0*a10)/MatrixValue; 
      } 
      else 
      { 
        m_X1=b0/a00; 
        m_X2=0.0; 
      } 
   
  } 
  if(pgImage->type==INTER_IMG) 
  { 
    Pm_X1=m_X1; 
    Pm_X2=m_X2; 
  } 
} 
/////////////////////////////////////////////////////////////////////////////// 
// Update the parameters of linear prediction model 
// 更新有效比特数预测模型 
/////////////////////////////////////////////////////////////////////////////// 
void updateValidbitsModel() 
{ 
   
  int n_windowSize; 
  int i; 
  double error[MaxWindowSize], std = 0.0, threshold; 
  int m_Nc; // 已经编码的 Basic Unit 的数目 
   
  if( pgImage->NumberofCodedPFrame > 0 ) 
  { 
     
    if(pgImage->type==INTER_IMG) 
    { 
      // frame layer rate control 
      m_Nc = pgImage->NumberofCodedPFrame; 
 
      for (i = MaxWindowSize-1; i > 0; i--) // update the history 
	  { 
        PPicLValidbits[i] = PPicLValidbits[i-1]; 
        PicLValidbits[i] = PPicLValidbits[i]; 
        RefLValidbits[i] = RefLValidbits[i-1]; 
      } 
	  // 加入新数据 
	  PPicLValidbits[0] = CurrentFrameLValidbits; 
      PicLValidbits[0] = PPicLValidbits[0]; 
	   
      RefLValidbits[0] = PicLValidbits[1]; 
	  // my rate control 
	   
      LValidbitsPicC1 = PLValidbitsPicC1; 
      LValidbitsPicC2 = PLValidbitsPicC2; 
    } 
     
     
    // compute the size of window* 
     
    n_windowSize = (CurrentFrameLValidbits>PreviousFrameLValidbits)?(int)(PreviousFrameLValidbits/CurrentFrameLValidbits*20)\ 
      :(int)(CurrentFrameLValidbits/PreviousFrameLValidbits*20); 
    n_windowSize = MIN(n_windowSize, (m_Nc-1)); // 预测窗大小的不能超过已编码 BasicUint 的数目 
    n_windowSize = MAX(n_windowSize, 1); // 预测窗大小的不能低于 1  
    n_windowSize = MIN(n_windowSize, Validbitsm_windowSize+1); // 每次预测窗大小的增加不能超过 1 
    n_windowSize = MIN(n_windowSize, MaxWindowSize );  
	// update the previous window size 
    Validbitsm_windowSize = n_windowSize; 
     
    for( i = 0; i < MaxWindowSize; i++ ) 
	{ 
      PicLValidbitsRejected[i] = 0; 
    } 
    if( pgImage->type == INTER_IMG ) 
      PreviousFrameLValidbits = CurrentFrameLValidbits; 
     
    // initial MAD model estimator 
    ValidbitsModelEstimator (n_windowSize); 
     
    // remove outlier      
    for (i = 0; i < (int) n_windowSize; i++) { 
      error[i] = LValidbitsPicC1*RefLValidbits[i]+LValidbitsPicC2 - PicLValidbits[i]; 
      std += error[i] * error[i];  
    } 
    threshold = (n_windowSize == 2) ? 0 : sqrt (std / n_windowSize); 
    for (i = 0; i < (int) n_windowSize; i++) { 
      if (fabs(error[i]) > threshold) 
        PicLValidbitsRejected[i] = 1; 
    } 
    // always include the last data point 
    PicLValidbitsRejected[0] = 0;     
    // second MAD model estimator 
    ValidbitsModelEstimator (n_windowSize); 
  } 
} 
 
void ValidbitsModelEstimator (int n_windowSize) 
{ 
  int n_realSize = n_windowSize; 
  int i; 
  double oneSampleQ; 
  double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0, b0 = 0.0, b1 = 0.0; 
  double MatrixValue; 
  int    estimateX2 = 0; 
   
  for( i = 0; i < n_windowSize; i++ )// find the number of samples which are not rejected 
  { 
    if( PicLValidbitsRejected[i] ) 
      n_realSize--; 
  } 
   
  LValidbitsPicC1 = 0.0; 
  LValidbitsPicC2 = 0.0; 
   
  for( i = 0; i < n_windowSize; i++ ) 
  { 
    if( !PicLValidbitsRejected[i] ) 
      oneSampleQ = PicLValidbits[i]; 
  } 
  for( i = 0; i < n_windowSize; i++ ) // if all non-rejected Validbits are the same, take 1st order model 
  { 
    if ( (PicLValidbits[i] != oneSampleQ) && !PicLValidbitsRejected[i] ) 
      estimateX2 = 1; 
 
    if ( !PicLValidbitsRejected[i] ) 
      LValidbitsPicC1 += PicLValidbits[i] / (RefLValidbits[i]*n_realSize); 
  }   
 
  if ((n_realSize >= 1) && estimateX2) { 
    for (i = 0; i < n_windowSize; i++) { 
      if (!PicLValidbitsRejected[i]) { 
        a00 = a00 + 1.0; 
        a01 += RefLValidbits[i];// (x) 
        a10 = a01;//(x) 
        a11 += RefLValidbits[i]*RefLValidbits[i];//(x2) 
        b0 += PicLValidbits[i];//(y) 
        b1 += PicLValidbits[i]*RefLValidbits[i];//(xy) 
      } 
    } 
 
    MatrixValue = a00*a11 - a01*a10; 
    if(fabs(MatrixValue)>0.000001) 
    { 
      LValidbitsPicC2 = (b0*a11-b1*a01)/MatrixValue; 
      LValidbitsPicC1 = (b1*a00-b0*a10)/MatrixValue; 
    } 
    else 
    { 
      LValidbitsPicC1 = b0/a01; 
      LValidbitsPicC2 = 0.0; 
    } 
     
  } 
  if( pgImage->type == INTER_IMG ) 
  { 
    PLValidbitsPicC1 = LValidbitsPicC1; 
    PLValidbitsPicC2 = LValidbitsPicC2; 
  } 
} 
 
 
/////////////////////////////////////////////////////////////////////////////// 
// 由量化系数 QP 计算实际的量化步长 Qstep 
/////////////////////////////////////////////////////////////////////////////// 
double QP2Qstep( int QP ) 
{ 
  int i;  
  double Qstep; 
  static const double QP2QSTEP[6] = { 0.625, 0.6875, 0.8125, 0.875, 1.0, 1.125 }; 
   
  Qstep = QP2QSTEP[QP % 6]; 
  for( i=0; i<(QP/6); i++) 
    Qstep *= 2; 
   
  return Qstep; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
// 由实际的量化步长 Qstep 计算量化系数 QP 
/////////////////////////////////////////////////////////////////////////////// 
int Qstep2QP( double Qstep ) 
{ 
  int q_per = 0, q_rem = 0; 
   
  //  assert( Qstep >= QP2Qstep(0) && Qstep <= QP2Qstep(51) ); 
  if( Qstep < QP2Qstep(0)) 
    return 0; 
  else if (Qstep > QP2Qstep(51) ) 
    return 51; 
   
  while( Qstep > QP2Qstep(5) ) 
  { 
    Qstep /= 2; 
    q_per += 1; 
  } 
   
  if (Qstep <= (0.625+0.6875)/2)  
  { 
    Qstep = 0.625; 
    q_rem = 0; 
  } 
  else if (Qstep <= (0.6875+0.8125)/2) 
  { 
    Qstep = 0.6875; 
    q_rem = 1; 
  } 
  else if (Qstep <= (0.8125+0.875)/2) 
  { 
    Qstep = 0.8125; 
    q_rem = 2; 
  } 
  else if (Qstep <= (0.875+1.0)/2) 
  { 
    Qstep = 0.875; 
    q_rem = 3; 
  } 
  else if (Qstep <= (1.0+1.125)/2) 
  { 
    Qstep = 1.0;   
    q_rem = 4; 
  } 
  else  
  { 
    Qstep = 1.125; 
    q_rem = 5; 
  } 
   
  return (q_per * 6 + q_rem); 
}