分享

x264之scan_zigzag_4x4full

 lyz1985 2010-07-14
之字形置乱加密的代码修改与说明 

H264视频图像压缩编码算法主要基于DCT 变换和熵编码等基本算法。视频数据一般分成4×4像素块,先经DCT 变换,再进行量化和游程编码,最后得到编码后的压缩数据。

经过量化得到的4×4DCT 系数具有一定的特征:较大的非零系数集中于4×4 块的左上角,而值为零的系数大多在右下角。所以,如果按表1 的顺序来扫描这个4×4块,映射成1× 16 的序列,则非零系数相对集中,通过游程编码就可以达到压缩的目的。上述用来扫描4×4DCT 系数的表就叫做ZigZag 表,扫描的过程就称作ZigZag扫描。解码算法只要用这种规定的顺序来扫描,就可以正确的解码任何符合H264标准的码流。

/*

原扫描顺序(表1ZigZag ):

  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

*/

之字形置乱加密的主导思想:在编码时,采用自己设计的一个随机置乱表代替标准中规定的ZigZag 扫描表,这样编出的视频数据如果用标准中的ZigZag表来扫描解码的话,得到的图像将是加密后的图像。要想得到正确的图像,必须要用编码时使用的表。因此,可以把编码时使用的扫描表当作密钥,从而实现视频加密。

代码修改:

1、   编码端(针对X264的代码进行修改)

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_4x4full1即可.

 

2、   在解码端;(针对从FFMPEG中抽取的264解码代码进行修改)

修改头文件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,

};//置乱后的扫描顺序

*/

 

缺点体现在以下两点:

1、   由于只使用了一张置乱序列表,且为4X4的,所以破解置乱表的难度不高。即使使用两张表,破解难度也只是增加了一倍,只要破解出一个表,另一个表也就不难了。

2、   对于DC 系数,其值远大于AC 系数值,因此乱序后很容易被识别

改进方案

1、   在每次出现I帧的时候改变置乱序列表,提高置乱序列表的破解难度。或者用序列发生器,每帧都分配一个随机置乱序列表。

2、   DC我们一次提取一帧图像里面的所有DC系数,用高强度的加密算法AES加密,加密后的DC再按顺序返回到码流中。到解码端,再按照同样的操作提取DC系数,然后解密。(适用于加密传输的应用中)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多