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.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.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" ); } }