H264编码- 码率控制 RQ 模型参数推导过程以及JM代码分析

摘要:本文主要介绍H264码率控制过程中,RQ模型参数更新推导过程,并结合JM19.0代码分析其功能实现

H264码率控制中比较重要的一个模型是RQ模型,不管是图像级码率控制还是基本单元码率控制都会用到。

RQ模型主要作用是根据目标比特数以及预测MAD,预测得到当前编码单元(帧/宏块)的量化步长QStep,得到量化步长后,才可以进行后续的率失真优化RDO获取最佳编码方式。

RQ模型参数初始值是固定值,肯定不能满足所有的编码场景,因此,在编码过程中需要根据已编码的数据不断更新参数,从而使 RQ 模型更加精准。

1. RQ模型

RQ模型公式如下:
T a r g e t = c 1 ∗ M A D Q S t e p + c 2 ∗ M A D Q S t e p 2 Target = c1* \frac {MAD} {QStep} + c2* \frac {MAD} {QStep^2} Target=c1QStepMAD+c2QStep2MAD
其中, T a r g e t Target Target 表示预测得到的目标比特数,
M A D MAD MAD表示编码后数据的平均误差,由于这个时候还没有开始编码,所以这个值也是通过已编码帧的MAD预测当前帧得到的。

c 1 、 c 2 c1、c2 c1c2就是我们要不断更新的参数。

2. 参数更新过程

使用线性回归算法来更新RQ模型的参数。更新过程由下面三步组成(这部分代码实现参考JM的updateRCModel函数):

  1. 选择数据集

模型的准确度依赖于做线性回归的数据集大小及其质量。一般来说,选择的数据量越多,越能反映出平均情况,但难以反映出实时情况。例如在场景切换时,需要根据最近的情况及时更新模型。

在滑动窗口内的已编码视频帧的信息 ( Q S t e p i 、 M A D i 、 b i t s i ) (QStep_{i}、MAD_{i}、bits_{i}) QStepiMADibitsi构成了一组数据集。每编码一个帧或基本编码单元,会把该次编码生成的数据样本放入滑动窗,作为数据集的一部分。

  1. 计算模型参数

根据滑动窗内数据集(QStep、MAD、编码bit数),使用线性回归法更新RQ模型参数。计算过程在JM的RCModelEstimator函数
使用线性回归方法,统计数据集中所有样本,使得真实编码比特数和RQ模型预测目标比特数最接近。

  1. 移除滑动窗内误差太大的数据样本,并重新计算RQ模型参数。

使用上一步骤计算得到的RQ模型参数计算每个样本的均方差,均方差超过阈值K的样本则认为该数据是错误数据,应该从数据集剔除。然后再根据步骤2重新计算一次RQ模型参数。

3. 线性回归推导

参数更新通过线性回归方法实现.
可得到滑动窗内所有样本平方差代价函数如下:
E = ∑ i = 1 n ( c 1 ∗ M A D i / Q S t e p i + c 2 ∗ M A D i / Q S t e p i 2 − T a r g e t i ) 2 E= \sum_{i=1}^{n} (c_1* MAD_{i}/QStep_{i} + c_2*MAD_{i}/QStep_{i}^2-Target_{i})^2 E=i=1n(c1MADi/QStepi+c2MADi/QStepi2Targeti)2

x = Q S t e p x=QStep x=QStep,表示实际编码使用的量化步长;
y = b i t s y=bits y=bits,表示最终编码后的真实比特数。

代价函数可表示为
E ( c 1 , c 2 ) = ∑ i = 1 n ( c 1 ∗ M A D i / x i + c 2 ∗ M A D i / x i 2 − y i ) 2 E(c_1,c_2)= \sum_{i=1}^{n} (c_1* MAD_{i}/x_{i} + c_2*MAD_{i}/x_{i}^2-y_{i})^2 E(c1,c2)=i=1n(c1MADi/xi+c2MADi/xi2yi)2
我们要做的实际上是求得 c 1 , c 2 c_1,c_2 c1,c2,使 E E E最小。

分 别 对 c 1 和 c 2 求 偏 导 , 可 得 E 的 最 小 值 分别对c_1和c_2求偏导,可得E的最小值 c1c2E
∂ E ∂ c 1 = ∂ ∑ i = 1 n ( c 1 ∗ M A D i / x i + c 2 ∗ M A D i / x i 2 − y i ) 2 ∂ c 1 = 0 \frac{\partial E}{\partial c_1}=\frac{\partial \sum_{i=1}^{n} (c_1* MAD_{i}/x_{i} + c_2*MAD_{i}/x_{i}^2-y_{i})^2}{\partial c_1}=0 c1E=c1i=1n(c1MADi/xi+c2MADi/xi2yi)2=0

