static void x264_cabac_mb_intra_chroma_pred_mode( x264_t *h, x264_cabac_t *cb ) { const int i_mode = x264_mb_pred_mode8x8c_fix[ h->mb.i_chroma_pred_mode ]; int ctx = 0; /* No need to test for I4x4 or I_16x16 as cache_save handle that */ if( (h->mb.i_neighbour & MB_LEFT) && h->mb.chroma_pred_mode[h->mb.i_mb_xy - 1] != 0 ) { ctx++; } if( (h->mb.i_neighbour & MB_TOP) && h->mb.chroma_pred_mode[h->mb.i_mb_top_xy] != 0 ) { ctx++; } x264_cabac_encode_decision( cb, 64 + ctx, i_mode > 0 ); if( i_mode > 0 ) { x264_cabac_encode_decision( cb, 64 + 3, i_mode > 1 ); if( i_mode > 1 ) { x264_cabac_encode_decision( cb, 64 + 3, i_mode > 2 ); } } }
static inline void x264_cabac_mb_type_intra( x264_t *h, x264_cabac_t *cb, int i_mb_type, int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 ) { if( i_mb_type == I_4x4 || i_mb_type == I_8x8 ) { x264_cabac_encode_decision( cb, ctx0, 0 ); } else if( i_mb_type == I_PCM ) { x264_cabac_encode_decision( cb, ctx0, 1 ); x264_cabac_encode_terminal( cb, 1 ); x264_cabac_encode_flush( cb ); } else { int i_pred = x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode]; x264_cabac_encode_decision( cb, ctx0, 1 ); x264_cabac_encode_terminal( cb, 0 ); x264_cabac_encode_decision( cb, ctx1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 )); if( h->mb.i_cbp_chroma == 0 ) { x264_cabac_encode_decision( cb, ctx2, 0 ); } else { x264_cabac_encode_decision( cb, ctx2, 1 ); x264_cabac_encode_decision( cb, ctx3, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) ); } x264_cabac_encode_decision( cb, ctx4, ( (i_pred / 2) ? 1 : 0 )); x264_cabac_encode_decision( cb, ctx5, ( (i_pred % 2) ? 1 : 0 )); } }
static inline void x264_cabac_mb_type_intra( x264_t *h, x264_cabac_t *cb, int i_mb_type, int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 ) { if( i_mb_type == I_4x4 || i_mb_type == I_8x8 ) { x264_cabac_encode_decision_noup( cb, ctx0, 0 ); } #if !RDO_SKIP_BS else if( i_mb_type == I_PCM ) { x264_cabac_encode_decision_noup( cb, ctx0, 1 ); x264_cabac_encode_flush( h, cb ); } #endif else { int i_pred = x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode]; x264_cabac_encode_decision_noup( cb, ctx0, 1 ); x264_cabac_encode_terminal( cb ); x264_cabac_encode_decision_noup( cb, ctx1, !!h->mb.i_cbp_luma ); if( h->mb.i_cbp_chroma == 0 ) x264_cabac_encode_decision_noup( cb, ctx2, 0 ); else { x264_cabac_encode_decision( cb, ctx2, 1 ); x264_cabac_encode_decision_noup( cb, ctx3, h->mb.i_cbp_chroma>>1 ); } x264_cabac_encode_decision( cb, ctx4, i_pred>>1 ); x264_cabac_encode_decision_noup( cb, ctx5, i_pred&1 ); } }
static void x264_cabac_mb_intra4x4_pred_mode( x264_cabac_t *cb, int i_pred, int i_mode ) { if( i_pred == i_mode ) { /* b_prev_intra4x4_pred_mode */ x264_cabac_encode_decision( cb, 68, 1 ); } else { /* b_prev_intra4x4_pred_mode */ x264_cabac_encode_decision( cb, 68, 0 ); if( i_mode > i_pred ) { i_mode--; } x264_cabac_encode_decision( cb, 69, (i_mode )&0x01 ); x264_cabac_encode_decision( cb, 69, (i_mode >> 1)&0x01 ); x264_cabac_encode_decision( cb, 69, (i_mode >> 2)&0x01 ); } }
static void x264_cabac_mb_type( x264_t *h, x264_cabac_t *cb ) { const int i_mb_type = h->mb.i_type; if( h->sh.b_mbaff && (!(h->mb.i_mb_y & 1) || IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride])) ) { x264_cabac_encode_decision_noup( cb, 70 + h->mb.cache.i_neighbour_interlaced, h->mb.b_interlaced ); } if( h->sh.i_type == SLICE_TYPE_I ) { int ctx = 0; if( (h->mb.i_neighbour & MB_LEFT) && h->mb.i_mb_type_left != I_4x4 ) ctx++; if( (h->mb.i_neighbour & MB_TOP) && h->mb.i_mb_type_top != I_4x4 ) ctx++; x264_cabac_mb_type_intra( h, cb, i_mb_type, 3+ctx, 3+3, 3+4, 3+5, 3+6, 3+7 ); } else if( h->sh.i_type == SLICE_TYPE_P ) { /* prefix: 14, suffix: 17 */ if( i_mb_type == P_L0 ) { x264_cabac_encode_decision_noup( cb, 14, 0 ); x264_cabac_encode_decision_noup( cb, 15, h->mb.i_partition != D_16x16 ); x264_cabac_encode_decision_noup( cb, 17-(h->mb.i_partition == D_16x16), h->mb.i_partition == D_16x8 ); } else if( i_mb_type == P_8x8 ) { x264_cabac_encode_decision_noup( cb, 14, 0 ); x264_cabac_encode_decision_noup( cb, 15, 0 ); x264_cabac_encode_decision_noup( cb, 16, 1 ); } else /* intra */ { /* prefix */ x264_cabac_encode_decision_noup( cb, 14, 1 ); /* suffix */ x264_cabac_mb_type_intra( h, cb, i_mb_type, 17+0, 17+1, 17+2, 17+2, 17+3, 17+3 ); } } else //if( h->sh.i_type == SLICE_TYPE_B ) { int ctx = 0; if( (h->mb.i_neighbour & MB_LEFT) && h->mb.i_mb_type_left != B_SKIP && h->mb.i_mb_type_left != B_DIRECT ) ctx++; if( (h->mb.i_neighbour & MB_TOP) && h->mb.i_mb_type_top != B_SKIP && h->mb.i_mb_type_top != B_DIRECT ) ctx++; if( i_mb_type == B_DIRECT ) { x264_cabac_encode_decision_noup( cb, 27+ctx, 0 ); return; } x264_cabac_encode_decision_noup( cb, 27+ctx, 1 ); if( i_mb_type == B_8x8 ) { x264_cabac_encode_decision_noup( cb, 27+3, 1 ); x264_cabac_encode_decision_noup( cb, 27+4, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision_noup( cb, 27+5, 1 ); } else if( IS_INTRA( i_mb_type ) ) { /* prefix */ x264_cabac_encode_decision_noup( cb, 27+3, 1 ); x264_cabac_encode_decision_noup( cb, 27+4, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 0 ); x264_cabac_encode_decision( cb, 27+5, 1 ); /* suffix */ x264_cabac_mb_type_intra( h, cb, i_mb_type, 32+0, 32+1, 32+2, 32+2, 32+3, 32+3 ); } else { static const uint8_t i_mb_bits[9*3] = { 0x31, 0x29, 0x4, /* L0 L0 */ 0x35, 0x2d, 0, /* L0 L1 */ 0x43, 0x63, 0, /* L0 BI */ 0x3d, 0x2f, 0, /* L1 L0 */ 0x39, 0x25, 0x6, /* L1 L1 */ 0x53, 0x73, 0, /* L1 BI */ 0x4b, 0x6b, 0, /* BI L0 */ 0x5b, 0x7b, 0, /* BI L1 */ 0x47, 0x67, 0x21 /* BI BI */ }; const int idx = (i_mb_type - B_L0_L0) * 3 + (h->mb.i_partition - D_16x8); int bits = i_mb_bits[idx]; x264_cabac_encode_decision_noup( cb, 27+3, bits&1 ); x264_cabac_encode_decision( cb, 27+5-(bits&1), (bits>>1)&1 ); bits >>= 2; if( bits != 1 ) { x264_cabac_encode_decision( cb, 27+5, bits&1 ); bits >>= 1; x264_cabac_encode_decision( cb, 27+5, bits&1 ); bits >>= 1; x264_cabac_encode_decision( cb, 27+5, bits&1 ); bits >>= 1; if( bits != 1 ) x264_cabac_encode_decision_noup( cb, 27+5, bits&1 ); } } }
static void x264_cabac_mb_type( x264_t *h, x264_cabac_t *cb ) { const int i_mb_type = h->mb.i_type; if( h->sh.b_mbaff && (!(h->mb.i_mb_y & 1) || IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride])) ) { x264_cabac_encode_decision( cb, 70 + h->mb.cache.i_neighbour_interlaced, h->mb.b_interlaced ); } if( h->sh.i_type == SLICE_TYPE_I ) { int ctx = 0; if( h->mb.i_mb_type_left >= 0 && h->mb.i_mb_type_left != I_4x4 ) { ctx++; } if( h->mb.i_mb_type_top >= 0 && h->mb.i_mb_type_top != I_4x4 ) { ctx++; } x264_cabac_mb_type_intra( h, cb, i_mb_type, 3+ctx, 3+3, 3+4, 3+5, 3+6, 3+7 ); } else if( h->sh.i_type == SLICE_TYPE_P ) { /* prefix: 14, suffix: 17 */ if( i_mb_type == P_L0 ) { if( h->mb.i_partition == D_16x16 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 0 ); x264_cabac_encode_decision( cb, 16, 0 ); } else if( h->mb.i_partition == D_16x8 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 1 ); x264_cabac_encode_decision( cb, 17, 1 ); } else if( h->mb.i_partition == D_8x16 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 1 ); x264_cabac_encode_decision( cb, 17, 0 ); } } else if( i_mb_type == P_8x8 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 0 ); x264_cabac_encode_decision( cb, 16, 1 ); } else /* intra */ { /* prefix */ x264_cabac_encode_decision( cb, 14, 1 ); /* suffix */ x264_cabac_mb_type_intra( h, cb, i_mb_type, 17+0, 17+1, 17+2, 17+2, 17+3, 17+3 ); } } else if( h->sh.i_type == SLICE_TYPE_B ) { int ctx = 0; if( h->mb.i_mb_type_left >= 0 && h->mb.i_mb_type_left != B_SKIP && h->mb.i_mb_type_left != B_DIRECT ) { ctx++; } if( h->mb.i_mb_type_top >= 0 && h->mb.i_mb_type_top != B_SKIP && h->mb.i_mb_type_top != B_DIRECT ) { ctx++; } if( i_mb_type == B_DIRECT ) { x264_cabac_encode_decision( cb, 27+ctx, 0 ); } else if( i_mb_type == B_8x8 ) { x264_cabac_encode_decision( cb, 27+ctx, 1 ); x264_cabac_encode_decision( cb, 27+3, 1 ); x264_cabac_encode_decision( cb, 27+4, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); } else if( IS_INTRA( i_mb_type ) ) { /* prefix */ x264_cabac_encode_decision( cb, 27+ctx, 1 ); x264_cabac_encode_decision( cb, 27+3, 1 ); x264_cabac_encode_decision( cb, 27+4, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 0 ); x264_cabac_encode_decision( cb, 27+5, 1 ); /* suffix */ x264_cabac_mb_type_intra( h, cb, i_mb_type, 32+0, 32+1, 32+2, 32+2, 32+3, 32+3 ); } else { static const int i_mb_len[9*3] = { 6, 6, 3, /* L0 L0 */ 6, 6, 0, /* L0 L1 */ 7, 7, 0, /* L0 BI */ 6, 6, 0, /* L1 L0 */ 6, 6, 3, /* L1 L1 */ 7, 7, 0, /* L1 BI */ 7, 7, 0, /* BI L0 */ 7, 7, 0, /* BI L1 */ 7, 7, 6, /* BI BI */ }; static const int i_mb_bits[9*3][7] = { { 1,1,0,0,0,1 }, { 1,1,0,0,1,0, }, { 1,0,0 }, /* L0 L0 */ { 1,1,0,1,0,1 }, { 1,1,0,1,1,0 }, {0}, /* L0 L1 */ { 1,1,1,0,0,0,0 }, { 1,1,1,0,0,0,1 }, {0}, /* L0 BI */ { 1,1,0,1,1,1 }, { 1,1,1,1,1,0 }, {0}, /* L1 L0 */ { 1,1,0,0,1,1 }, { 1,1,0,1,0,0 }, { 1,0,1 }, /* L1 L1 */ { 1,1,1,0,0,1,0 }, { 1,1,1,0,0,1,1 }, {0}, /* L1 BI */ { 1,1,1,0,1,0,0 }, { 1,1,1,0,1,0,1 }, {0}, /* BI L0 */ { 1,1,1,0,1,1,0 }, { 1,1,1,0,1,1,1 }, {0}, /* BI L1 */ { 1,1,1,1,0,0,0 }, { 1,1,1,1,0,0,1 }, { 1,1,0,0,0,0 }, /* BI BI */ }; const int idx = (i_mb_type - B_L0_L0) * 3 + (h->mb.i_partition - D_16x8); int i; x264_cabac_encode_decision( cb, 27+ctx, i_mb_bits[idx][0] ); x264_cabac_encode_decision( cb, 27+3, i_mb_bits[idx][1] ); x264_cabac_encode_decision( cb, 27+5-i_mb_bits[idx][1], i_mb_bits[idx][2] ); for( i = 3; i < i_mb_len[idx]; i++ ) x264_cabac_encode_decision( cb, 27+5, i_mb_bits[idx][i] ); } } else { x264_log(h, X264_LOG_ERROR, "unknown SLICE_TYPE unsupported in x264_macroblock_write_cabac\n" ); } }
static void x264_cabac_mb_type( x264_t *h, x264_cabac_t *cb ) { const int i_mb_type = h->mb.i_type; if( h->sh.i_type == SLICE_TYPE_I ) { int ctx = 0; if( h->mb.i_mb_type_left >= 0 && h->mb.i_mb_type_left != I_4x4 ) { ctx++; } if( h->mb.i_mb_type_top >= 0 && h->mb.i_mb_type_top != I_4x4 ) { ctx++; } x264_cabac_mb_type_intra( h, cb, i_mb_type, 3+ctx, 3+3, 3+4, 3+5, 3+6, 3+7 ); } else if( h->sh.i_type == SLICE_TYPE_P ) { /* prefix: 14, suffix: 17 */ if( i_mb_type == P_L0 ) { if( h->mb.i_partition == D_16x16 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 0 ); x264_cabac_encode_decision( cb, 16, 0 ); } else if( h->mb.i_partition == D_16x8 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 1 ); x264_cabac_encode_decision( cb, 17, 1 ); } else if( h->mb.i_partition == D_8x16 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 1 ); x264_cabac_encode_decision( cb, 17, 0 ); } } else if( i_mb_type == P_8x8 ) { x264_cabac_encode_decision( cb, 14, 0 ); x264_cabac_encode_decision( cb, 15, 0 ); x264_cabac_encode_decision( cb, 16, 1 ); } else /* intra */ { /* prefix */ x264_cabac_encode_decision( cb, 14, 1 ); /* suffix */ x264_cabac_mb_type_intra( h, cb, i_mb_type, 17+0, 17+1, 17+2, 17+2, 17+3, 17+3 ); } } else if( h->sh.i_type == SLICE_TYPE_B ) { int ctx = 0; if( h->mb.i_mb_type_left >= 0 && h->mb.i_mb_type_left != B_SKIP && h->mb.i_mb_type_left != B_DIRECT ) { ctx++; } if( h->mb.i_mb_type_top >= 0 && h->mb.i_mb_type_top != B_SKIP && h->mb.i_mb_type_top != B_DIRECT ) { ctx++; } if( i_mb_type == B_DIRECT ) { x264_cabac_encode_decision( cb, 27+ctx, 0 ); } else if( i_mb_type == B_8x8 ) { x264_cabac_encode_decision( cb, 27+ctx, 1 ); x264_cabac_encode_decision( cb, 27+3, 1 ); x264_cabac_encode_decision( cb, 27+4, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); } else if( IS_INTRA( i_mb_type ) ) { /* prefix */ x264_cabac_encode_decision( cb, 27+ctx, 1 ); x264_cabac_encode_decision( cb, 27+3, 1 ); x264_cabac_encode_decision( cb, 27+4, 1 ); x264_cabac_encode_decision( cb, 27+5, 1 ); x264_cabac_encode_decision( cb, 27+5, 0 ); x264_cabac_encode_decision( cb, 27+5, 1 ); /* suffix */ x264_cabac_mb_type_intra( h, cb, i_mb_type, 32+0, 32+1, 32+2, 32+2, 32+3, 32+3 ); } else { static const int i_mb_len[21] = { 3, 6, 6, /* L0 L0 */ 3, 6, 6, /* L1 L1 */ 6, 7, 7, /* BI BI */ 6, 6, /* L0 L1 */ 6, 6, /* L1 L0 */ 7, 7, /* L0 BI */ 7, 7, /* L1 BI */ 7, 7, /* BI L0 */ 7, 7, /* BI L1 */ }; static const int i_mb_bits[21][7] = { { 1, 0, 0, }, { 1, 1, 0, 0, 0, 1, }, { 1, 1, 0, 0, 1, 0, }, /* L0 L0 */ { 1, 0, 1, }, { 1, 1, 0, 0, 1, 1, }, { 1, 1, 0, 1, 0, 0, }, /* L1 L1 */ { 1, 1, 0, 0, 0, 0 ,}, { 1, 1, 1, 1, 0, 0 , 0 }, { 1, 1, 1, 1, 0, 0 , 1 },/* BI BI */ { 1, 1, 0, 1, 0, 1, }, { 1, 1, 0, 1, 1, 0, }, /* L0 L1 */ { 1, 1, 0, 1, 1, 1, }, { 1, 1, 1, 1, 1, 0, }, /* L1 L0 */ { 1, 1, 1, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0, 0, 1 }, /* L0 BI */ { 1, 1, 1, 0, 0, 1, 0 }, { 1, 1, 1, 0, 0, 1, 1 }, /* L1 BI */ { 1, 1, 1, 0, 1, 0, 0 }, { 1, 1, 1, 0, 1, 0, 1 }, /* BI L0 */ { 1, 1, 1, 0, 1, 1, 0 }, { 1, 1, 1, 0, 1, 1, 1 } /* BI L1 */ }; const int i_partition = h->mb.i_partition; int idx = 0; int i; switch( i_mb_type ) { /* D_16x16, D_16x8, D_8x16 */ case B_BI_BI: idx += 3; case B_L1_L1: idx += 3; case B_L0_L0: if( i_partition == D_16x8 ) idx += 1; else if( i_partition == D_8x16 ) idx += 2; break; /* D_16x8, D_8x16 */ case B_BI_L1: idx += 2; case B_BI_L0: idx += 2; case B_L1_BI: idx += 2; case B_L0_BI: idx += 2; case B_L1_L0: idx += 2; case B_L0_L1: idx += 3*3; if( i_partition == D_8x16 ) idx++; break; default: x264_log(h, X264_LOG_ERROR, "error in B mb type\n" ); return; } x264_cabac_encode_decision( cb, 27+ctx, i_mb_bits[idx][0] ); x264_cabac_encode_decision( cb, 27+3, i_mb_bits[idx][1] ); x264_cabac_encode_decision( cb, 27+(i_mb_bits[idx][1] != 0 ? 4 : 5), i_mb_bits[idx][2] ); for( i = 3; i < i_mb_len[idx]; i++ ) { x264_cabac_encode_decision( cb, 27+5, i_mb_bits[idx][i] ); } } } else { x264_log(h, X264_LOG_ERROR, "unknown SLICE_TYPE unsupported in x264_macroblock_write_cabac\n" ); } }