码率控制(五):流体流量模型
码率控制的主要作用就是适应带宽需求来压缩码率,防止网络频繁丢包
流体流量模型就是模拟比特数据在网络和缓存器中的状态,下面从解码端的视角来说明。
HRD( hypothetical reference decoder)中的CPB(coded picture buffer)是用来缓存比特数据的,CPB的容量有限,如果CPB装满了则接下来的数据就会溢出造成数据丢失(上溢),如果CPB太空则造成浪费(下溢)。
CPB的状态可以用三个量来刻画,R、B、F。R表示网络传输带宽,B表示CPB容量,F表示CPB充盈度。下图是一个CPB的状态变化图:
其中i表示第i帧图像,bi表示第i帧图像的比特数,f表示帧率。
什么是上溢和下溢?
码率控制算法的一个重要作用就是防止CPB上溢和下溢。
上面两个公式分别描述了上溢和下溢发生的情况。
公式(1)表示在某个时刻从CPB中取出第i帧数据用于解码,同时网络向CPB中写入R/f比特数据,此时CPB的比特数超过容量B发生了上溢。下图是发生上溢的情况。
公式(2)表示在某个时刻从CPB中取出第i帧数据用于解码,但CPB中数据不够,发生了下溢。下图是发生下溢的情况。
防止上溢和下溢
为了防止上溢和下溢的发生,HM中实现了帧级的码率调整,使CPB的充盈度保持在10%-90%。码率调整在计算图像lambda和QP之前完成。
如下图所示:
上面的状态图可以用下面公式表示:
tbi是HM中码率控制算法计算的第i帧的目标比特,如果发生上溢则将tbi设置为Fi+R/f-Bx0.9,如果发生上溢则将tbi设置为max(200,Fi-Bx0.1)。
参考代码
#if U0132_TARGET_BITS_SATURATION
if (m_pcRateCtrl->getCpbSaturationEnabled() && frameLevel != 0)
{
Int estimatedCpbFullness = m_pcRateCtrl->getCpbState() + m_pcRateCtrl->getBufferingRate();
// prevent overflow
if (estimatedCpbFullness - estimatedBits > (Int)(m_pcRateCtrl->getCpbSize()*0.9f))
{
estimatedBits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.9f);
}
estimatedCpbFullness -= m_pcRateCtrl->getBufferingRate();
// prevent underflow
#if V0078_ADAPTIVE_LOWER_BOUND
if (estimatedCpbFullness - estimatedBits < m_pcRateCtrl->getRCPic()->getLowerBound())
{
estimatedBits = max(200, estimatedCpbFullness - m_pcRateCtrl->getRCPic()->getLowerBound());
}
#else
if (estimatedCpbFullness - estimatedBits < (Int)(m_pcRateCtrl->getCpbSize()*0.1f))
{
estimatedBits = max(200, estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.1f));
}
#endif
m_pcRateCtrl->getRCPic()->setTargetBits(estimatedBits);
}
#endif
参考
JCTVC-U0132
感兴趣的请关注微信公众号Video Coding