#include <stdio.h>
#include <string.h>
-#include "../core/common.h"
+#include "common/common.h"
#include "macroblock.h"
static const uint8_t block_idx_x[16] =
{ 5, 7, 13, 15}
};
+static inline void x264_cabac_mb_type_intra( x264_t *h, int i_mb_type,
+ int ctx0, int ctx1, int ctx2, int ctx3, int ctx4, int ctx5 )
+{
+ if( i_mb_type == I_4x4 )
+ {
+ x264_cabac_encode_decision( &h->cabac, ctx0, 0 );
+ }
+ else if( i_mb_type == I_PCM )
+ {
+ x264_cabac_encode_decision( &h->cabac, ctx0, 1 );
+ x264_cabac_encode_terminal( &h->cabac, 1 );
+ }
+ else
+ {
+ x264_cabac_encode_decision( &h->cabac, ctx0, 1 );
+ x264_cabac_encode_terminal( &h->cabac, 0 );
+
+ x264_cabac_encode_decision( &h->cabac, ctx1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
+ if( h->mb.i_cbp_chroma == 0 )
+ {
+ x264_cabac_encode_decision( &h->cabac, ctx2, 0 );
+ }
+ else
+ {
+ x264_cabac_encode_decision( &h->cabac, ctx2, 1 );
+ x264_cabac_encode_decision( &h->cabac, ctx3, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
+ }
+ x264_cabac_encode_decision( &h->cabac, ctx4, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
+ x264_cabac_encode_decision( &h->cabac, ctx5, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
+ }
+}
+
static void x264_cabac_mb_type( x264_t *h )
{
const int i_mb_type = h->mb.i_type;
ctx++;
}
- if( i_mb_type == I_4x4 )
- {
- x264_cabac_encode_decision( &h->cabac, 3 + ctx, 0 );
- }
- else if( i_mb_type == I_PCM )
- {
- x264_cabac_encode_decision( &h->cabac, 3 + ctx, 1 );
- x264_cabac_encode_terminal( &h->cabac, 1 );
- }
- else /* I_16x16 */
- {
- x264_cabac_encode_decision( &h->cabac, 3 + ctx, 1 );
- x264_cabac_encode_terminal( &h->cabac, 0 );
-
- x264_cabac_encode_decision( &h->cabac, 3 + 3, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
- if( h->mb.i_cbp_chroma == 0 )
- {
- x264_cabac_encode_decision( &h->cabac, 3 + 4, 0 );
- }
- else
- {
- x264_cabac_encode_decision( &h->cabac, 3 + 4, 1 );
- x264_cabac_encode_decision( &h->cabac, 3 + 5, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
- }
- x264_cabac_encode_decision( &h->cabac, 3 + 6, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
- x264_cabac_encode_decision( &h->cabac, 3 + 7, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
- }
+ x264_cabac_mb_type_intra( h, i_mb_type, 3+ctx, 3+3, 3+4, 3+5, 3+6, 3+7 );
}
else if( h->sh.i_type == SLICE_TYPE_P )
{
x264_cabac_encode_decision( &h->cabac, 15, 0 );
x264_cabac_encode_decision( &h->cabac, 16, 1 );
}
- else if( i_mb_type == I_4x4 )
- {
- /* prefix */
- x264_cabac_encode_decision( &h->cabac, 14, 1 );
-
- x264_cabac_encode_decision( &h->cabac, 17, 0 );
- }
- else if( i_mb_type == I_PCM )
- {
- /* prefix */
- x264_cabac_encode_decision( &h->cabac, 14, 1 );
-
- x264_cabac_encode_decision( &h->cabac, 17, 1 );
- x264_cabac_encode_terminal( &h->cabac, 1 ); /*ctxIdx == 276 */
- }
- else /* intra 16x16 */
+ else /* intra */
{
/* prefix */
x264_cabac_encode_decision( &h->cabac, 14, 1 );
/* suffix */
- x264_cabac_encode_decision( &h->cabac, 17, 1 );
- x264_cabac_encode_terminal( &h->cabac, 0 ); /*ctxIdx == 276 */
-
- x264_cabac_encode_decision( &h->cabac, 17+1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
- if( h->mb.i_cbp_chroma == 0 )
- {
- x264_cabac_encode_decision( &h->cabac, 17+2, 0 );
- }
- else
- {
- x264_cabac_encode_decision( &h->cabac, 17+2, 1 );
- x264_cabac_encode_decision( &h->cabac, 17+2, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
- }
- x264_cabac_encode_decision( &h->cabac, 17+3, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
- x264_cabac_encode_decision( &h->cabac, 17+3, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
+ x264_cabac_mb_type_intra( h, i_mb_type, 17+0, 17+1, 17+2, 17+2, 17+3, 17+3 );
}
}
else if( h->sh.i_type == SLICE_TYPE_B )
x264_cabac_encode_decision( &h->cabac, 27+5, 0 );
x264_cabac_encode_decision( &h->cabac, 27+5, 1 );
- /* Suffix */
- if( i_mb_type == I_4x4 )
- {
- x264_cabac_encode_decision( &h->cabac, 32, 0 );
- }
- else if( i_mb_type == I_PCM )
- {
- x264_cabac_encode_decision( &h->cabac, 32, 1 );
- x264_cabac_encode_terminal( &h->cabac, 1 );
- }
- else
- {
- x264_cabac_encode_decision( &h->cabac, 32, 1 );
- x264_cabac_encode_terminal( &h->cabac, 0 );
-
- /* TODO */
- x264_cabac_encode_decision( &h->cabac, 32+1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
- if( h->mb.i_cbp_chroma == 0 )
- {
- x264_cabac_encode_decision( &h->cabac, 32+2, 0 );
- }
- else
- {
- x264_cabac_encode_decision( &h->cabac, 32+2, 1 );
- x264_cabac_encode_decision( &h->cabac, 32+2, ( h->mb.i_cbp_chroma == 1 ? 0 : 1 ) );
- }
- x264_cabac_encode_decision( &h->cabac, 32+3, ( (h->mb.i_intra16x16_pred_mode / 2) ? 1 : 0 ));
- x264_cabac_encode_decision( &h->cabac, 32+3, ( (h->mb.i_intra16x16_pred_mode % 2) ? 1 : 0 ));
- }
+ /* suffix */
+ x264_cabac_mb_type_intra( h, i_mb_type, 32+0, 32+1, 32+2, 32+2, 32+3, 32+3 );
}
else
{
idx++;
break;
default:
- fprintf( stderr, "error in B mb type\n" );
+ x264_log(h, X264_LOG_ERROR, "error in B mb type\n" );
return;
}
}
else
{
- fprintf( stderr, "unknown SLICE_TYPE unsupported in x264_macroblock_write_cabac\n" );
+ x264_log(h, X264_LOG_ERROR, "unknown SLICE_TYPE unsupported in x264_macroblock_write_cabac\n" );
}
}
{
x264_cabac_encode_decision( &h->cabac, 36, 1 );
x264_cabac_encode_decision( &h->cabac, 37, 0 );
- x264_cabac_encode_decision( &h->cabac, 38, 0 );
+ x264_cabac_encode_decision( &h->cabac, 39, 0 );
}
else if( i_sub == D_L1_8x8 )
{
x264_cabac_encode_decision( &h->cabac, 36, 1 );
x264_cabac_encode_decision( &h->cabac, 37, 0 );
- x264_cabac_encode_decision( &h->cabac, 38, 1 );
+ x264_cabac_encode_decision( &h->cabac, 39, 1 );
}
else if( i_sub == D_BI_8x8 )
{
int i_ref = h->mb.cache.ref[i_list][i8];
int ctx = 0;
- if( i_refa > 0 )
+ if( i_refa > 0 && !h->mb.cache.skip[i8 - 1])
ctx++;
- if( i_refb > 0 )
+ if( i_refb > 0 && !h->mb.cache.skip[i8 - 8])
ctx += 2;
while( i_ref > 0 )
x264_macroblock_cache_mvd( h, block_idx_x[idx], block_idx_y[idx], width, height, i_list, mdx, mdy );
}
+static inline void x264_cabac_mb8x8_mvd( x264_t *h, int i_list )
+{
+ int i;
+ for( i = 0; i < 4; i++ )
+ {
+ if( !x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
+ {
+ continue;
+ }
+
+ switch( h->mb.i_sub_partition[i] )
+ {
+ case D_L0_8x8:
+ case D_L1_8x8:
+ case D_BI_8x8:
+ x264_cabac_mb_mvd( h, i_list, 4*i, 2, 2 );
+ break;
+ case D_L0_8x4:
+ case D_L1_8x4:
+ case D_BI_8x4:
+ x264_cabac_mb_mvd( h, i_list, 4*i+0, 2, 1 );
+ x264_cabac_mb_mvd( h, i_list, 4*i+2, 2, 1 );
+ break;
+ case D_L0_4x8:
+ case D_L1_4x8:
+ case D_BI_4x8:
+ x264_cabac_mb_mvd( h, i_list, 4*i+0, 1, 2 );
+ x264_cabac_mb_mvd( h, i_list, 4*i+1, 1, 2 );
+ break;
+ case D_L0_4x4:
+ case D_L1_4x4:
+ case D_BI_4x4:
+ x264_cabac_mb_mvd( h, i_list, 4*i+0, 1, 1 );
+ x264_cabac_mb_mvd( h, i_list, 4*i+1, 1, 1 );
+ x264_cabac_mb_mvd( h, i_list, 4*i+2, 1, 1 );
+ x264_cabac_mb_mvd( h, i_list, 4*i+3, 1, 1 );
+ break;
+ }
+ }
+}
+
static int x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx )
{
/* TODO: clean up/optimize */
void x264_macroblock_write_cabac( x264_t *h, bs_t *s )
{
const int i_mb_type = h->mb.i_type;
+ const int i_mb_pos_start = bs_pos( s );
+ int i_mb_pos_tex;
+
+ int i_list;
int i;
/* Write the MB type */
x264_cabac_mb_ref( h, 0, 12 );
}
- for( i = 0; i < 4; i++ )
+ x264_cabac_mb8x8_mvd( h, 0 );
+ }
+ else if( i_mb_type == B_8x8 )
+ {
+ /* sub mb type */
+ x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[0] );
+ x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[1] );
+ x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[2] );
+ x264_cabac_mb_sub_b_partition( h, h->mb.i_sub_partition[3] );
+
+ /* ref */
+ for( i_list = 0; i_list < 2; i_list++ )
{
- switch( h->mb.i_sub_partition[i] )
+ 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++ )
{
- case D_L0_8x8:
- x264_cabac_mb_mvd( h, 0, 4*i, 2, 2 );
- break;
- case D_L0_8x4:
- x264_cabac_mb_mvd( h, 0, 4*i+0, 2, 1 );
- x264_cabac_mb_mvd( h, 0, 4*i+2, 2, 1 );
- break;
- case D_L0_4x8:
- x264_cabac_mb_mvd( h, 0, 4*i+0, 1, 2 );
- x264_cabac_mb_mvd( h, 0, 4*i+1, 1, 2 );
- break;
- case D_L0_4x4:
- x264_cabac_mb_mvd( h, 0, 4*i+0, 1, 1 );
- x264_cabac_mb_mvd( h, 0, 4*i+1, 1, 1 );
- x264_cabac_mb_mvd( h, 0, 4*i+2, 1, 1 );
- x264_cabac_mb_mvd( h, 0, 4*i+3, 1, 1 );
- break;
+ if( x264_mb_partition_listX_table[i_list][ h->mb.i_sub_partition[i] ] )
+ {
+ x264_cabac_mb_ref( h, i_list, 4*i );
+ }
}
}
- }
- else if( i_mb_type == B_8x8 )
- {
- /* TODO */
- fprintf( stderr, "Arggg B_8x8\n" );
- return;
+
+ x264_cabac_mb8x8_mvd( h, 0 );
+ x264_cabac_mb8x8_mvd( h, 1 );
}
else if( i_mb_type != B_DIRECT )
{
/* All B mode */
- int i_list;
int b_list[2][2];
/* init ref list utilisations */
}
}
+ i_mb_pos_tex = bs_pos( s );
+ h->stat.frame.i_hdr_bits += i_mb_pos_tex - i_mb_pos_start;
+
if( i_mb_type != I_16x16 )
{
x264_cabac_mb_cbp_luma( h );
}
}
}
+
+ if( IS_INTRA( i_mb_type ) )
+ h->stat.frame.i_itex_bits += bs_pos(s) - i_mb_pos_tex;
+ else
+ h->stat.frame.i_ptex_bits += bs_pos(s) - i_mb_pos_tex;
}