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);
}