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

原创 2015年07月07日 15:12:09

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

基本单元层码率控制

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

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


版权声明:本文为博主原创文章,未经博主允许不得转载。

H264学习笔记(4):CABAC基于上下文的自适应二进制熵编码

CABAC

视频编解码学习之三:变换,量化与熵编码

第6章 变换编码 1. 变换编码 变换编码的目的 去除空间信号的相关性将空间信号的能力集中到频域的一小部分低频系数上能量小的系数可通过量化去除,而不会严重影响重构图像的质量 ...

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

这是之前我们学校张远老师留的课程作业,要求个人整理分析H.264码率控制算法及JM相应代码,个人感觉自己做的还不错,所以发出来给大家分享一下。鉴于公式什么的太多了,我这里就直接从文档里截图了。 要明白...

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

在前一篇文章的基础上,现在先看一下MPEG4 编码标准中应用的码率控制算法,总结起来,各大算法都是在解决两个问题:RD 率失真的优化以及避免缓冲区的上溢下溢。 MPEG-4 VM8 码率控制算法 在这...

HEVC码率控制算法研究与HM相应代码分析(三)——算法及代码分析

在前两篇文章中,首先介绍了HEVC标准和编码流程,然后介绍了在HEVC中采用的全新的R-λ模型,本文将基于前面的内容和相应代码对码率控制算法进行详细的分析。 下面基于JCTVC-K0103提案详细介...

HEVC码率控制算法研究与HM相应代码分析(二)——新的码率控制模型

下面简单回顾一下H.264中的码率控制算法,并说明为什么不能直接将之前的码率控制算法用于HEVC,同时介绍一下一种很有意思的新的R-λ模型。 在H.264以及之前的码率控制算法中,R-Q模型得到...

H.264的码率控制算法

H.264的码率控制算法采用了多种技术,其中包括自适应基本单元层(Adaptive Basic Unit Layer)、流量往返模型(Fluid Traffic Model)、线性MAD模型、二次率失...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:H.264码率控制算法研究及JM相应代码分析(三)
举报原因:
原因补充:

(最多只允许输入30个字)