VVC中码率控制算法沿用了HEVC中经典的 R-λ码率控制模型, R-λ由中科大的李斌博士提出(详情参考
JCTVC-K0103
)。
R-λ模型的基础为视频编码中
R(比特 bpp)和
D(失真 MSE)之间的双曲线模型,即
D ( R ) = C R − K D(R) = CR^{-K} D(R)=CR−K
R-λ模型中λ是R-D曲线的斜率,对上式求导,可得
λ = − ∂ D ∂ R = C K ⋅ R − K − 1 ≜ α ⋅ R β \lambda=-\frac{\partial D}{\partial R} = CK\cdot R^{-K-1} \triangleq \alpha \cdot R^ \beta λ=−∂R∂D=CK⋅R−K−1≜α⋅Rβ
其中 α α α和 β β β是和视频内容相关的参数。
码率控制主要可分成两个步骤:
1. 首先是比特分配,即将序列目标比特以一定策略确定GOP、帧和LCU各级单元的目标编码比特。
2. 依据分配到的目标比特,通过调整编码单元的编码参数,以达到分配到的目标比特。
1. 比特分配
一般情况下,序列第一帧所需分配的比特需要特殊考虑,第一帧的质量会很大程度上影响后续的编码效率和质量。实际应用中,第一帧的编码参数会根据一些先验知识进行设定。编码第一帧所需比特由于缺乏必要先验信息很难预测,一般采取的策略即给第一帧多分配,以保证质量。
首先定义平均每帧比特
R
p
i
c
A
v
g
=
R
t
a
r
/
F
R
R_{picAvg} = R_{tar} / FR
RpicAvg=Rtar/FR
其中
R
t
a
r
R_{tar}
Rtar为目标比特,FR为帧率。
1.1 GOP级比特分配
一般来说,每个GOP所分配的比特应该是一样的,但是由于实际编码的比特和目标比特总是有差异,GOP级比特分配引入滑动窗口SW来消除每个GOP的实际编码比特与目标比特的误差,每个GOP所分配的比特计算如下
T
G
O
P
=
R
p
i
c
A
v
g
⋅
(
N
c
o
d
e
d
+
S
W
)
−
R
c
o
d
e
d
S
W
×
N
G
O
P
T_{GOP} = \frac{R_{picAvg}\cdot (N_{coded} + SW) - R_{coded}}{SW} \times N_{GOP}
TGOP=SWRpicAvg⋅(Ncoded+SW)−Rcoded×NGOP
公式写成这样可能比较不容易理解,换个表达如下
T
G
O
P
=
T
p
i
c
A
v
g
×
N
G
O
P
T_{GOP} = T_{picAvg}\times N_{GOP}
TGOP=TpicAvg×NGOP 其中
T
p
i
c
A
v
g
=
R
p
i
c
A
v
g
+
R
p
i
c
A
v
g
⋅
N
c
o
d
e
d
−
R
c
o
d
e
d
S
W
T_{picAvg} = R_{picAvg} + \frac{R_{picAvg} \cdot N_{coded} - R_{coded}}{SW}
TpicAvg=RpicAvg+SWRpicAvg⋅Ncoded−Rcoded
显然,
R
p
i
c
A
v
g
R_{picAvg}
RpicAvg为目标码率,
R
p
i
c
A
v
g
⋅
N
c
o
d
e
d
−
R
c
o
d
e
d
R_{picAvg} \cdot N_{coded} - R_{coded}
RpicAvg⋅Ncoded−Rcoded为误差项,需要以SW为长度进行修正。
1.2 帧级比特分配
定义
T
G
O
P
T_{GOP}
TGOP为当前GOP目标比特,
C
o
d
e
d
G
O
P
Coded_{GOP}
CodedGOP为当前GOP已消耗比特,
ω
\omega
ω为当前GOP中每帧图片比特分配权重,于是当前帧所分配的比特计算如下
T
p
i
c
=
T
G
O
P
−
C
o
d
e
d
G
O
P
∑
m
=
0
N
R
P
ω
p
i
c
_
m
×
ω
c
u
r
r
P
i
c
T_{pic} = \frac{T_{GOP} - Coded_{GOP}}{ \sum_{m=0}^{N_{RP}} \omega_{pic\_m}} \times \omega_{currPic}
Tpic=∑m=0NRPωpic_mTGOP−CodedGOP×ωcurrPic
需要注意,I帧所分配的比特由bpp决定。
1.3 LCU级比特分配
类似于帧级比特分配策略,每个LCU所分配到的比特通过下式计算:
T
L
C
U
=
T
c
u
r
r
P
i
c
−
B
i
t
H
−
C
o
d
e
d
p
i
c
∑
A
l
l
N
o
t
C
o
d
e
d
L
C
U
ω
L
C
U
×
ω
c
u
r
r
L
C
U
T_{LCU} = \frac{T_{currPic} - Bit_{H}-Coded_{pic}}{\sum_{AllNotCodedLCU} \omega_{LCU}} \times \omega_{currLCU}
TLCU=∑AllNotCodedLCUωLCUTcurrPic−BitH−Codedpic×ωcurrLCU
其中
B
i
t
H
Bit_{H}
BitH为所有头信息编码所需比特,由之前对应已编码帧所用比特预测得到。
ω
L
C
U
\omega_{LCU}
ωLCU为每个LCU码率分配权重,由之前属于同一level 的已编码帧对应位置的LCU的预测误差(原始和预测信号的MAD)计算得到。
2. 码率控制
2.1 λ的计算和更新
根据
λ
\lambda
λ与R之间的关系
λ
=
−
∂
D
∂
R
=
C
K
⋅
R
−
K
−
1
≜
α
⋅
R
β
\lambda=-\frac{\partial D}{\partial R} = CK\cdot R^{-K-1} \triangleq \alpha \cdot R^ \beta
λ=−∂R∂D=CK⋅R−K−1≜α⋅Rβ,即
λ
\lambda
λ可由R通过
α
\alpha
α和
β
\beta
β直接计算得到。但是
α
\alpha
α和
β
\beta
β是和序列内容特性相关的参数,不同内容其值差异显著。R-λ模型通过引入如下算法解决此问题,首先使用下式计算帧和LCU的
λ
\lambda
λ
λ
=
α
b
p
p
β
\lambda = \alpha bpp ^ {\beta}
λ=αbppβ
这里
α
\alpha
α和
β
\beta
β对每帧和每个LCU都是不同的。为了实现内容自适应,
α
\alpha
α和
β
\beta
β会在编码过程中不断更新,在完成一个LCU或者一帧图像的编码后,
α
\alpha
α和
β
\beta
β更新方式如下
λ
=
α
o
l
d
b
p
p
r
e
a
l
β
o
l
d
\lambda = \alpha_{old} bpp_{real} ^ {\beta_{old}}
λ=αoldbpprealβold
α
n
e
w
=
α
o
l
d
+
δ
α
×
(
ln
λ
r
e
a
l
−
ln
λ
c
o
m
p
)
×
α
o
l
d
\alpha_{new} = \alpha_{old} + \delta_{ \alpha } \times (\ln\lambda_{real}-\ln\lambda_{comp} ) \times \alpha_{old}
αnew=αold+δα×(lnλreal−lnλcomp)×αold
β
n
e
w
=
β
o
l
d
+
δ
β
×
(
ln
λ
r
e
a
l
−
ln
λ
c
o
m
p
)
×
ln
b
p
p
r
e
a
l
\beta_{new} = \beta_{old} + \delta_{ \beta } \times (\ln\lambda_{real}-\ln\lambda_{comp} ) \times \ln{bpp_{real}}
βnew=βold+δβ×(lnλreal−lnλcomp)×lnbppreal
其中
b
p
p
r
e
a
l
bpp_{real}
bppreal为编码实际的bpp,
λ
r
e
a
l
\lambda{real}
λreal为实际使用λ。
记住以下这个公式:
R
=
(
λ
α
)
1
β
≜
α
1
⋅
λ
β
1
R=( \frac{ \lambda }{\alpha })^{\frac{1}{\beta}}\triangleq \alpha_1 \cdot \lambda^{\beta_1}
R=(αλ)β1≜α1⋅λβ1。
2.2 参数QP的确定
当
λ
\lambda
λ确定之后,QP的计算方式如下
Q
P
=
c
1
×
ln
(
λ
)
+
c
2
QP = c_1 \times \ln(\lambda)+c_2
QP=c1×ln(λ)+c2
其中
c
1
c_1
c1和
c
2
c_2
c2分别等于4.2005和13.7122。