一. 引擎的初始化
引擎初始化 |
|
标准定义 |
FFMPEG实现 |
codIRange = 0x01FE codIOffset = read_bits( 9 )
codIRange和codIOffset都是16位精度 |
range= 0x1FE; low = read_bits(16)<<10; if(((uintptr_t)c->bytestream & 1) == 0) { c->low += (1 << 9);//这里作2字节对齐仅仅是优化内存访问效率 }else { c->low += ((*c->bytestream++) << 2) + 2; //在后面的10bit中先放入8bit码字,再放入标志1和尾部的0 } Low中一共使用了26个bit,前面为码字,尾部为标志1和拖尾的0,根据拖尾的0的个数可计算出low中还有多少bit的码字(26 – 1 - 拖尾0个数) codIRange和codIOffset都是9bit数,但ffmpeg中low被放到了26个bit的前面,所以range在参与low的运算(比较或加减时)需要放到同样的位置,即左移26-9=17= CABAC_BITS+1 |
Context初始化 |
|
标准定义 |
FFMPEG实现 |
preCtxState = Clip3( 1, 126, ( ( m ∗ Clip3( 0, 51, SliceQPY ) ) >> 4 ) + n ) if( preCtxState <= 63 ) { pStateIdx = 63 - preCtxState valMPS = 0 } else { pStateIdx = preCtxState - 64 valMPS = 1 } 对每个上下文context,有两个变量pStateIdx 和valMPS,代表的意思分别是位于哪个状态以及MPS的值 |
const int8_t (*tab)[2]; tab指向2元数据[0]为m,[1]为m for( i= 0; i < 1024; i++ ) { int pre = 2*(((tab[i][0] * slice_qp) >>4 ) + tab[i][1]) - 127; pre^= pre>>31; if(pre > 124) pre= 124 + (pre&1);//这两句代码的作用相当于clip3(1,126.x) sl->cabac_state[i] = pre; } 将pStateIdx和valMPS放在一个变量cabac_state里,变量的最低位表示valMPS,高位表示pStateIdx,所以pre在初始化时乘2 Pre*2后,值限制在[2-252],再-127后,限制在[-125,125],将^对负数取反后,成了[124..0,1..125]。 这 |