最初调用位置
h->zigzagf.scan_4x4( h->dct.luma4x4[p*16+idx], dct4x4 );
第一个参数就是个空的一维数组,第二个是4x4的宏块,经过dct和量化后的。目的就是为了将第二个数组中的内容线性的放入第一个数组
Encoder_open中初始化 通过参数分了帧和场 主要先看帧progressive
void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf_progressive, x264_zigzag_function_t *pf_interlaced )
pf_interlaced->scan_8x8 = zigzag_scan_8x8_field;
pf_progressive->scan_8x8 = zigzag_scan_8x8_frame;
pf_interlaced->scan_4x4 = zigzag_scan_4x4_field;
pf_progressive->scan_4x4 = zigzag_scan_4x4_frame;
pf_interlaced->sub_8x8 = zigzag_sub_8x8_field;
pf_progressive->sub_8x8 = zigzag_sub_8x8_frame;
pf_interlaced->sub_4x4 = zigzag_sub_4x4_field;
pf_progressive->sub_4x4 = zigzag_sub_4x4_frame;
pf_interlaced->sub_4x4ac = zigzag_sub_4x4ac_field;
pf_progressive->sub_4x4ac = zigzag_sub_4x4ac_frame;
Dct是刚生命的那个 dct4x4
static void zigzag_scan_4x4_frame( dctcoef level[16], dctcoef dct[16] )
{
ZIGZAG4_FRAME
}
//前面是标示要生成数组下表,后面是4x4的数组下标
#define ZIGZAG4_FRAME\
ZIGDC( 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)
展开ZIGZAG4_FRAME
#define ZIGDC(i,y,x) ZIG(i,y,x)
#define ZIG(i,y,x) level[i] = dct[x*4+y];
单纯的zig中就是调用的这两个函数
全局笔记貌似很不错
http://blog.csdn.net/nba520pz/article/details/7466787
另外一个
http://blog.csdn.net/markman101/article/category/762869
H264视频图像压缩编码算法主要基于dct变换和熵编码等基本算法。视频数据一般分为4x4像素块,先经dct变换,然后进行量化和游程编码,最后得到编码后压缩数据。
经过量化后等到的4x4dct系数具有一定特征,较大的非零系数集中于4x4块的左上角,而值为0的系数大多在右下角。所以如果经过zig扫描这个4x4块,映射为1x16序列,则非零系数相对几种,通过游程编码就能达到压缩目的。
void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf_progressive, x264_zigzag_function_t *pf_interlaced )
{
pf_interlaced->scan_8x8 = zigzag_scan_8x8_field;
pf_progressive->scan_8x8 = zigzag_scan_8x8_frame;
pf_interlaced->scan_4x4 = zigzag_scan_4x4_field;
pf_progressive->scan_4x4 = zigzag_scan_4x4_frame;
pf_interlaced->sub_8x8 = zigzag_sub_8x8_field;
pf_progressive->sub_8x8 = zigzag_sub_8x8_frame;
pf_interlaced->sub_4x4 = zigzag_sub_4x4_field;
pf_progressive->sub_4x4 = zigzag_sub_4x4_frame;
pf_interlaced->sub_4x4ac = zigzag_sub_4x4ac_field;
pf_progressive->sub_4x4ac = zigzag_sub_4x4ac_frame;
}
函数都可以直接找到定义没有宏定义 以4x4 frame类型为例可以看出zig的过程
static void zigzag_scan_4x4_frame( dctcoef level[16], dctcoef dct[16] )
{
/*****************************************************************
printf("================before level=================\n");
for (int i = 0; i < 16; i++)
{
printf("[%d]",level[i]);
}
printf("\n");
printf("================before dct=================\n");
for (int i = 0; i < 16; i++)
{
printf("[%d]",dct[i]);
}
printf("\n");
******************************************************************/
//在zig之前所有的level 都是0 应该就是一个内存空间为了放置后面那个4x4的矩阵
ZIGZAG4_FRAME
/****************************************************************
printf("================after level=================\n");
for (int i = 0; i < 16; i++)
{
printf("[%d]",level[i]);
}
printf("\n");
printf("================after dct=================\n");
for (int i = 0; i < 16; i++)
{
printf("[%d]",dct[i]);
}
printf("\n");
******************************************************************/
}
多的都是自己看的打印信息只有一个宏定义的调用 ZIGZAG4_FRAME
#define ZIGZAG4_FRAME\
ZIGDC( 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)
#define ZIG(i,y,x) level[i] = dct[x*4+y]; \
#define ZIGDC(i,y,x) ZIG(i,y,x) \
插入一个计算结果来理解
CABAC 计算过程
http://blog.csdn.net/sunshine1314/articl