H264視頻圖像壓縮編碼算法主要基于DCT 變換和熵編碼等基本算法。視頻數(shù)據(jù)一般分成4×4像素塊,先經(jīng)DCT 變換,再進(jìn)行量化和游程編碼,最后得到編碼后的壓縮數(shù)據(jù)。
經(jīng)過量化得到的4×4的DCT 系數(shù)具有一定的特征:較大的非零系數(shù)集中于4×4 塊的左上角,而值為零的系數(shù)大多在右下角。所以,如果按表1 的順序來掃描這個(gè)4×4塊,映射成1× 16 的序列,則非零系數(shù)相對(duì)集中,通過游程編碼就可以達(dá)到壓縮的目的。上述用來掃描4×4塊DCT 系數(shù)的表就叫做ZigZag 表,掃描的過程就稱作ZigZag掃描。解碼算法只要用這種規(guī)定的順序來掃描,就可以正確的解碼任何符合H264標(biāo)準(zhǔn)的碼流。
/*
原掃描順序(表1:ZigZag 表):
x 0 1 2 3
y 0 00 01 05 06
1 02 04 07 12
2 03 08 11 13
3 09 10 14 15
置亂后的掃描順序(也即秘鑰):
x 0 1 2 3
y 0 00 04 13 12
1 07 01 02 06
2 15 08 11 05
3 09 14 10 15
*/
之字形置亂加密的主導(dǎo)思想:在編碼時(shí),采用自己設(shè)計(jì)的一個(gè)隨機(jī)置亂表代替標(biāo)準(zhǔn)中規(guī)定的ZigZag 掃描表,這樣編出的視頻數(shù)據(jù)如果用標(biāo)準(zhǔn)中的ZigZag表來掃描解碼的話,得到的圖像將是加密后的圖像。要想得到正確的圖像,必須要用編碼時(shí)使用的表。因此,可以把編碼時(shí)使用的掃描表當(dāng)作密鑰,從而實(shí)現(xiàn)視頻加密。
代碼修改:
1、 編碼端(針對(duì)X264的代碼進(jìn)行修改)
將macroblock.c中的:
/*
static inline void scan_zigzag_4x4full( int level[16], int16_t dct[4][4] )
{
ZIG( 0,0,0) ZIG( 1,0,1) ZIG( 2,1,0) ZIG( 3,2,0)
ZIG( 4,1,1) ZIG( 5,0,2) ZIG( 6,0,3) ZIG( 7,1,2)
ZIG( 8,2,1) ZIG( 9,3,0) ZIG(10,3,1) ZIG(11,2,2)
ZIG(12,1,3) ZIG(13,2,3) ZIG(14,3,2) ZIG(15,3,3)
}//原scan_zigzag_4x4full掃描順序
static inline void scan_zigzag_4x4( int level[15], int16_t dct[4][4] )
{
ZIG( 0,0,1) ZIG( 1,1,0) ZIG( 2,2,0)
ZIG( 3,1,1) ZIG( 4,0,2) ZIG( 5,0,3) ZIG( 6,1,2)
ZIG( 7,2,1) ZIG( 8,3,0) ZIG( 9,3,1) ZIG(10,2,2)
ZIG(11,1,3) ZIG(12,2,3) ZIG(13,3,2) ZIG(14,3,3)
}//原scan_zigzag_4x4掃描順序
*/
修改為:
static inline void scan_zigzag_4x4full( int level[16], int16_t dct[4][4] )
{
ZIG( 0,0,0) ZIG( 4,0,1) ZIG( 7,1,0) ZIG(15,2,0)
ZIG( 1,1,1) ZIG(13,0,2) ZIG(12,0,3) ZIG( 2,1,2)
ZIG( 8,2,1) ZIG( 9,3,0) ZIG(14,3,1) ZIG(11,2,2)
ZIG( 6,1,3) ZIG( 5,2,3) ZIG(10,3,2) ZIG( 3,3,3)
}//置亂后的scan_zigzag_4x4full掃描順序
static inline void scan_zigzag_4x4( int level[15], int16_t dct[4][4] )
{
ZIG( 3,0,1) ZIG( 6,1,0) ZIG(14,2,0)
ZIG( 0,1,1) ZIG(12,0,2) ZIG(11,0,3) ZIG( 1,1,2)
ZIG( 7,2,1) ZIG( 8,3,0) ZIG(13,3,1) ZIG(10,2,2)
ZIG( 5,1,3) ZIG( 4,2,3) ZIG( 9,3,2) ZIG( 2,3,3)
}//置亂后的掃描順序,由置亂后的scan_zigzag_4x4full減1即可.
2、 在解碼端;(針對(duì)從FFMPEG中抽取的264解碼代碼進(jìn)行修改)
修改頭文件h264data.h中的代碼:
/*
static const uint8_t zigzag_scan[16]={
0+0*4, 1+0*4, 0+1*4, 0+2*4,
1+1*4, 2+0*4, 3+0*4, 2+1*4,
1+2*4, 0+3*4, 1+3*4, 2+2*4,
3+1*4, 3+2*4, 2+3*4, 3+3*4,
};//原zigzag掃描順序
修改為:
static const uint8_t zigzag_scan[16]={
0+0*4, 1+1*4, 2+1*4, 3+3*4,
1+0*4, 3+2*4, 3+1*4, 0+1*4,
1+2*4, 0+3*4, 2+3*4, 2+2*4,
3+0*4, 2+0*4, 1+3*4, 0+2*4,
};//置亂后的掃描順序
*/
缺點(diǎn)體現(xiàn)在以下兩點(diǎn):
1、 由于只使用了一張置亂序列表,且為4X4的,所以破解置亂表的難度不高。即使使用兩張表,破解難度也只是增加了一倍,只要破解出一個(gè)表,另一個(gè)表也就不難了。
2、 對(duì)于DC 系數(shù),其值遠(yuǎn)大于AC 系數(shù)值,因此亂序后很容易被識(shí)別。
改進(jìn)方案:
1、 在每次出現(xiàn)I幀的時(shí)候改變置亂序列表,提高置亂序列表的破解難度?;蛘哂眯蛄邪l(fā)生器,每幀都分配一個(gè)隨機(jī)置亂序列表。
2、 對(duì)DC我們一次提取一幀圖像里面的所有DC系數(shù),用高強(qiáng)度的加密算法AES加密,加密后的DC再按順序返回到碼流中。到解碼端,再按照同樣的操作提取DC系數(shù),然后解密。(適用于加密傳輸?shù)膽?yīng)用中)