1.1.
kd_compressed_stats
1.1.1.
功能
监视压缩过程统计状态的类,一个应用就是与在图像完全压缩之后通过
PCRD-opt
率分配算法找到的失真长度斜率门限相关的码块编码器的反馈。这允许编码器跳过几乎是肯定抛弃的编码过程。
当前非常简单的时间就是假定所有子带样本的可压缩性是相同的,而不管子带或分辨率层。这对于那些被处理的子带样本与子带的大小成比率是可行的,因为平均压缩性对于使用预测率控制属性是容易度量的。
1.1.2.
数据成员
名称
|
类型
|
说明
|
Target_rate
|
double
|
目标码率,用字节
/
样本来表示
|
Total_samples
|
int
|
整个图像中的总子带样本树
|
Next_trime
|
int
|
下个应该被修整的样本数
|
Conservative_extra_samples
|
int
|
增加到
num_coded_samples
,为了安全
|
Num_coded_samples
|
int
|
已经被编码的样本数量
|
Quant_slope_rates
|
Int[4096]
|
元素的索引由块过程斜率的
1/16
决定,值是到当前过程的所有过程编码长度和。斜率的值是
2
个字节,最大是
65535
,而为了归整到
4096
个元素中,必须除以
16
。
|
Min_quant_slope
|
int
|
在所有块编码过程中出现的最小量化斜率
|
Max_quant_slope
|
int
|
在所有编码过程中出现的最大的量化斜率
|
1.1.3.
成员函数
1.1.1.1.
get_conservative_slope_threshold
参数:
assume_all_coded, bool
类型
PCRD-opt
算法产生的斜率门限不可能比这里返回的值小,记住,小的门限意味着在码流中包含更多的压缩数据。如果参数使
true
,斜率门限基于这样的假定:对于任何更多的样本不产生字节。否则,假定为:将来的样本将有与已经编码的有相同的平均压缩性。注意,由于压缩器倾向于先输出高频子带样本的高比率部分,因此后来样本的实际压缩性低于平均值,使我们的估计更保守。
1.
设置临时编码
max_bytes
2.
如果
all_coded
为
true
,设置
max_bytes
为目保码率×总样本数量。否则设置其为目标码率×已经编码的样本和保守的额外样本数(
conservative_extra_samples
)。
3.
设置
curmulative_byte
临时变量为
0
4.
设置初始
n
为
max_quant_slope
,并逐次减
1
循环,结束的条件是
n
小于
min_quant_slope
。
5.
累加
curmulative_bytes
的值为
quant_slope_rates
,如果某个循环中,其大于
max_bytes
,停止循环。
6.
判断
n
是否大于
0
,如果大于
0
,取
n
×
16
-
1
的值返回,否则返回
1
。
1.1.1.2.
kd_compressed_stats
参数:
total_samples(
总样本数量
)
,
target_bytes
(目标字节数量)。
1.
保存总样本数量
2.
设置
next_trim
为总样本数量的字节数量
3.
设置
conservative_extra_samples
为
4096
加总样本数量除以
16
。
4.
计算目标码率,如果总样本数量是
0
,为
1
,否则目标字节除以总样本树,单位为字节
/
样本
5.
设置已经编码的样本数量为
0
6.
Min_quant_slope
为
4095
,
max_quat_slope
为
0
7.
设置
quant_slope_rates
的每个元素为
0
1.1.1.3.
update
参数:
block
对象
如果该函数返回
TRUE
,推荐压缩的数据流截断到与该点目标压缩长度一直的大小。
1.
增加已经编码的样本数量;加上码块的高度乘宽度
2.
设置临时变量
quant_slope
和
length
参数为
0
,
3.
按照块的编码过程来循环
4.
累计每个块编码过程的长度
5.
如果某个块的过程斜率为
0
,循环下一操作
6.
否则设置临时变量
quant_slope
为块编码过程斜率除以
16
的值,现在其再
0
到
4096
范围内。作为
quant_slope_rates
数组的索引。
7.
如果
quant_slope
比
min_quant_slope
小,那么
min_quant_slope
取该值;如果其比
max_quant_slope
当,那么
max_quant_slope
取该值。
8.
修改
quant_slope_rates
的
quant_slope
个元素的值,增加
length
;实际上,后面的元素比前面的元素要大。
9.
如果已经编码的样本比
next_trim
要大,那么将增加总样本数量的
1/16
个字节到
next_trim
中。并且返回
true
。否则返回
false
。
1.1.4.
讨论
压缩状态类进行码率分配方面的工作。
1.
首先对斜率门限进行了量化,也就是
16
个门限值量化为一个值,这样有
4096
个门限量化值(这里说明,斜率门限最大值是
65536
)。
Quat_slope_rates
的每个入口保存着当前门限下编码的长度,其应该是一个增加值的序列。
2.
刚开始的时候设置检查截断点的地方是八分之一样本处。并且为每次样本增加保守的空间来计算。
3.
码率是按照目标字节数量和样本总数确定的。
4.
每次对
block
编码的时候,首先查寻的到一个当前的门限值;当然第一个
block
是
1
。这里基于一个假设,所有
block
的可压缩性是均匀的。
5.
在每次查询斜率量化值的时候,首先计算已经编码的最大字节数量,然后在已经编码的许列中找到一个满足到当前点所有长度的累加值比理想最大长度小的点,这个点对应的数值就是当前块采用的估计斜率值。所以从这里可以看到,对当前编码块的压缩性是假设与前面编码过的
block
相等的。
6.
在块编码完成以后需要根据块编码过程中产生的斜率和当前过程长度来重新更新前面的值。
7.
这个时候需要先计算已经编码的样本的数量。
8.
Block
的编码过程中可能存在不在
convex hull
上的点,这些点的斜率不是我们要求的,被踢出,而将在凸壳上的自然过程截断点的斜率进行比较。这里对该过程的斜率进行了
1/16
的量化,并且检查设置下个斜率区间的范围。
9.
对在凸壳上的自然截断点需要查找对应的量化斜率
rate
入口,并将该过程产生的编码长度增加到该入口中。对于
8
中描述的,不在凸壳上的点所在那个过程产生的编码长度被累加到下一个在凸壳上的点量化斜率
rate
入口中。
10.
最后需要检查是否已经到了需要截断码流的位置,初始的时候设置的是在总样本
1/8
处检查一次,以后每次增加
1/16
,那么检查点的序列为:
2/16-3/16-4/16-5/16-….
在进行
trim
的时候,已经对当前编码
block
对码流的贡献做了更新,因此斜率值是当前
block
对失真长度曲线产生的真正斜率。那么如果码流已经超出了当前
block
在当前码率情况下的最大长度,需要抛弃那些比这个斜率值小的所有编码过程。其实可以理解为,增加编码长度对失真的改进已经在降低,而且比我们期望的最小值还要低,所以即使加上了这些长度,失真的改进比期望的小了,那么这个点的斜率应该是最优化的,超出的过程需要截断。