在前一篇文章的基础上继续往下讲。
基本单元层码率控制
如果不是选择一帧作为一个基本单元,还得添加上额外的基本单元层码率控制。同帧层码率控制一样,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)