📄 cabac.c.svn-base
字号:
} for( i = i_coeff - 1; i >= 0; i-- ) { /* write coeff_abs - 1 */ const int i_prefix = X264_MIN( i_coeff_abs_m1[i], 14 ); const int i_ctxIdxInc = (i_abslevelgt1 ? 0 : X264_MIN( 4, i_abslevel1 + 1 )) + i_ctx_level; x264_cabac_encode_decision( cb, i_ctxIdxInc, i_prefix != 0 ); if( i_prefix != 0 ) { const int i_ctxIdxInc = 5 + X264_MIN( 4, i_abslevelgt1 ) + i_ctx_level; int j; for( j = 0; j < i_prefix - 1; j++ ) x264_cabac_encode_decision( cb, i_ctxIdxInc, 1 ); if( i_prefix < 14 ) x264_cabac_encode_decision( cb, i_ctxIdxInc, 0 ); else /* suffix */ x264_cabac_encode_ue_bypass( cb, 0, i_coeff_abs_m1[i] - 14 ); i_abslevelgt1++; } else i_abslevel1++; /* write sign */ x264_cabac_encode_bypass( cb, i_coeff_sign[i] ); }}void x264_macroblock_write_cabac( x264_t *h, x264_cabac_t *cb ){ const int i_mb_type = h->mb.i_type; int i_list; int i;#ifndef RDO_SKIP_BS const int i_mb_pos_start = x264_cabac_pos( cb ); int i_mb_pos_tex;#endif /* Write the MB type */ x264_cabac_mb_type( h, cb ); /* PCM special block type UNTESTED */ if( i_mb_type == I_PCM ) {#ifdef RDO_SKIP_BS cb->f8_bits_encoded += (384*8) << 8;#else bs_t *s = cb->s; bs_align_0( s ); /* not sure */ /* Luma */ for( i = 0; i < 16*16; i++ ) { const int x = 16 * h->mb.i_mb_x + (i % 16); const int y = 16 * h->mb.i_mb_y + (i / 16); bs_write( s, 8, h->fenc->plane[0][y*h->mb.pic.i_stride[0]+x] ); } /* Cb */ for( i = 0; i < 8*8; i++ ) { const int x = 8 * h->mb.i_mb_x + (i % 8); const int y = 8 * h->mb.i_mb_y + (i / 8); bs_write( s, 8, h->fenc->plane[1][y*h->mb.pic.i_stride[1]+x] ); } /* Cr */ for( i = 0; i < 8*8; i++ ) { const int x = 8 * h->mb.i_mb_x + (i % 8); const int y = 8 * h->mb.i_mb_y + (i / 8); bs_write( s, 8, h->fenc->plane[2][y*h->mb.pic.i_stride[2]+x] ); } x264_cabac_encode_init( cb, s );#endif return; } if( IS_INTRA( i_mb_type ) ) { if( h->pps->b_transform_8x8_mode && i_mb_type != I_16x16 ) x264_cabac_mb_transform_size( h, cb ); if( i_mb_type != I_16x16 ) { int di = (i_mb_type == I_8x8) ? 4 : 1; for( i = 0; i < 16; i += di ) { const int i_pred = x264_mb_predict_intra4x4_mode( h, i ); const int i_mode = x264_mb_pred_mode4x4_fix( h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] ); x264_cabac_mb_intra4x4_pred_mode( cb, i_pred, i_mode ); } } x264_cabac_mb_intra_chroma_pred_mode( h, cb ); } else if( i_mb_type == P_L0 ) { if( h->mb.i_partition == D_16x16 ) { if( h->sh.i_num_ref_idx_l0_active > 1 ) { x264_cabac_mb_ref( h, cb, 0, 0 ); } x264_cabac_mb_mvd( h, cb, 0, 0, 4, 4 ); } else if( h->mb.i_partition == D_16x8 ) { if( h->sh.i_num_ref_idx_l0_active > 1 ) { x264_cabac_mb_ref( h, cb, 0, 0 ); x264_cabac_mb_ref( h, cb, 0, 8 ); } x264_cabac_mb_mvd( h, cb, 0, 0, 4, 2 ); x264_cabac_mb_mvd( h, cb, 0, 8, 4, 2 ); } else if( h->mb.i_partition == D_8x16 ) { if( h->sh.i_num_ref_idx_l0_active > 1 ) { x264_cabac_mb_ref( h, cb, 0, 0 ); x264_cabac_mb_ref( h, cb, 0, 4 ); } x264_cabac_mb_mvd( h, cb, 0, 0, 2, 4 ); x264_cabac_mb_mvd( h, cb, 0, 4, 2, 4 ); } } else if( i_mb_type == P_8x8 ) { /* sub mb type */ x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[0] ); x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[1] ); x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[2] ); x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[3] ); /* ref 0 */ if( h->sh.i_num_ref_idx_l0_active > 1 ) { x264_cabac_mb_ref( h, cb, 0, 0 ); x264_cabac_mb_ref( h, cb, 0, 4 ); x264_cabac_mb_ref( h, cb, 0, 8 ); x264_cabac_mb_ref( h, cb, 0, 12 ); } for( i = 0; i < 4; i++ ) x264_cabac_mb8x8_mvd( h, cb, 0, i ); } else if( i_mb_type == B_8x8 ) { /* sub mb type */ x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[0] ); x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[1] ); x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[2] ); x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[3] ); /* ref */ for( i_list = 0; i_list < 2; i_list++ ) { if( ( i_list ? h->sh.i_num_ref_idx_l1_active : h->sh.i_num_ref_idx_l0_active ) == 1 ) continue; for( i = 0; i < 4; i++ ) if( x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] ) x264_cabac_mb_ref( h, cb, i_list, 4*i ); } for( i = 0; i < 4; i++ ) x264_cabac_mb8x8_mvd( h, cb, 0, i ); for( i = 0; i < 4; i++ ) x264_cabac_mb8x8_mvd( h, cb, 1, i ); } else if( i_mb_type != B_DIRECT ) { /* All B mode */ int b_list[2][2]; /* init ref list utilisations */ for( i = 0; i < 2; i++ ) { b_list[0][i] = x264_mb_type_list0_table[i_mb_type][i]; b_list[1][i] = x264_mb_type_list1_table[i_mb_type][i]; } for( i_list = 0; i_list < 2; i_list++ ) { const int i_ref_max = i_list == 0 ? h->sh.i_num_ref_idx_l0_active : h->sh.i_num_ref_idx_l1_active; if( i_ref_max > 1 ) { if( h->mb.i_partition == D_16x16 ) { if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 ); } else if( h->mb.i_partition == D_16x8 ) { if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 ); if( b_list[i_list][1] ) x264_cabac_mb_ref( h, cb, i_list, 8 ); } else if( h->mb.i_partition == D_8x16 ) { if( b_list[i_list][0] ) x264_cabac_mb_ref( h, cb, i_list, 0 ); if( b_list[i_list][1] ) x264_cabac_mb_ref( h, cb, i_list, 4 ); } } } for( i_list = 0; i_list < 2; i_list++ ) { if( h->mb.i_partition == D_16x16 ) { if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 4, 4 ); } else if( h->mb.i_partition == D_16x8 ) { if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 4, 2 ); if( b_list[i_list][1] ) x264_cabac_mb_mvd( h, cb, i_list, 8, 4, 2 ); } else if( h->mb.i_partition == D_8x16 ) { if( b_list[i_list][0] ) x264_cabac_mb_mvd( h, cb, i_list, 0, 2, 4 ); if( b_list[i_list][1] ) x264_cabac_mb_mvd( h, cb, i_list, 4, 2, 4 ); } } }#ifndef RDO_SKIP_BS i_mb_pos_tex = x264_cabac_pos( cb ); h->stat.frame.i_hdr_bits += i_mb_pos_tex - i_mb_pos_start;#endif if( i_mb_type != I_16x16 ) { x264_cabac_mb_cbp_luma( h, cb ); x264_cabac_mb_cbp_chroma( h, cb ); } if( h->mb.cache.b_transform_8x8_allowed && h->mb.i_cbp_luma && !IS_INTRA(i_mb_type) ) { x264_cabac_mb_transform_size( h, cb ); } if( h->mb.i_cbp_luma > 0 || h->mb.i_cbp_chroma > 0 || i_mb_type == I_16x16 ) { x264_cabac_mb_qp_delta( h, cb ); /* write residual */ if( i_mb_type == I_16x16 ) { /* DC Luma */ block_residual_write_cabac( h, cb, DCT_LUMA_DC, 0, h->dct.luma16x16_dc, 16 ); /* AC Luma */ if( h->mb.i_cbp_luma != 0 ) for( i = 0; i < 16; i++ ) block_residual_write_cabac( h, cb, DCT_LUMA_AC, i, h->dct.block[i].residual_ac, 15 ); } else if( h->mb.b_transform_8x8 ) { for( i = 0; i < 4; i++ ) if( h->mb.i_cbp_luma & ( 1 << i ) ) block_residual_write_cabac( h, cb, DCT_LUMA_8x8, i, h->dct.luma8x8[i], 64 ); } else { for( i = 0; i < 16; i++ ) if( h->mb.i_cbp_luma & ( 1 << ( i / 4 ) ) ) block_residual_write_cabac( h, cb, DCT_LUMA_4x4, i, h->dct.block[i].luma4x4, 16 ); } if( h->mb.i_cbp_chroma &0x03 ) /* Chroma DC residual present */ { block_residual_write_cabac( h, cb, DCT_CHROMA_DC, 0, h->dct.chroma_dc[0], 4 ); block_residual_write_cabac( h, cb, DCT_CHROMA_DC, 1, h->dct.chroma_dc[1], 4 ); } if( h->mb.i_cbp_chroma&0x02 ) /* Chroma AC residual present */ { for( i = 0; i < 8; i++ ) block_residual_write_cabac( h, cb, DCT_CHROMA_AC, i, h->dct.block[16+i].residual_ac, 15 ); } }#ifndef RDO_SKIP_BS if( IS_INTRA( i_mb_type ) ) h->stat.frame.i_itex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex; else h->stat.frame.i_ptex_bits += x264_cabac_pos( cb ) - i_mb_pos_tex;#endif}#ifdef RDO_SKIP_BS/***************************************************************************** * RD only; doesn't generate a valid bitstream * doesn't write cbp or chroma dc (I don't know how much this matters) * works on all partition sizes except 16x16 * for sub8x8, call once per 8x8 block *****************************************************************************/void x264_partition_size_cabac( x264_t *h, x264_cabac_t *cb, int i8, int i_pixel ){ const int i_mb_type = h->mb.i_type; int j; if( i_mb_type == P_8x8 ) { x264_cabac_mb_sub_p_partition( cb, h->mb.i_sub_partition[i8] ); if( h->sh.i_num_ref_idx_l0_active > 1 ) x264_cabac_mb_ref( h, cb, 0, 4*i8 ); x264_cabac_mb8x8_mvd( h, cb, 0, i8 ); } else if( i_mb_type == P_L0 ) { if( h->sh.i_num_ref_idx_l0_active > 1 ) x264_cabac_mb_ref( h, cb, 0, 4*i8 ); if( h->mb.i_partition == D_16x8 ) x264_cabac_mb_mvd( h, cb, 0, 4*i8, 4, 2 ); else //8x16 x264_cabac_mb_mvd( h, cb, 0, 4*i8, 2, 4 ); } else if( i_mb_type == B_8x8 ) { x264_cabac_mb_sub_b_partition( cb, h->mb.i_sub_partition[i8] ); if( h->sh.i_num_ref_idx_l0_active > 1 && x264_mb_partition_listX_table[0][ h->mb.i_sub_partition[i8] ] ) x264_cabac_mb_ref( h, cb, 0, 4*i8 ); if( h->sh.i_num_ref_idx_l1_active > 1 && x264_mb_partition_listX_table[1][ h->mb.i_sub_partition[i8] ] ) x264_cabac_mb_ref( h, cb, 1, 4*i8 ); x264_cabac_mb8x8_mvd( h, cb, 0, i8 ); x264_cabac_mb8x8_mvd( h, cb, 1, i8 ); } else { x264_log(h, X264_LOG_ERROR, "invalid/unhandled mb_type\n" ); return; } for( j = (i_pixel < PIXEL_8x8); j >= 0; j-- ) { if( h->mb.i_cbp_luma & (1 << i8) ) { if( h->mb.b_transform_8x8 ) block_residual_write_cabac( h, cb, DCT_LUMA_8x8, i8, h->dct.luma8x8[i8], 64 ); else { int i4; for( i4 = 0; i4 < 4; i4++ ) block_residual_write_cabac( h, cb, DCT_LUMA_4x4, i4+i8*4, h->dct.block[i4+i8*4].luma4x4, 16 ); } } block_residual_write_cabac( h, cb, DCT_CHROMA_AC, i8, h->dct.block[16+i8 ].residual_ac, 15 ); block_residual_write_cabac( h, cb, DCT_CHROMA_AC, i8+4, h->dct.block[16+i8+4].residual_ac, 15 ); i8 += x264_pixel_size[i_pixel].h >> 3; }}static void x264_partition_i8x8_size_cabac( x264_t *h, x264_cabac_t *cb, int i8, int i_mode ){ const int i_pred = x264_mb_predict_intra4x4_mode( h, 4*i8 ); i_mode = x264_mb_pred_mode4x4_fix( i_mode ); x264_cabac_mb_intra4x4_pred_mode( cb, i_pred, i_mode ); block_residual_write_cabac( h, cb, DCT_LUMA_8x8, 4*i8, h->dct.luma8x8[i8], 64 );}static void x264_partition_i4x4_size_cabac( x264_t *h, x264_cabac_t *cb, int i4, int i_mode ){ const int i_pred = x264_mb_predict_intra4x4_mode( h, i4 ); i_mode = x264_mb_pred_mode4x4_fix( i_mode ); x264_cabac_mb_intra4x4_pred_mode( cb, i_pred, i_mode ); block_residual_write_cabac( h, cb, DCT_LUMA_4x4, i4, h->dct.block[i4].luma4x4, 16 );}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -