• JM8.6(H.264编码器)源码注释——码率控制部分主要推导


    讲解分为三个部分:MAD线性回归参数估计的计算、RQ模型参数计算、Qstep估计,以下分别从JM8.6的源码注释和公式推导进行讲解。更多关于码率控制的注释在我的Github里面。

    一、矩阵求解MAD线性回归参数的程序注释:

     1 void MADModelEstimator (int n_windowSize)//MAD模型估计
     2 {
     3   int n_realSize = n_windowSize;//暂时存放当前的窗口大小
     4   int i;
     5   double oneSampleQ;
     6   double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0, b0 = 0.0, b1 = 0.0;
     7   double MatrixValue;
     8   Boolean estimateX2 = FALSE;
     9   
    10   for (i = 0; i < n_windowSize; i++) {// find the number of samples which are not rejected
    11     if (PictureRejected[i])//如果某一帧图像被限制了 n_realSize就减一次 最后记录的是没有被限制使用的图像
    12       n_realSize--;
    13   }
    14   
    15   // default MAD model estimation results
    16   
    17   MADPictureC1 = MADPictureC2 = 0.0;//某一帧图像MAD线性预测的参数
    18   
    19   for (i = 0; i < n_windowSize; i++)  {
    20     if (!PictureRejected[i])//如果图像没有被限制
    21     //难道是记录最后一帧没有被限制图像的MAD???
    22       oneSampleQ = PictureMAD[i];//把最后一个没有被限制的图像的MAD赋值给oneSampleQ变量 
    23   }
    24   for (i = 0; i < n_windowSize; i++)  {// if all non-rejected MAD are the same, take 1st order model
    25     if ((PictureMAD[i] != oneSampleQ) && !PictureRejected[i])//图像没有被限制且不是最后一帧被限制的图像
    26       estimateX2 = TRUE;//estimateX2标志位赋值为真
    27     if (!PictureRejected[i])//如果图像没有被限制
    28     //这句话不知道在做怎样的优化??? W值
    29       MADPictureC1 += PictureMAD[i] / (ReferenceMAD[i]*n_realSize);//
    30   }
    31   
    32   // take 2nd order model to estimate X1 and X2
    33   if ((n_realSize >= 1) && estimateX2) {
    34     for (i = 0; i < n_windowSize; i++) {
    35       if (!PictureRejected[i]) {
    36       /*图像没有被限制 好厉害这部分就是在求解参数
    37           平方差求和最小来优化 线性回归
    38           i从0到n的(MADPictureC1*ReferenceMAD[i]+MADPictureC2-PictureMAD[i])^2求和=平方差求和最小优化
    39         相当于我下面公式推导中i从0到n的(W*x[i]+b-y[i])^2求和=平方差求和最小优化
    40 
    41         以下部分是通过矩阵求解两个参数的过程
    42             */
    43         a00 = a00 + 1.0;
    44         a01 += ReferenceMAD[i];
    45         a10 = a01;
    46         a11 += ReferenceMAD[i]*ReferenceMAD[i];
    47         b0 += PictureMAD[i];
    48         b1 += PictureMAD[i]*ReferenceMAD[i];
    49       }
    50     }
    51     // solve the equation of AX = B
    52     MatrixValue=a00*a11-a01*a10;//求矩阵A的行列式
    53     if(fabs(MatrixValue)>0.000001)//行列式不为0 A可逆 有解
    54     {
    55     //通过伴随矩阵求解
    56       MADPictureC2=(b0*a11-b1*a01)/MatrixValue;//b
    57       MADPictureC1=(b1*a00-b0*a10)/MatrixValue;//W
    58     }
    59     else//行列式为0 A不可逆
    60     {
    61         //只是一个特解
    62       MADPictureC2=0.0;//b
    63       MADPictureC1=b0/a01;//W
    64     }
    65     
    66   }
    67   if(img->type==P_SLICE)//如果是P帧 把上面刚刚计算的结果覆盖掉前面计算的 
    68   {
    69     PMADPictureC1=MADPictureC1;
    70     PMADPictureC2=MADPictureC2;
    71   }
    72 }

    以下是矩阵求解MAD线性回归参数的推导过程:

    二、 码率控制模型的线性回归参数估计程序注释:

     1 //码率控制模型的核心
     2 void RCModelEstimator (int n_windowSize)
     3 {
     4   int n_realSize = n_windowSize;
     5   int i;
     6   double oneSampleQ;
     7   double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0, b0 = 0.0, b1 = 0.0;
     8   double MatrixValue;
     9   Boolean estimateX2 = FALSE;
    10 
    11   for (i = 0; i < n_windowSize; i++) {// find the number of samples which are not rejected
    12     if (m_rgRejected[i])//如果存在某一帧图像数据被拒绝
    13       n_realSize--;//求和遍历的n减少 即被限制的数据不参加优化过程
    14   }
    15 
    16   // default RD model estimation results
    17 
    18   m_X1 = m_X2 = 0.0;//码率控制模型参数先清零
    19 
    20   for (i = 0; i < n_windowSize; i++)  {
    21     if (!m_rgRejected[i])//
    22       oneSampleQ = m_rgQp[i];//m_rgQp[i]里面是Qstep值 记录最后一个没有被限制的数据
    23   }
    24   for (i = 0; i < n_windowSize; i++)  {// if all non-rejected Q are the same, take 1st order model
    25     if ((m_rgQp[i] != oneSampleQ) && !m_rgRejected[i])//如果当前的数据不是最后一个且当前数据没有被限制使用
    26       estimateX2 = TRUE;//标志位置为真
    27     if (!m_rgRejected[i])//如果数据没有被拒绝
    28       m_X1 += (m_rgQp[i] * m_rgRp[i]) / n_realSize;//为啥这样算???
    29   }
    30 
    31   // take 2nd order model to estimate X1 and X2 看不懂求解过程????
    32   if ((n_realSize >= 1) && estimateX2) {
    33       for (i = 0; i < n_windowSize; i++) {
    34       if (!m_rgRejected[i]) {//数据没有被限制使用 
    35       //线性回归优化
    36         a00 = a00 + 1.0;
    37         a01 += 1.0 / m_rgQp[i];
    38         a10 = a01;
    39         a11 += 1.0 / (m_rgQp[i] * m_rgQp[i]);
    40         b0 += m_rgQp[i] * m_rgRp[i];
    41         b1 += m_rgRp[i];
    42       }
    43     }
    44     // solve the equation of AX = B
    45       MatrixValue=a00*a11-a01*a10;//A矩阵行列式
    46       if(fabs(MatrixValue)>0.000001)//A行列式不为0 满秩
    47       {
    48         m_X1=(b0*a11-b1*a01)/MatrixValue;
    49         m_X2=(b1*a00-b0*a10)/MatrixValue;
    50       }
    51       else//A的行列式为0 特解
    52       {
    53         m_X1=b0/a00;
    54         m_X2=0.0;
    55       }
    56   
    57   }
    58   if(img->type==P_SLICE)
    59   {
    60     Pm_X1=m_X1;
    61     Pm_X2=m_X2;
    62   }
    63 }

    以下的码率控制模型的线性回归参数估计推导过程:

     三、Qstep(量化步长)估计的程序注释:

     1         //Pm_X1=bit_rate*1.0;//RD模型参数
     2            //Pm_X2=0.0;
     3         m_X1=Pm_X1;//RD模型的两个参数
     4         m_X2=Pm_X2;
     5         m_Hp=PPreHeader;
     6         m_Qp=Pm_Qp;//前一帧P帧的QP
     7         DuantQp=PDuantQp;//量化参数最大的变化量 2
     8         MADPictureC1=PMADPictureC1;//PMADPictureC1=1 线性预测的两个参数
     9         MADPictureC2=PMADPictureC2;//PMADPictureC1=0
    10         PreviousPictureMAD=PPictureMAD[0];
    11         
    12         /* predict the MAD of current picture*/
    13         CurrentFrameMAD=MADPictureC1*PreviousPictureMAD+MADPictureC2;//线性预测当前帧的MAD
    14         
    15         /*compute the number of bits for the texture*/      
    16         
    17         if(T<0)//当T小于0 直接使用前一个P帧的QP来预测 然后加2 得到当前的QP值
    18         {
    19           m_Qc=m_Qp+DuantQp;//前一帧P帧的QP加2 DuantQp=2
    20           m_Qc = MIN(m_Qc, RC_MAX_QUANT); // clipping
    21         }
    22         else//当T大于0 执行RD优化
    23         {
    24           m_Bits =T-m_Hp;//减去头部bits ??
    25           m_Bits = MAX(m_Bits, (int)(bit_rate/(MINVALUE*frame_rate)));//MINVALUE=4 确定一个最大值上界
    26           //求解m_Bits(Qstep)=X1*D/Qstep+x2*D/(Qstep*Qstep)一元二次方程解
    27           dtmp = CurrentFrameMAD * m_X1 * CurrentFrameMAD * m_X1 
    28             + 4 * m_X2 * CurrentFrameMAD * m_Bits;//判别式
    29           if ((m_X2 == 0.0) || (dtmp < 0) || ((sqrt (dtmp) - m_X1 * CurrentFrameMAD) <= 0.0)) // fall back 1st order mode
    30             m_Qstep = (float) (m_X1 * CurrentFrameMAD / (double) m_Bits);
    31           else // 2nd order mode
    32             m_Qstep = (float) ((2 * m_X2 * CurrentFrameMAD) / (sqrt (dtmp) - m_X1 * CurrentFrameMAD));
    33           
    34           m_Qc=Qstep2QP(m_Qstep);//0.625到224的Qstep映射到QP 0到51
    35           //m_Qp是前一P帧QP的预测
    36           m_Qc = MIN(m_Qp+DuantQp,  m_Qc);  // control variation
    37           m_Qc = MIN(m_Qc, RC_MAX_QUANT); // clipping
    38           m_Qc = MAX(m_Qp-DuantQp, m_Qc); // control variation
    39           m_Qc = MAX(RC_MIN_QUANT, m_Qc);//    QP平滑和限幅
    40         }

    以下的已知码率控制RQ模型的参数后,对当前Qstep(量化步长)的估计过程:

  • 相关阅读:
    应用市场高速下载以及网页端调起APP页面研究与实现
    linux系统下,添加硬盘并挂载到操作系统的shell 脚本范例
    linux系统下,新加硬盘并把现有的/home目录扩容。
    Java打印裴波那契数列
    JAVA排序的方法
    Java语言输出菱形图型
    Oracle中的sql脚本语言中的循环语句介绍
    Oracle存储过程的创建实例和调用实例
    数组常用方法3---新增元素
    数组常用方法2——修改数组元素。
  • 原文地址:https://www.cnblogs.com/weitter/p/13525229.html
Copyright © 2020-2023  润新知