∑ i = 1 n ∂ ( c 1 ∗ M A D i / x i + c 2 ∗ M A D i / x i 2 − y i ) 2 ∂ c 1 = 0 \sum_{i=1}^{n} \frac{\partial (c_1* MAD_{i}/x_{i} + c_2*MAD_{i}/x_{i}^2-y_{i})^2}{\partial c_1} = 0 i=1nc1(c1MADi/xi+c2MADi/xi2yi)2=0

2 ∗ ∑ i = 1 n ( c 1 ∗ M A D i / x i + c 2 ∗ x i / x i 2 − y i ) ∗ M A D i x i = 0 2*\sum_{i=1}^{n} { (c_1* MAD_{i}/x_{i} + c_2*x_{i}/x_{i}^2-y_{i})} * \frac {MAD_i} {x_i}= 0 2i=1n(c1MADi/xi+c2xi/xi2yi)xiMADi=0

∑ i = 1 n ( c 1 + c 2 x i − y i ∗ x i / M A D i ) = 0 \sum_{i=1}^{n} (c_1+ \frac{c_2} {x_i} - y_i*x_i/MAD_i)=0 i=1n(c1+xic2yixi/MADi)=0

同理对 c 2 c_2 c2的偏导可得方程:
∑ i = 1 n ( c 1 / x i + c 2 / x i 2 − y i / M A D i ) = 0 \sum_{i=1}^{n} (c_1/x_i+ {c_2}/ {x_i^2} - y_i/MAD_i)=0 i=1n(c1/xi+c2/xi2yi/MADi)=0

可得矩阵运算方程
[ ∑ i = 1 n 1 ∑ i = 1 n 1 / x i ∑ i = 1 n 1 / x i ∑ i = 1 n 2 / x i 2 ] ∗ [ c 1 c 2 ] = [ ∑ i = 1 n y i ∗ x i / M A D i ∑ i = 1 n y i / M A D i ] \begin{bmatrix} \sum_{i=1}^{n} 1 & \sum_{i=1}^{n} 1/x_i \\ \sum_{i=1}^{n} 1/x_i & \sum_{i=1}^{n} 2/x_i^2 \\ \end{bmatrix} * \begin{bmatrix} c_1 \\ c_2 \\ \end{bmatrix}= \begin{bmatrix} \sum_{i=1}^{n} y_i*x_i/MAD_i \\ \sum_{i=1}^{n} y_i/MAD_i \\ \end{bmatrix} [i=1n1i=1n1/xii=1n1/xii=1n2/xi2][c1c2]=[i=1nyixi/MADii=1nyi/MADi]
求解以上方程可得 c 1 , c 2 c_1,c_2 c1,c2

JM代码中求解过程在函数RCModelEstimator中,其中用到的几个变量如下:
a 00 = ∑ i = 1 n 1 , a 01 = ∑ i = 1 n 1 / x i a_{00}=\sum_{i=1}^{n} 1, a_{01}= \sum_{i=1}^{n} 1/x_i a00=i=1n1,a01=i=1n1/xi
a 10 = ∑ i = 1 n 1 / x i , a 11 = ∑ i = 1 n 2 / x i 2 a_{10}= \sum_{i=1}^{n} 1/x_i, a_{11}= \sum_{i=1}^{n} 2/x_i^2 a10=i=1n1/xi,a11=i=1n2/xi2
b 0 = ∑ i = 1 n y i ∗ x i / M A D i , b 1 = ∑ i = 1 n y i / M A D i b_0=\sum_{i=1}^{n} y_i*x_i/MAD_i , b_1=\sum_{i=1}^{n} y_i/MAD_i b0=i=1nyixi/MADi,b1=i=1nyi/MADi

