关闭

H.264码率控制算法研究及JM相应代码分析(三)

标签: 编码算法代码分析h.264码率控制
1068人阅读 评论(0) 收藏 举报
分类:

在前一篇文章的基础上继续往下讲。

基本单元层码率控制

如果不是选择一帧作为一个基本单元,还得添加上额外的基本单元层码率控制。

同帧层码率控制一样,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)


本文完整pdf地址下载链接http://download.csdn.net/detail/nonmarking/8876649


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:145153次
    • 积分:2056
    • 等级:
    • 排名:第18746名
    • 原创:43篇
    • 转载:10篇
    • 译文:6篇
    • 评论:139条
    联系方式
    email:zhanghuicuc@gmail.com QQ:592271823 欢迎交流讨论
    文章分类
    最新评论