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
在當前碼率情況下的最大長度,需要拋棄那些比這個斜率值小的所有編碼過程。其實可以理解為,增加編碼長度對失真的改進已經在降低,而且比我們期望的最小值還要低,所以即使加上了這些長度,失真的改進比期望的小了,那么這個點的斜率應該是最優化的,超出的過程需要截斷。