5_4 calvc

Cavlc

需要内容 

coeff_token 编码非零系数的个数(totalcoeff)trailingones(没个宏块一个)

Trailing_ones_sign_flag   trailing one值得符号

Level_prefix 非零系数码字的第一部分(每个系数一个,除了trailing ones

Level_suffix 非零系数码字的第二部分(不总是存在)

Total_zeros 编码第一个非零系数后面发生的零的总数(按zigzag顺序)(每个块一个)

Run_before 编码每个非零系数前的零的个数,按照反zigzag顺序

 

 

函数中对应代码

最开始调用计算非零个数  函数在x264_quant_init中初始化

 

调用函数 i_total = h->quantf.coeff_level_run[ctx_block_cat]( l, &runlevel );

 

初始化函数  pf->coeff_level_run4 = x264_coeff_level_run4;

    pf->coeff_level_run8 = x264_coeff_level_run8;

    pf->coeff_level_run[  DCT_LUMA_AC] = x264_coeff_level_run15;

pf->coeff_level_run[ DCT_LUMA_4x4] = x264_coeff_level_run16;

 

后面是个宏定义

 

#define level_run(num)\

static int x264_coeff_level_run##num( dctcoef *dct, x264_run_level_t *runlevel )\

{\

    int i_last = runlevel->last = x264_coeff_last##num(dct);\

    int i_total = 0;\

    int mask = 0;\

    do\

    {\

        runlevel->level[i_total++] = dct[i_last];\

        mask |= 1 << (i_last);\

        while( --i_last >= 0 && dct[i_last] == 0 );\

    } while( i_last >= 0 );\

    runlevel->mask = mask;\

    return i_total;\

}

 

level_run(4)

level_run(8)

level_run(15)

level_run(16)

展开

 

static int x264_coeff_level_run16( dctcoef *dct, x264_run_level_t *runlevel )

{

int i_last = runlevel->last = x264_coeff_last16(dct);

int i_total = 0;

int mask = 0;

 

do

{

runlevel->level[i_total++] = dct[i_last];

mask |= 1 << (i_last);

while ( --i_last >= 0; && dct[i_last] == 0 )

} while (i_last >= 0)

runlevel->mask = mask;

 

return total;

 

}

 

第二行的x264_coeff_last16(dct)还是个宏定义

 

#define last(num)\

static int x264_coeff_last##num( dctcoef *l )\

{\

    int i_last = num-1;\

    while( i_last >= 0 && l[i_last] == 0 )\

        i_last--;\

    return i_last;\

}

 

last(4)

last(8)

last(15)

last(16)

last(64)

 

展开

static int x264_coeff_last16( dctcoef *l )

{

int i_last = num-1;

while ( i_last >= 0 && l[i_last] == 0 )

i_last--;

return i_last;

}

 

这样这个宏的整体脉络比较清晰了,传输过来的dct就是活着4x4 8x8 16x16zig之后的那个一维数组,第二个函数x264_coeff_last16来统计这个序列中从最后开始有多少个0,最后返回第一个不是0的位置。

Runlevel中的last就是标识这个位置的。

 

里面的第二个循环就是将所有不为0的数复制到runlevel->level数组中,这个数组的元素个数和dct里面相同,因为复制的位置都完全相同的。

 

Level->mask元素暂且不知道具体含义,指示对每个位置都做了下左移位操作,有几个非0的元素就做几次左移。

posted on 2012-05-04 17:23  hatreds  阅读(226)  评论(0编辑  收藏  举报