void RCModelEstimator (VideoParameters *p_Vid, InputParameters *p_Inp, RCQuadratic *p_quad, int n_windowSize, Boolean *m_rgRejected)
{
  int n_realSize = n_windowSize;
  int i;
  double oneSampleQ = 0;
  double a00 = 0.0, a01 = 0.0, a10 = 0.0, a11 = 0.0, b0 = 0.0, b1 = 0.0;
  double MatrixValue;
  Boolean estimateX2 = FALSE;

// 获取滑动窗内有效样本个数
  for (i = 0; i < n_windowSize; i++)
  {// find the number of samples which are not rejected
    if (m_rgRejected[i])
      n_realSize--;
  }

  // default RD model estimation results,m_X1、m_X2对应公式里的c1、c2
  p_quad->m_X1 = p_quad->m_X2 = 0.0;

  for (i = 0; i < n_windowSize; i++)
  {
    if (!m_rgRejected[i])
      oneSampleQ = p_quad->m_rgQp[i]; // m_rgQp存放的是QStep值
  }
  for (i = 0; i < n_windowSize; i++)
  {// if all non-rejected Q are the same, take 1st order model
    if ((p_quad->m_rgQp[i] != oneSampleQ) && !m_rgRejected[i])
      estimateX2 = TRUE;
    if (!m_rgRejected[i])
      p_quad->m_X1 += (p_quad->m_rgQp[i] * p_quad->m_rgRp[i]) / n_realSize;
  }

  // take 2nd order model to estimate X1 and X2
  /*
  求解方程,也就是上面推导的矩阵公式
  | a00  a01 |  |  m_x1 | = | b0 |
  | a10  a11 |  |  m_x2 |    | b1 |
  */
  if ((n_realSize >= 1) && estimateX2)
  {
    for (i = 0; i < n_windowSize; i++)
    {
      if (!m_rgRejected[i])
      {
        a00  = a00 + 1.0;
        a01 += 1.0 / p_quad->m_rgQp[i];
        a10  = a01;
        a11 += 1.0 / (p_quad->m_rgQp[i] * p_quad->m_rgQp[i]);
        b0  += p_quad->m_rgQp[i] * p_quad->m_rgRp[i];
        b1  += p_quad->m_rgRp[i];
      }
    }
    // solve the equation of AX = B
    MatrixValue=a00*a11-a01*a10;
    if(fabs(MatrixValue) > 0.000001)
    {
      p_quad->m_X1 = (b0 * a11 - b1 * a01) / MatrixValue;
      p_quad->m_X2 = (b1 * a00 - b0 * a10) / MatrixValue;
    }
    else
    {
      p_quad->m_X1 = b0 / a00;
      p_quad->m_X2 = 0.0;
    }
  }
  if( p_Vid->type == P_SLICE || (p_Inp->RCUpdateMode == RC_MODE_1 && (p_Vid->number != 0)) )
  {
    p_quad->Pm_X1 = p_quad->m_X1;
    p_quad->Pm_X2 = p_quad->m_X2;
  }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于QR-EGARCH-SGED模型计算VaR的具体代码比较复杂,这里只能给出大致的思路和部分代码示例。具体实现还需要参考相关文献和数据情况进行调整。 首先,需要用R语言中的quantreg包进行分位数回归分析,得到QR-EGARCH-SGED模型的系数。然后,使用rugarch包建立EGARCH-SGED模型,并将分位数回归得到的系数加入到模型中。 接下来,可以使用VaR估计方法中的历史模拟法(Historical Simulation)、蒙特卡罗模拟法(Monte Carlo Simulation)、基于正态分布的方法(Parametric Method)等方法,对VaR进行计算。 以Historical Simulation为例,具体代码如下: ```R library(rugarch) library(quantreg) # 读取数据 data <- read.csv("data.csv", header = TRUE) # 分位数回归 qr_model <- rq(y ~ x1 + x2 + x3, tau = 0.05, data = data) qr_coef <- coef(qr_model) # 建立EGARCH-SGED模型 spec <- ugarchspec(variance.model = list(model = "eGARCH", garchOrder = c(1, 1)), mean.model = list(armaOrder = c(1, 1), include.mean = TRUE), distribution.model = "sGED") # 将分位数回归得到的系数加入到模型中 spec@coef$mu <- qr_coef[1] spec@coef$ar1 <- qr_coef[2] spec@coef$ar2 <- qr_coef[3] spec@coef$ar3 <- qr_coef[4] # 拟合模型 fit <- ugarchfit(spec = spec, data = data$y) # 计算VaR VaR <- quantile(data$y, 0.05) ``` 需要注意的是,上述代码中的数据需要根据实际情况进行替换和调整。同时,还需要对其他参数进行设置,如分位数回归的tau值、EGARCH-SGED模型的阶数等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值