在前一篇文章的基础上继续往下讲。
基本单元层码率控制
如果不是选择一帧作为一个基本单元,还得添加上额外的基本单元层码率控制。
同帧层码率控制一样,I帧以单一的QP值编码,且这个QP值和帧层码率控制中的QP值求法一样。B帧也是以单一的QP值编码,以几乎和帧层中一样的方法求出,只是QP1和QP2由相应帧中所有基本单元的QP的平均值替换。
main
encode_sequence
encode_one_frame
perform_encode_frame
rc_init_frame
rc_init_pict
rc_updateQP
I帧
if (p_Vid->type == I_SLICE)
{
p_quad->m_Qc = p_quad->MyInitialQp;
return p_quad->m_Qc;
}
B帧
else if( p_Vid->type == B_SLICE )
{
/*top field of B frame*/
if((topfield)||(p_gen->FieldControl==0))
{
if(p_Inp->NumberBFrames==1)
{
if(p_quad->PrevLastQP==p_quad->CurrLastQP)
p_quad->m_Qc=p_quad->PrevLastQP+2;
else
p_quad->m_Qc = ((p_quad->PrevLastQP+p_quad->CurrLastQP) >> 1) + 1;
p_quad->m_Qc = iClip3(p_Vid->RCMinQP + p_quad->bitdepth_qp_scale, p_Vid->RCMaxQP + p_quad->bitdepth_qp_scale, p_quad->m_Qc); // Clipping
}
else
{
BFrameNumber=(p_quad->NumberofBFrames+1)%p_Inp->NumberBFrames;
if(BFrameNumber==0)
BFrameNumber=p_Inp->NumberBFrames;
if((p_quad->CurrLastQP-p_quad->PrevLastQP)<=(-2*p_Inp->NumberBFrames-3))
StepSize=-3;
else if((p_quad->CurrLastQP-p_quad->PrevLastQP)==(-2*p_Inp->NumberBFrames-2))
StepSize=-2;
else if((p_quad->CurrLastQP-p_quad->PrevLastQP)==(-2*p_Inp->NumberBFrames-1))
StepSize=-1;
else if((p_quad->CurrLastQP-p_quad->PrevLastQP)==(-2*p_Inp->NumberBFrames))
StepSize=0;//0
else if((p_quad->CurrLastQP-p_quad->PrevLastQP)==(-2*p_Inp->NumberBFrames+1))
StepSize=1;//1
else
StepSize=2;//2
p_quad->m_Qc=p_quad->PrevLastQP+StepSize;
p_quad->m_Qc +=
iClip3( -2*(BFrameNumber-1), 2*(BFrameNumber-1), (BFrameNumber-1)*(p_quad->CurrLastQP-p_quad->PrevLastQP)/(p_Inp->NumberBFrames-1) );
p_quad->m_Qc = iClip3(p_Vid->RCMinQP + p_quad->bitdepth_qp_scale, p_Vid->RCMaxQP + p_quad->bitdepth_qp_scale, p_quad->m_Qc); // Clipping
}
return p_quad->m_Qc;
}
/*bottom field of B frame*/
else
{
return p_quad->m_Qc;
}
}
main
encode_sequence
encode_one_frame
rc_update_pict_frame
rc_update_picture
rc_update_pict
updateRCModel
if(p_quad->CodedBasicUnit > 0)
{
p_quad->PAveHeaderBits1=(int)((double)(p_quad->PAveHeaderBits1*(p_quad->CodedBasicUnit-1)+
p_gen->NumberofBasicUnitHeaderBits)/p_quad->CodedBasicUnit+0.5);
if(p_quad->PAveHeaderBits3 == 0)
p_quad->PAveHeaderBits2 = p_quad->PAveHeaderBits1;
else
{
p_quad->PAveHeaderBits2 = (int)((double)(p_quad->PAveHeaderBits1 * p_quad->CodedBasicUnit+
p_quad->PAveHeaderBits3 * p_quad->NumberofBasicUnit)/p_quad->TotalNumberofBasicUnit+0.5);
}
}
main
encode_sequence
encode_one_frame
perform_encode_frame
rc_init_frame
rc_init_pict
updateQP
updateFirstBU
if(p_quad->Target<=0)
{
p_quad->m_Qc = p_quad->PAveFrameQP + 2;
if(p_quad->m_Qc > (p_Vid->RCMaxQP + p_quad->bitdepth_qp_scale))
p_quad->m_Qc = p_Vid->RCMaxQP + p_quad->bitdepth_qp_scale;
if(topfield||(p_gen->FieldControl==0))
p_quad->GOPOverdue=TRUE;
}
else
{
p_quad->m_Qc=p_quad->PAveFrameQP;
}
Main
init_encoder
rc_init_sequence
rc_init_seq
p_quad->DDquant = (p_quad->TotalNumberofBasicUnit>=9 ? 1 : 2);
同时在cfg文件中还可定义
RCMaxQPChange = 4 # maximum QP change for frames of the base layer
对应于代码中的
Main
init_encoder
rc_init_sequence
rc_init_seq
//Define the largest variation of quantization parameters
p_quad->PMaxQpChange = p_Inp->RCMaxQPChange;
main
encode_sequence
encode_one_frame
perform_encode_frame
rc_init_frame
rc_init_pict
updateQP
/*compute the number of remaining bits*/
p_quad->Target -= (p_gen->NumberofBasicUnitHeaderBits + p_gen->NumberofBasicUnitTextureBits);
updateNegativeTarget
if(p_quad->GOPOverdue==TRUE)
p_quad->m_Qc=m_Qp+2;
else
p_quad->m_Qc=m_Qp+p_quad->DDquant;//2
p_quad->m_Qc = imin(p_quad->m_Qc, p_Vid->RCMaxQP + p_quad->bitdepth_qp_scale); // clipping
if(p_Inp->basicunit>=p_quad->MBPerRow)
p_quad->m_Qc = imin(p_quad->m_Qc, p_quad->PAveFrameQP + 6);
else
p_quad->m_Qc = imin(p_quad->m_Qc, p_quad->PAveFrameQP + 3);
main
encode_sequence
encode_one_frame
perform_encode_frame
rc_init_frame
rc_init_pict
updateQP
predictCurrPicMAD
updateModelQPBU
double dtmp, m_Qstep;
int m_Bits;
/*compute the total number of bits for the current basic unit*/
m_Bits =(int)(p_quad->Target * p_quad->CurrentFrameMAD * p_quad->CurrentFrameMAD / p_quad->TotalBUMAD);
/*compute the number of texture bits*/
m_Bits -=p_quad->PAveHeaderBits2;
m_Bits=imax(m_Bits,(int)(p_quad->bit_rate/(MINVALUE*p_quad->frame_rate*p_quad->TotalNumberofBasicUnit)));
dtmp = p_quad->CurrentFrameMAD * p_quad->CurrentFrameMAD * p_quad->m_X1 * p_quad->m_X1 \
+ 4 * p_quad->m_X2 * p_quad->CurrentFrameMAD * m_Bits;
if ((p_quad->m_X2 == 0.0) || (dtmp < 0) || ((sqrt (dtmp) - p_quad->m_X1 * p_quad->CurrentFrameMAD) <= 0.0)) // fall back 1st order mode
m_Qstep = (float)(p_quad->m_X1 * p_quad->CurrentFrameMAD / (double) m_Bits);
else // 2nd order mode
m_Qstep = (float) ((2 * p_quad->m_X2 * p_quad->CurrentFrameMAD) / (sqrt (dtmp) - p_quad->m_X1 * p_quad->CurrentFrameMAD));
p_quad->m_Qc = Qstep2QP(m_Qstep, p_quad->bitdepth_qp_scale);
p_quad->m_Qc = imin(m_Qp+p_quad->DDquant, p_quad->m_Qc); // control variation
if(p_Inp->basicunit>=p_quad->MBPerRow)
p_quad->m_Qc = imin(p_quad->PAveFrameQP+6, p_quad->m_Qc);
else
p_quad->m_Qc = imin(p_quad->PAveFrameQP+3, p_quad->m_Qc);
p_quad->m_Qc = iClip3(m_Qp-p_quad->DDquant, p_Vid->RCMaxQP + p_quad->bitdepth_qp_scale, p_quad->m_Qc); // clipping
if(p_Inp->basicunit>=p_quad->MBPerRow)
p_quad->m_Qc = imax(p_quad->PAveFrameQP-6, p_quad->m_Qc);
else
p_quad->m_Qc = imax(p_quad->PAveFrameQP-3, p_quad->m_Qc);
p_quad->m_Qc = imax(p_Vid->RCMinQP + p_quad->bitdepth_qp_scale, p_quad->m_Qc);
main
encode_sequence
encode_one_frame
rc_update_pict_frame
当然,在一切开始之前要初始化码率控制流程中的两个关键结构体rc_generic和rc_quadratic 调用层级结构如下
Main
init_encoder
init_global_buffers
rc_allocate_memory (rc_quadratic.c)
rc_alloc_generic(ratectl.c)
rc_alloc_quadratic (rc_quadratic.c)
关注下方公众号,回复“264代码分析”,查看本文完整pdf文档下载链接
关注公众号,掌握更多多媒体领域知识与资讯

文章帮到你了?可以扫描如下二维码进行打赏~,打赏多少您随意~

版权声明:本文为nonmarking原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。