📄 dec_cabac.c
字号:
i_coeff ++;
//--- read last coefficient symbol ---
if(T264_cabac_decode_decision(&t->cabac, 166 + last_significant_coeff_flag_offset[i_ctxBlockCat] + i_ctxIdxInc))
{
for(i++; i<i_count; i++)
i_coeff_sig_map[i] = 0;
}
}
else
{
i_coeff_sig_map[i] = 0;
}
}
//--- last coefficient must be significant if no last symbol was received ---
if (i<i_count)
{
i_coeff_sig_map[i] = 1;
i_coeff ++;
}
i1 = i_count - 1;
for( i = i_coeff - 1; i >= 0; i-- )
{
int i_prefix;
int i_ctxIdxInc;
i_ctxIdxInc = (i_abslevelgt1 != 0 ? 0 : T264_MIN( 4, i_abslevel1 + 1 )) + coeff_abs_level_m1_offset[i_ctxBlockCat];
sym = T264_cabac_decode_decision(&t->cabac, 227+i_ctxIdxInc);
if(sym == 0)
{
i_abs = 0;
}
else
{
i_prefix = 1;
i_ctxIdxInc = 5 + T264_MIN( 4, i_abslevelgt1 ) + coeff_abs_level_m1_offset[i_ctxBlockCat];
while(i_prefix<14 && T264_cabac_decode_decision(&t->cabac, 227+i_ctxIdxInc)!=0)
{
i_prefix ++;
}
/* suffix */
if(i_prefix >= 14)
{
int k = 0;
int i_suffix = 0;
while(T264_cabac_decode_bypass(&t->cabac) != 0)
{
i_suffix += 1<<k;
k++;
}
while(k--)
{
i_suffix += T264_cabac_decode_bypass(&t->cabac)<<k;
}
i_abs = i_prefix + i_suffix;
}
else
{
i_abs = i_prefix;
}
}
/* read the sign */
sym = T264_cabac_decode_bypass(&t->cabac);
while(i_coeff_sig_map[i1]==0)
{
i1 --;
}
l[i1] = (sym==0)?(i_abs+1):(-(i_abs+1));
i1 --;
if(i_abs == 0)
{
i_abslevel1 ++;
}
else
{
i_abslevelgt1 ++;
}
}
if (i_ctxBlockCat==1 || i_ctxBlockCat==2)
{
x = luma_inverse_x[i_idx];
y = luma_inverse_y[i_idx];
t->mb.nnz[luma_index[i_idx]] = i_coeff;
t->mb.nnz_ref[NNZ_LUMA + y * 8 + x] = i_coeff;
}
else if (i_ctxBlockCat==4 && i_idx<4)
{
int idx = i_idx + 16;
t->mb.nnz[idx] = i_coeff;
x = (idx - 16) % 2;
y = (idx - 16) / 2;
t->mb.nnz_ref[NNZ_CHROMA0 + y * 8 + x] = i_coeff;
}
else if (i_ctxBlockCat==4 && i_idx<8)
{
int idx = i_idx + 16;
t->mb.nnz[idx] = i_coeff;
x = (idx - 20) % 2;
y = (idx - 20) / 2;
t->mb.nnz_ref[NNZ_CHROMA1 + y * 8 + x] = i_coeff;
}
}
static int8_t
T264_mb_predict_intra4x4_mode(T264_t *t, int32_t idx)
{
int32_t x, y;
int8_t nA, nB, pred_blk;
x = luma_inverse_x[idx];
y = luma_inverse_y[idx];
nA = t->mb.i4x4_pred_mode_ref[IPM_LUMA + x + y * 8 - 1];
nB = t->mb.i4x4_pred_mode_ref[IPM_LUMA + x + y * 8 - 8];
pred_blk = T264_MIN(nA, nB);
if( pred_blk < 0 )
return Intra_4x4_DC;
return pred_blk;
}
static void __inline mb_get_directMB16x16_mv_cabac(T264_t* t)
{
int i, j, i8, k;
//to be revised. This has a problem
T264_get_direct_mv(t, t->mb.vec);
for(k=0; k<16; k++)
{
i8 = luma_index[k];
i = luma_inverse_x[k];
j = luma_inverse_y[k];
t->mb.vec_ref[VEC_LUMA+(j<<3)+i].vec[0] = t->mb.vec[0][k];
t->mb.vec_ref[VEC_LUMA+(j<<3)+i].vec[1] = t->mb.vec[1][k];
}
i8 = VEC_LUMA;
for(j=0; j<4; j++)
{
for(i=0; i<4; i++)
{
t->mb.mvd_ref[0][i8+i][0] = 0;
t->mb.mvd_ref[0][i8+i][1] = 0;
t->mb.mvd_ref[1][i8+i][0] = 0;
t->mb.mvd_ref[1][i8+i][1] = 0;
}
i8 += 8;
}
memset(&(t->mb.mvd[0][0][0]), 0, sizeof(t->mb.mvd));
}
void T264_macroblock_read_cabac( T264_t *t, bs_t *s )
{
int i_mb_type;
const int i_mb_pos_start = BitstreamPos( s );
int i_mb_pos_tex;
int i, j, cbp_dc;
/* Write the MB type */
T264_cabac_mb_type( t );
/* PCM special block type UNTESTED */
/* no PCM here*/
i_mb_type = t->mb.mb_mode;
if( IS_INTRA( i_mb_type ) )
{
/* Prediction */
if( i_mb_type == I_4x4 )
{
for( i = 0; i < 16; i++ )
{
const int i_pred = T264_mb_predict_intra4x4_mode( t, i );
const int i_mode = T264_cabac_mb_intra4x4_pred_mode( t, i_pred);
t->mb.i4x4_pred_mode_ref[T264_scan8[i]] = i_mode;
t->mb.mode_i4x4[i] = i_mode;
}
}
T264_cabac_mb_intra8x8_pred_mode( t );
/* save ref */
memset(t->mb.submb_part, -1, sizeof(t->mb.submb_part));
t->mb.mb_part = -1;
#define INITINVALIDVEC(vec) vec.refno = -1; vec.x = vec.y = 0;
for(i = 0 ; i < 2 ; i ++)
{
for(j = 0 ; j < 16 ; j ++)
{
INITINVALIDVEC(t->mb.vec[i][j]);
}
}
#undef INITINVALIDVEC
}
else if( i_mb_type == P_MODE )
{
int i_ref_max = t->refl0_num;
if( t->mb.mb_part == MB_16x16 )
{
T264_cabac_mb_ref( t, 0, 0, 4, 4, i_ref_max);
T264_cabac_mb_mvd( t, 0, 0, 4, 4 );
}
else if( t->mb.mb_part == MB_16x8 )
{
T264_cabac_mb_ref( t, 0, 0, 4, 2, i_ref_max );
T264_cabac_mb_ref( t, 0, 8, 4, 2, i_ref_max );
T264_cabac_mb_mvd( t, 0, 0, 4, 2 );
T264_cabac_mb_mvd( t, 0, 8, 4, 2 );
}
else if( t->mb.mb_part == MB_8x16 )
{
T264_cabac_mb_ref( t, 0, 0, 2, 4, i_ref_max );
T264_cabac_mb_ref( t, 0, 4, 2, 4, i_ref_max );
T264_cabac_mb_mvd( t, 0, 0, 2, 4 );
T264_cabac_mb_mvd( t, 0, 4, 2, 4 );
}
else /* 8x8 */
{
/* sub mb type */
t->mb.submb_part[0] = T264_cabac_mb_sub_p_partition( t );
t->mb.submb_part[2] = T264_cabac_mb_sub_p_partition( t );
t->mb.submb_part[8] = T264_cabac_mb_sub_p_partition( t );
t->mb.submb_part[10] = T264_cabac_mb_sub_p_partition( t );
/* ref 0 */
T264_cabac_mb_ref( t, 0, 0, 2, 2, i_ref_max );
T264_cabac_mb_ref( t, 0, 4, 2, 2, i_ref_max );
T264_cabac_mb_ref( t, 0, 8, 2, 2, i_ref_max );
T264_cabac_mb_ref( t, 0, 12, 2, 2, i_ref_max);
for( i = 0; i < 4; i++ )
{
switch( t->mb.submb_part[luma_index[i<<2]] )
{
case MB_8x8:
T264_cabac_mb_mvd( t, 0, 4*i, 2, 2 );
break;
case MB_8x4:
T264_cabac_mb_mvd( t, 0, 4*i+0, 2, 1 );
T264_cabac_mb_mvd( t, 0, 4*i+2, 2, 1 );
break;
case MB_4x8:
T264_cabac_mb_mvd( t, 0, 4*i+0, 1, 2 );
T264_cabac_mb_mvd( t, 0, 4*i+1, 1, 2 );
break;
case MB_4x4:
T264_cabac_mb_mvd( t, 0, 4*i+0, 1, 1 );
T264_cabac_mb_mvd( t, 0, 4*i+1, 1, 1 );
T264_cabac_mb_mvd( t, 0, 4*i+2, 1, 1 );
T264_cabac_mb_mvd( t, 0, 4*i+3, 1, 1 );
break;
}
}
}
}
else if( i_mb_type == B_MODE )
{
if((t->mb.mb_part==MB_16x16&&t->mb.is_copy!=1) || (t->mb.mb_part==MB_16x8) || (t->mb.mb_part==MB_8x16))
{
/* to be changed here*/
/* All B mode */
int i_list;
int b_list[2][2];
const int i_partition = t->mb.mb_part;
int b_part_mode, part_mode0, part_mode1;
static const int b_part_mode_map[3][3] = {
{ B_L0_L0, B_L0_L1, B_L0_BI },
{ B_L1_L0, B_L1_L1, B_L1_BI },
{ B_BI_L0, B_BI_L1, B_BI_BI }
};
switch(t->mb.mb_part)
{
case MB_16x16:
part_mode0 = t->mb.mb_part2[0] - B_L0_16x16;
b_part_mode = b_part_mode_map[part_mode0][part_mode0];
break;
case MB_16x8:
part_mode0 = t->mb.mb_part2[0] - B_L0_16x8;
part_mode1 = t->mb.mb_part2[1] - B_L0_16x8;
b_part_mode = b_part_mode_map[part_mode0][part_mode1];
break;
case MB_8x16:
part_mode0 = t->mb.mb_part2[0] - B_L0_8x16;
part_mode1 = t->mb.mb_part2[1] - B_L0_8x16;
b_part_mode = b_part_mode_map[part_mode0][part_mode1];
break;
}
/* init ref list utilisations */
for( i = 0; i < 2; i++ )
{
b_list[0][i] = T264_mb_type_list0_table[b_part_mode][i];
b_list[1][i] = T264_mb_type_list1_table[b_part_mode][i];
}
#define INITINVALIDVEC(vec) vec.refno = -1; vec.x = vec.y = 0;
for( i_list = 0; i_list < 2; i_list++ )
{
const int i_ref_max = i_list == 0 ? t->refl0_num:t->refl1_num;//t->ps.num_ref_idx_l0_active_minus1+1 : t->ps.num_ref_idx_l1_active_minus1+1;
if( t->mb.mb_part == MB_16x16 )
{
if( b_list[i_list][0] )
T264_cabac_mb_ref( t, i_list, 0, 4, 4, i_ref_max );
else
{
INITINVALIDVEC(t->mb.vec[i_list][0]);
copy_nvec(&t->mb.vec[i_list][0], &t->mb.vec[i_list][0], 4, 4, 4);
}
}
else if( t->mb.mb_part == MB_16x8 )
{
if( b_list[i_list][0] )
T264_cabac_mb_ref( t, i_list, 0, 4, 2, i_ref_max );
else
{
INITINVALIDVEC(t->mb.vec[i_list][0]);
copy_nvec(&t->mb.vec[i_list][0], &t->mb.vec[i_list][0], 4, 2, 4);
INITINVALIDVEC(t->mb.vec_ref[VEC_LUMA+8].vec[i_list]);
}
if( b_list[i_list][1] )
T264_cabac_mb_ref( t, i_list, 8, 4, 2, i_ref_max );
else
{
INITINVALIDVEC(t->mb.vec[i_list][8]);
copy_nvec(&t->mb.vec[i_list][8], &t->mb.vec[i_list][8], 4, 2, 4);
}
}
else if( t->mb.mb_part == MB_8x16 )
{
if( b_list[i_list][0] )
T264_cabac_mb_ref( t, i_list, 0, 2, 4, i_ref_max );
else
{
INITINVALIDVEC(t->mb.vec[i_list][0]);
copy_nvec(&t->mb.vec[i_list][0], &t->mb.vec[i_list][0], 2, 4, 4);
INITINVALIDVEC(t->mb.vec_ref[VEC_LUMA+1].vec[i_list]);
}
if( b_list[i_list][1] )
T264_cabac_mb_ref( t, i_list, 4, 2, 4, i_ref_max );
else
{
INITINVALIDVEC(t->mb.vec[i_list][2]);
copy_nvec(&t->mb.vec[i_list][2], &t->mb.vec[i_list][2], 2, 4, 4);
}
}
}
#undef INITINVALIDVEC
for( i_list = 0; i_list < 2; i_list++ )
{
if( t->mb.mb_part == MB_16x16 )
{
if( b_list[i_list][0] )
T264_cabac_mb_mvd( t, i_list, 0, 4, 4 );
}
else if( t->mb.mb_part == MB_16x8 )
{
if( b_list[i_list][0] )
T264_cabac_mb_mvd( t, i_list, 0, 4, 2 );
if( b_list[i_list][1] )
T264_cabac_mb_mvd( t, i_list, 8, 4, 2 );
}
else if( t->mb.mb_part == MB_8x16 )
{
if( b_list[i_list][0] )
T264_cabac_mb_mvd( t, i_list, 0, 2, 4 );
if( b_list[i_list][1] )
T264_cabac_mb_mvd( t, i_list, 4, 2, 4 );
}
}
}
else if(t->mb.mb_part==MB_16x16 && t->mb.is_copy)
{
mb_get_directMB16x16_mv_cabac(t);
}
else /* B8x8 */
{
/* TODO */
int i_list;
/* sub mb type */
t->mb.submb_part[0] = T264_cabac_mb_sub_b_partition( t );
t->mb.submb_part[2] = T264_cabac_mb_sub_b_partition( t );
t->mb.submb_part[8] = T264_cabac_mb_sub_b_partition( t );
t->mb.submb_part[10] = T264_cabac_mb_sub_b_partition( t );
/* ref */
for( i_list = 0; i_list < 2; i_list++ )
{
int i_ref_max = (i_list==0)?t->refl0_num:t->refl1_num;
for( i = 0; i < 4; i++ )
{
int luma_idx = luma_index[i<<2];
int sub_part = t->mb.submb_part[luma_idx]-B_DIRECT_8x8;
if( T264_mb_partition_listX_table[sub_part][i_list] == 1 )
{
T264_cabac_mb_ref( t, i_list, 4*i, 2, 2, i_ref_max );
}
else
{
int i8 = i / 2 * 16 + i % 2 * 2;
#define INITINVALIDVEC(vec) vec.refno = -1; vec.x = vec.y = 0;
INITINVALIDVEC(t->mb.vec[i_list][luma_idx]);
copy_nvec(&t->mb.vec[i_list][luma_idx], &t->mb.vec[i_list][luma_idx], 2, 2, 4);
t->mb.vec_ref[VEC_LUMA + i8 + 0].vec[i_list] =
t->mb.vec_ref[VEC_LUMA + i8 + 1].vec[i_list] =
t->mb.vec_ref[VEC_LUMA + i8 + 8].vec[i_list] =
t->mb.vec_ref[VEC_LUMA + i8 + 9].vec[i_list] = t->mb.vec[i_list][luma_idx];
#undef INITINVALIDVEC
}
}
}
T264_cabac_mb8x8_mvd( t, 0 );
T264_cabac_mb8x8_mvd( t, 1 );
for(i=0; i<4; i++)
{
int i_part = luma_index[i<<2];
int sub_part = t->mb.submb_part[i_part] - B_DIRECT_8x8;
t->mb.submb_part[i_part] = T264_map_btype_mbpart[sub_part];
}
}
}
i_mb_pos_tex = BitstreamPos( s );
if( i_mb_type != I_16x16 )
{
T264_cabac_mb_cbp_luma( t );
T264_cabac_mb_cbp_chroma( t );
}
cbp_dc = 0;
if( t->mb.cbp_y > 0 || t->mb.cbp_c > 0 || i_mb_type == I_16x16 )
{
T264_cabac_mb_qp_delta( t );
/* read residual */
if( i_mb_type == I_16x16 )
{
/* DC Luma */
int dc_nz;
block_residual_read_cabac( t, 0, 0, t->mb.dc4x4_z, 16 );
//for CABAC, record the DC non_zero
dc_nz = array_non_zero_count(&(t->mb.dc4x4_z[0]), 16);
if(dc_nz != 0)
{
cbp_dc = 1;
}
if( t->mb.cbp_y != 0 )
{
/* AC Luma */
for( i = 0; i < 16; i++ )
{
block_residual_read_cabac( t, 1, i, &(t->mb.dct_y_z[i][1]), 15 );
t->mb.dct_y_z[i][0] = t->mb.dc4x4_z[i];
}
}
}
else
{
if(t->frame_num == 1)
t->frame_num = 1;
for( i = 0; i < 16; i++ )
{
if( t->mb.cbp_y & ( 1 << ( i / 4 ) ) )
{
block_residual_read_cabac( t, 2, i, &(t->mb.dct_y_z[i][0]), 16 );
}
}
}
if( t->mb.cbp_c&0x03 ) /* Chroma DC residual present */
{
int dc_nz0, dc_nz1;
block_residual_read_cabac( t, 3, 0, &(t->mb.dc2x2_z[0][0]), 4 );
block_residual_read_cabac( t, 3, 1, &(t->mb.dc2x2_z[1][0]), 4 );
//for CABAC, chroma dc pattern
dc_nz0 = array_non_zero_count(t->mb.dc2x2_z[0], 4) > 0;
dc_nz1 = array_non_zero_count(t->mb.dc2x2_z[1], 4) > 0;
if(dc_nz0)
cbp_dc |= 0x02;
if(dc_nz1)
cbp_dc |= 0x04;
}
if( t->mb.cbp_c&0x02 ) /* Chroma AC residual present */
{
for( i = 0; i < 8; i++ )
{
block_residual_read_cabac( t, 4, i, &(t->mb.dct_uv_z[i>>2][i&0x03][1]), 15);
t->mb.dct_uv_z[i>>2][i&0x03][0] = t->mb.dc2x2_z[i>>2][i&0x03];
}
}
else
{
for(i = 0 ; i < 4 ; i ++)
{
t->mb.dct_uv_z[0][i][0] = t->mb.dc2x2_z[0][i];
t->mb.dct_uv_z[1][i][0] = t->mb.dc2x2_z[1][i];
}
}
}
//for CABAC, cbp
t->mb.cbp = t->mb.cbp_y | (t->mb.cbp_c<<4) | (cbp_dc << 8);
/*
if( IS_INTRA( i_mb_type ) )
t->stat.frame.i_itex_bits += bs_pos(s) - i_mb_pos_tex;
else
t->stat.frame.i_ptex_bits += bs_pos(s) - i_mb_pos_tex;
*/
}
int T264dec_mb_read_cabac(T264_t *t)
{
int skip;
//for dec CABAC, set MVD to zero
memset(&(t->mb.mvd[0][0][0]), 0, sizeof(t->mb.mvd));
t->mb.cbp = t->mb.cbp_y = t->mb.cbp_c = t->mb.mb_qp_delta = 0;
if (t->slice_type != SLICE_I)
skip = T264_cabac_dec_mb_skip(t);
else
skip = 0;
if(skip)
{
/* skip mb block */
if (t->slice_type == SLICE_P)
{
T264_predict_mv_skip(t, 0, &t->mb.vec[0][0]);
copy_nvec(&t->mb.vec[0][0], &t->mb.vec[0][0], 4, 4, 4);
t->mb.mb_mode = P_MODE; /* decode as MB_16x16 */
t->mb.mb_part = MB_16x16;
}
else if(t->slice_type == SLICE_B)
{
mb_get_directMB16x16_mv_cabac(t);
t->mb.is_copy = 1;
t->mb.mb_mode = B_MODE; /* decode as MB_16x16 */
t->mb.mb_part = MB_16x16;
}
else
{
assert(0);
}
}
else
{
T264_macroblock_read_cabac(t, t->bs);
}
return skip;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -