?? cabac.c
字號:
i_nzb = t->mb.nnz_ref[i8 - 8];
}
}
}
else if( i_cat == 3 )
{
/* no need to test skip/pcm */
if( t->mb.mb_x > 0 )
{
i_mba_xy = t->mb.mb_xy -1;
cbp = mb_ctxs[i_mba_xy].cbp;
if( cbp&0x30 )
{
i_nza = cbp&( 0x02 << ( 8 + i_idx) );
}
}
if( t->mb.mb_y > 0 )
{
i_mbb_xy = t->mb.mb_xy - t->mb_stride;
cbp = mb_ctxs[i_mbb_xy].cbp;
if( cbp&0x30 )
{
i_nzb = cbp&( 0x02 << ( 8 + i_idx) );
}
}
}
else if( i_cat == 4 )
{
int idxc = i_idx% 4;
if( idxc == 1 || idxc == 3 )
i_mba_xy = t->mb.mb_xy;
else if( t->mb.mb_x > 0 )
i_mba_xy = t->mb.mb_xy - 1;
if( idxc == 2 || idxc == 3 )
i_mbb_xy = t->mb.mb_xy;
else if( t->mb.mb_y > 0 )
i_mbb_xy = t->mb.mb_xy - t->mb_stride;
/* no need to test skip/pcm */
if( i_mba_xy >= 0 && (mb_ctxs[i_mba_xy].cbp&0x30) == 0x20 )
{
i_nza = t->mb.nnz_ref[T264_scan8[16+i_idx] - 1];
}
if( i_mbb_xy >= 0 && (mb_ctxs[i_mbb_xy].cbp&0x30) == 0x20 )
{
i_nzb = t->mb.nnz_ref[T264_scan8[16+i_idx] - 8];
}
}
if( ( i_mba_xy < 0 && IS_INTRA( t->mb.mb_mode ) ) || i_nza > 0 )
{
ctx++;
}
if( ( i_mbb_xy < 0 && IS_INTRA( t->mb.mb_mode ) ) || i_nzb > 0 )
{
ctx += 2;
}
return 4 * i_cat + ctx;
}
static void block_residual_write_cabac( T264_t *t, int i_ctxBlockCat, int i_idx, int16_t *l, int i_count )
{
static const int significant_coeff_flag_offset[5] = { 0, 15, 29, 44, 47 };
static const int last_significant_coeff_flag_offset[5] = { 0, 15, 29, 44, 47 };
static const int coeff_abs_level_m1_offset[5] = { 0, 10, 20, 30, 39 };
int i_coeff_abs_m1[16];
int i_coeff_sign[16];
int i_coeff = 0;
int i_last = 0;
int i_abslevel1 = 0;
int i_abslevelgt1 = 0;
int i;
/* i_ctxBlockCat: 0-> DC 16x16 i_idx = 0
* 1-> AC 16x16 i_idx = luma4x4idx
* 2-> Luma4x4 i_idx = luma4x4idx
* 3-> DC Chroma i_idx = iCbCr
* 4-> AC Chroma i_idx = 4 * iCbCr + chroma4x4idx
*/
//fprintf( stderr, "l[] = " );
for( i = 0; i < i_count; i++ )
{
//fprintf( stderr, "%d ", l[i] );
if( l[i] != 0 )
{
i_coeff_abs_m1[i_coeff] = abs( l[i] ) - 1;
i_coeff_sign[i_coeff] = ( l[i] < 0 ? 1 : 0);
i_coeff++;
i_last = i;
}
}
//fprintf( stderr, "\n" );
if( i_coeff == 0 )
{
/* codec block flag */
T264_cabac_encode_decision( &t->cabac, 85 + T264_cabac_mb_cbf_ctxidxinc( t, i_ctxBlockCat, i_idx ), 0 );
return;
}
/* block coded */
T264_cabac_encode_decision( &t->cabac, 85 + T264_cabac_mb_cbf_ctxidxinc( t, i_ctxBlockCat, i_idx ), 1 );
for( i = 0; i < i_count - 1; i++ )
{
int i_ctxIdxInc;
i_ctxIdxInc = T264_MIN( i, i_count - 2 );
if( l[i] != 0 )
{
T264_cabac_encode_decision( &t->cabac, 105 + significant_coeff_flag_offset[i_ctxBlockCat] + i_ctxIdxInc, 1 );
T264_cabac_encode_decision( &t->cabac, 166 + last_significant_coeff_flag_offset[i_ctxBlockCat] + i_ctxIdxInc, i == i_last ? 1 : 0 );
}
else
{
T264_cabac_encode_decision( &t->cabac, 105 + significant_coeff_flag_offset[i_ctxBlockCat] + i_ctxIdxInc, 0 );
}
if( i == i_last )
{
break;
}
}
for( i = i_coeff - 1; i >= 0; i-- )
{
int i_prefix;
int i_ctxIdxInc;
/* write coeff_abs - 1 */
/* prefix */
i_prefix = T264_MIN( i_coeff_abs_m1[i], 14 );
i_ctxIdxInc = (i_abslevelgt1 != 0 ? 0 : T264_MIN( 4, i_abslevel1 + 1 )) + coeff_abs_level_m1_offset[i_ctxBlockCat];
if( i_prefix == 0 )
{
T264_cabac_encode_decision( &t->cabac, 227 + i_ctxIdxInc, 0 );
}
else
{
int j;
T264_cabac_encode_decision( &t->cabac, 227 + i_ctxIdxInc, 1 );
i_ctxIdxInc = 5 + T264_MIN( 4, i_abslevelgt1 ) + coeff_abs_level_m1_offset[i_ctxBlockCat];
for( j = 0; j < i_prefix - 1; j++ )
{
T264_cabac_encode_decision( &t->cabac, 227 + i_ctxIdxInc, 1 );
}
if( i_prefix < 14 )
{
T264_cabac_encode_decision( &t->cabac, 227 + i_ctxIdxInc, 0 );
}
}
/* suffix */
if( i_coeff_abs_m1[i] >= 14 )
{
int k = 0;
int i_suffix = i_coeff_abs_m1[i] - 14;
while( i_suffix >= (1<<k) )
{
T264_cabac_encode_bypass( &t->cabac, 1 );
i_suffix -= 1 << k;
k++;
}
T264_cabac_encode_bypass( &t->cabac, 0 );
while( k-- )
{
T264_cabac_encode_bypass( &t->cabac, (i_suffix >> k)&0x01 );
}
}
/* write sign */
T264_cabac_encode_bypass( &t->cabac, i_coeff_sign[i] );
if( i_coeff_abs_m1[i] == 0 )
{
i_abslevel1++;
}
else
{
i_abslevelgt1++;
}
}
}
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;
}
void T264_macroblock_write_cabac( T264_t *t, bs_t *s )
{
const int i_mb_type = t->mb.mb_mode;
const int i_mb_pos_start = BitstreamPos( s );
int i_mb_pos_tex;
int i;
/* Write the MB type */
T264_cabac_mb_type( t );
/* PCM special block type UNTESTED */
/* no PCM here*/
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 = t->mb.i4x4_pred_mode_ref[T264_scan8[i]];
T264_cabac_mb_intra4x4_pred_mode( t, i_pred, i_mode );
}
}
T264_cabac_mb_intra8x8_pred_mode( t );
}
else if( i_mb_type == P_MODE )
{
if( t->mb.mb_part == MB_16x16 )
{
if( t->ps.num_ref_idx_l0_active_minus1 > 0 )
{
T264_cabac_mb_ref( t, 0, 0 );
}
T264_cabac_mb_mvd( t, 0, 0, 4, 4 );
}
else if( t->mb.mb_part == MB_16x8 )
{
if( t->ps.num_ref_idx_l0_active_minus1 > 0 )
{
T264_cabac_mb_ref( t, 0, 0 );
T264_cabac_mb_ref( t, 0, 8 );
}
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 )
{
if( t->ps.num_ref_idx_l0_active_minus1 > 0 )
{
T264_cabac_mb_ref( t, 0, 0 );
T264_cabac_mb_ref( t, 0, 4 );
}
T264_cabac_mb_mvd( t, 0, 0, 2, 4 );
T264_cabac_mb_mvd( t, 0, 4, 2, 4 );
}
else /* 8x8 */
{
/* sub mb type */
T264_cabac_mb_sub_p_partition( t, 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] );
/* ref 0 */
if( t->ps.num_ref_idx_l0_active_minus1 > 0 )
{
T264_cabac_mb_ref( t, 0, 0 );
T264_cabac_mb_ref( t, 0, 4 );
T264_cabac_mb_ref( t, 0, 8 );
T264_cabac_mb_ref( t, 0, 12 );
}
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];
}
for( i_list = 0; i_list < 2; i_list++ )
{
const int i_ref_max = i_list == 0 ? t->ps.num_ref_idx_l0_active_minus1+1 : t->ps.num_ref_idx_l1_active_minus1+1;
if( i_ref_max > 1 )
{
if( t->mb.mb_part == MB_16x16 )
{
if( b_list[i_list][0] ) T264_cabac_mb_ref( t, i_list, 0 );
}
else if( t->mb.mb_part == MB_16x8 )
{
if( b_list[i_list][0] ) T264_cabac_mb_ref( t, i_list, 0 );
if( b_list[i_list][1] ) T264_cabac_mb_ref( t, i_list, 8 );
}
else if( t->mb.mb_part == MB_8x16 )
{
if( b_list[i_list][0] ) T264_cabac_mb_ref( t, i_list, 0 );
if( b_list[i_list][1] ) T264_cabac_mb_ref( t, i_list, 4 );
}
}
}
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)
{
}
else /* B8x8 */
{
/* TODO */
int i_list;
/* sub mb type */
T264_cabac_mb_sub_b_partition( t, 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] );
/* ref */
for( i_list = 0; i_list < 2; i_list++ )
{
if( ( i_list ? t->ps.num_ref_idx_l1_active_minus1 : t->ps.num_ref_idx_l0_active_minus1 ) == 0 )
continue;
for( i = 0; i < 4; i++ )
{
int sub_part = t->mb.submb_part[luma_index[i<<2]]-B_DIRECT_8x8;
if( T264_mb_partition_listX_table[sub_part][i_list] == 1 )
{
T264_cabac_mb_ref( t, i_list, 4*i );
}
}
}
T264_cabac_mb8x8_mvd( t, 0 );
T264_cabac_mb8x8_mvd( t, 1 );
}
}
i_mb_pos_tex = BitstreamPos( s );
if( i_mb_type != I_16x16 )
{
T264_cabac_mb_cbp_luma( t );
T264_cabac_mb_cbp_chroma( t );
}
if( t->mb.cbp_y > 0 || t->mb.cbp_c > 0 || i_mb_type == I_16x16 )
{
T264_cabac_mb_qp_delta( t );
/* write residual */
if( i_mb_type == I_16x16 )
{
/* DC Luma */
block_residual_write_cabac( t, 0, 0, t->mb.dc4x4_z, 16 );
if( t->mb.cbp_y != 0 )
{
/* AC Luma */
for( i = 0; i < 16; i++ )
{
block_residual_write_cabac( t, 1, i, &(t->mb.dct_y_z[i][1]), 15 );
}
}
}
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_write_cabac( t, 2, i, &(t->mb.dct_y_z[i][0]), 16 );
}
}
}
if( t->mb.cbp_c&0x03 ) /* Chroma DC residual present */
{
block_residual_write_cabac( t, 3, 0, &(t->mb.dc2x2_z[0][0]), 4 );
block_residual_write_cabac( t, 3, 1, &(t->mb.dc2x2_z[1][0]), 4 );
}
if( t->mb.cbp_c&0x02 ) /* Chroma AC residual present */
{
for( i = 0; i < 8; i++ )
{
block_residual_write_cabac( t, 4, i, &(t->mb.dct_uv_z[i>>2][i&0x03][1]), 15);
}
}
}
/*
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;
*/
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -