macroblock1.c
来自「另一个版本的x264的decoder」· C语言 代码 · 共 2,481 行 · 第 1/5 页
C
2,481 行
if( h->mb.i_mb_x > 0 && h->mb.chroma_pred_mode[h->mb.i_mb_xy - 1] != 0 ) { ctx++; } if( h->mb.i_mb_y > 0 && h->mb.chroma_pred_mode[h->mb.i_mb_xy - h->mb.i_mb_stride] != 0 ) { ctx++; } if( x264_cabac_decode_decision( &h->cabac, 64 + ctx ) == 0 ) return 0; else if( x264_cabac_decode_decision( &h->cabac, 64 + 3 ) == 0 ) return 1; else if( x264_cabac_decode_decision( &h->cabac, 64 + 3 ) == 0 ) return 2; else return 3;}static int x264_cabac_decode_mb_cbp_luma( x264_t *h ){ int cbp = 0; int i8x8; for( i8x8 = 0; i8x8 < 4; i8x8++ ) { int cbp_a = -1; int cbp_b = -1; int x, y; int ctx = 0; int i_mba_xy = -1; int i_mbb_xy = -1; x = block_idx_x[4*i8x8]; y = block_idx_y[4*i8x8]; if( x > 0 ) { cbp_a = cbp; i_mba_xy = h->mb.i_mb_xy; } else if( h->mb.i_mb_x > 0) { cbp_a = h->mb.cbp[h->mb.i_mb_xy - 1]; i_mba_xy = h->mb.i_mb_xy - 1; } if( y > 0 ) { cbp_b = cbp; i_mbb_xy = h->mb.i_mb_xy; } else if( h->mb.i_mb_y > 0) { cbp_b = h->mb.cbp[h->mb.i_mb_xy - h->mb.i_mb_stride]; i_mbb_xy = h->mb.i_mb_xy - h->mb.i_mb_stride; } /* No need to test for skip as we put 0 for skip block */ /* No need to test for IPCM as we put 1 for IPCM block */ if( i_mba_xy >= 0 ) { const int i8x8a = block_idx_xy[(x-1)&0x03][y]/4; if( ((cbp_a >> i8x8a)&0x01) == 0 ) ctx++; } if( i_mbb_xy >= 0 ) { const int i8x8b = block_idx_xy[x][(y-1)&0x03]/4; if( ((cbp_b >> i8x8b)&0x01) == 0 ) ctx += 2; } if( x264_cabac_decode_decision( &h->cabac, 73 + ctx ) ) { cbp |= 1 << i8x8; } } return cbp;}static int x264_cabac_decode_mb_cbp_chroma( x264_t *h ){ int cbp_a = -1; int cbp_b = -1; int ctx; /* No need to test for SKIP/PCM */ if( h->mb.i_mb_x > 0 ) { cbp_a = (h->mb.cbp[h->mb.i_mb_xy - 1] >> 4)&0x3; } if( h->mb.i_mb_y > 0 ) { cbp_b = (h->mb.cbp[h->mb.i_mb_xy - h->mb.i_mb_stride] >> 4)&0x3; } ctx = 0; if( cbp_a > 0 ) ctx++; if( cbp_b > 0 ) ctx += 2; if( x264_cabac_decode_decision( &h->cabac, 77 + ctx ) == 0 ) return 0; ctx = 4; if( cbp_a == 2 ) ctx++; if( cbp_b == 2 ) ctx += 2; return (1 + x264_cabac_decode_decision( &h->cabac, 77 + ctx ));}static int x264_cabac_decode_mb_qp_delta( x264_t *h ){ int i_mbn_xy = h->mb.i_mb_xy - 1; // int i_dqp = h->mb.qp[h->mb.i_mb_xy] - h->mb.i_last_qp; int val = 0;//= i_dqp <= 0 ? (-2*i_dqp) : (2*i_dqp - 1); int ctx = 0; //printf("mb.i_mb_xy %d",h->mb.i_mb_xy ); /* No need to test for PCM / SKIP */ if( i_mbn_xy >= 0 && h->mb.i_last_dqp != 0 && ( h->mb.type[i_mbn_xy] == I_16x16 || (h->mb.cbp[i_mbn_xy]&0x3f) ) ) ctx = 1; while( x264_cabac_decode_decision( &h->cabac, 60 + ctx ) ) { if( ctx < 2 ) ctx = 2; else ctx = 3; val++; if(val > 52) //prevent infinite loop { printf("\n error in decoding mb_qb_delta\n"); return 0; } } if( val&0x01 ) return (val + 1)/2; else return - val /2;}static int x264_cabac_mb_cbf_ctxidxinc( x264_t *h, int i_cat, int i_idx ){ /* TODO: clean up/optimize */ int i_mba_xy = -1; int i_mbb_xy = -1; int i_nza = -1; int i_nzb = -1; int ctx = 0; if( i_cat == 0 ) { if( h->mb.i_mb_x > 0 ) { i_mba_xy = h->mb.i_mb_xy -1; if( h->mb.type[i_mba_xy] == I_16x16 ) { i_nza = h->mb.cbp[i_mba_xy]&0x100; } } if( h->mb.i_mb_y > 0 ) { i_mbb_xy = h->mb.i_mb_xy - h->mb.i_mb_stride; if( h->mb.type[i_mbb_xy] == I_16x16 ) { i_nzb = h->mb.cbp[i_mbb_xy]&0x100; } } } else if( i_cat == 1 || i_cat == 2 ) { int x = block_idx_x[i_idx]; int y = block_idx_y[i_idx]; int cbp_ya, cbp_yb; if( x > 0 ) { i_mba_xy = h->mb.i_mb_xy; cbp_ya =h->mb.i_cbp_luma; } else if( h->mb.i_mb_x > 0 ) { i_mba_xy = h->mb.i_mb_xy -1; cbp_ya =h->mb.cbp[i_mba_xy]; } if( y > 0 ) { i_mbb_xy = h->mb.i_mb_xy; cbp_yb =h->mb.i_cbp_luma; } else if( h->mb.i_mb_y > 0 ) { i_mbb_xy= h->mb.i_mb_xy - h->mb.i_mb_stride; cbp_yb= h->mb.cbp[i_mbb_xy]; } /* no need to test for skip/pcm */ if( i_mba_xy >= 0 ) { const int i8x8a = block_idx_xy[(x-1)&0x03][y]/4; if( (cbp_ya&0x0f)>> i8x8a ) { i_nza = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 1]; } } if( i_mbb_xy >= 0 ) { const int i8x8b = block_idx_xy[x][(y-1)&0x03]/4; if( (cbp_yb&0x0f)>> i8x8b ) { i_nzb = h->mb.cache.non_zero_count[x264_scan8[i_idx] - 8]; } } } else if( i_cat == 3 ) { /* no need to test skip/pcm */ if( h->mb.i_mb_x > 0 ) { i_mba_xy = h->mb.i_mb_xy -1; if( h->mb.cbp[i_mba_xy]&0x30 ) { i_nza = h->mb.cbp[i_mba_xy]&( 0x02 << ( 8 + i_idx) ); } } if( h->mb.i_mb_y > 0 ) { i_mbb_xy = h->mb.i_mb_xy - h->mb.i_mb_stride; if( h->mb.cbp[i_mbb_xy]&0x30 ) { i_nzb = h->mb.cbp[i_mbb_xy]&( 0x02 << ( 8 + i_idx) ); } } } else if( i_cat == 4 ) { int idxc = i_idx% 4; if( idxc == 1 || idxc == 3 ) i_mba_xy = h->mb.i_mb_xy; else if( h->mb.i_mb_x > 0 ) i_mba_xy = h->mb.i_mb_xy - 1; if( idxc == 2 || idxc == 3 ) i_mbb_xy = h->mb.i_mb_xy; else if( h->mb.i_mb_y > 0 ) i_mbb_xy = h->mb.i_mb_xy - h->mb.i_mb_stride; /* no need to test skip/pcm */ if( i_mba_xy >= 0 && (h->mb.cbp[i_mba_xy]&0x30) == 0x20 ) { i_nza = h->mb.cache.non_zero_count[x264_scan8[16+i_idx] - 1]; } if( i_mbb_xy >= 0 && (h->mb.cbp[i_mbb_xy]&0x30) == 0x20 ) { i_nzb = h->mb.cache.non_zero_count[x264_scan8[16+i_idx] - 8]; } } if( ( i_mba_xy < 0 && IS_INTRA( h->mb.i_type ) ) || i_nza > 0 ) { ctx++; } if( ( i_mbb_xy < 0 && IS_INTRA( h->mb.i_type ) ) || i_nzb > 0 ) { ctx += 2; } return 4 * i_cat + ctx; }static void block_residual_read_cabac( x264_t *h, int i_ctxBlockCat, int i_idx, int *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_sig_map[16]; int i_coeff = 0; int i_last = 0; int i_abslevel1 = 0; int i_abslevelgt1 = 0; int i, i1, sym; int i_abs = 0;// int tmp[i_count]; /* 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 */ //memset(l, 0, sizeof(int)*i_count); sym = x264_cabac_decode_decision( &h->cabac, 85 + x264_cabac_mb_cbf_ctxidxinc( h, i_ctxBlockCat, i_idx ) ); if( sym == 0 ) { //the block is not coded if( i_ctxBlockCat == 1 || i_ctxBlockCat == 2 ) h->mb.cache.non_zero_count[x264_scan8[i_idx]] = 0; else if( i_ctxBlockCat == 4 ) h->mb.cache.non_zero_count[x264_scan8[16+i_idx]] = 0; return ; }// printf(" \nafter cbp %d",*h->cabac.s->p);// printf(" \nafter cbp %d",h->cabac.s->i_left); for( i = 0 ; i < i_count-1; i++ ) { int i_ctxIdxInc; i_ctxIdxInc = X264_MIN( i, i_count - 2 ); sym = x264_cabac_decode_decision( &h->cabac, 105 + significant_coeff_flag_offset[i_ctxBlockCat] + i_ctxIdxInc ); if( sym != 0 ) { i_coeff_sig_map[i] = 1; i_coeff ++; //--- read last coefficient symbol --- if(x264_cabac_decode_decision(&h->cabac, 166 + last_significant_coeff_flag_offset[i_ctxBlockCat] + i_ctxIdxInc) ) { for( i++; i < i_count; i++ ) i_coeff_sig_map[i] = 0; } } else { i_coeff_sig_map[i] = 0; } } //--- last coefficient must be significant if no last symbol was received --- if ( i < i_count ) { i_coeff_sig_map[i] = 1; i_coeff++; } if( i_ctxBlockCat == 1|| i_ctxBlockCat == 2 ) h->mb.cache.non_zero_count[x264_scan8[i_idx]] = i_coeff; else if( i_ctxBlockCat == 4 ) h->mb.cache.non_zero_count[x264_scan8[16+i_idx]] = i_coeff;// printf(" \nafter sig flag%d",*h->cabac.s->p);// printf(" \nafter sig flag%d",h->cabac.s->i_left); i1 = i_count - 1; for( i = i_coeff - 1; i >= 0; i-- ) { int i_prefix = 0; int i_ctxIdxInc; i_ctxIdxInc = (i_abslevelgt1 != 0 ? 0 : X264_MIN( 4, i_abslevel1 + 1 )) + coeff_abs_level_m1_offset[i_ctxBlockCat]; sym = x264_cabac_decode_decision( &h->cabac, 227 + i_ctxIdxInc ); if( sym == 0 ) { i_abs = 0; i_prefix = 0; } else { i_prefix = 1; i_ctxIdxInc = 5 + X264_MIN( 4, i_abslevelgt1 ) + coeff_abs_level_m1_offset[i_ctxBlockCat]; while( i_prefix<14 && x264_cabac_decode_decision(&h->cabac, 227 + i_ctxIdxInc) ) { i_prefix ++; } /* suffix */ if( i_prefix >= 14 ) { int k = 0; int i_suffix = 0; while( x264_cabac_decode_bypass( &h->cabac ) ) { i_suffix += 1<<k; k++; } while( k-- ) { i_suffix += x264_cabac_decode_bypass( &h->cabac )<<k; } i_abs = i_prefix + i_suffix; } else { i_abs = i_prefix; } } /* read the sign */ sym = x264_cabac_decode_bypass( &h->cabac ); while( i_coeff_sig_map[i1] == 0 ) { i1 --; } l[i1] = (sym==0)?(i_abs+1):(-(i_abs+1)); /*if( i_ctxBlockCat==0 || i_ctxBlockCat==3) { printf(" \ni_ctxBlockCat %d", i_ctxBlockCat); printf("\n %d",l[i1]); }*/ i1 --; if( i_abs == 0 ) { i_abslevel1 ++; } else { i_abslevelgt1 ++; } } }int x264_cabac_dec_mb_skip( x264_t *h){ int b_skip = 0; int ctx = 0; if( h->mb.i_mb_x > 0 && !IS_SKIP( h->mb.type[h->mb.i_mb_xy -1]) ) { ctx++; } if( h->mb.i_mb_y > 0 && !IS_SKIP( h->mb.type[h->mb.i_mb_xy -h->mb.i_mb_stride]) ) { ctx++; } if( h->sh.i_type == SLICE_TYPE_P ) b_skip = x264_cabac_decode_decision(&h->cabac, 11+ctx); else /* SLICE_TYPE_B */ b_skip = x264_cabac_decode_decision(&h->cabac, 24+ctx); return b_skip;}int x264_macroblock_read_cabac( x264_t *h, bs_t *s ){ int i_mb_i_offset; int i_mb_p_offset;// int b_sub_ref0 = 0; int i_cbp_dc = 0; int i_type; int i,j;#ifdef PROFILE int64_t count; h->type_cycles = 0; h->residual_cycles = 0; count = x264_get_ts();#endif /* read the mb type */ switch( h->sh.i_type ) { case SLICE_TYPE_I: i_mb_p_offset = 0; /* shut up gcc */ i_mb_i_offset = 0; break; case SLICE_TYPE_P: i_mb_p_offset = 0; i_mb_i_offset = 5; break; case SLICE_TYPE_B: i_mb_p_offset = 23; i_mb_i_offset = 23; break; default: fprintf( stderr, "internal error or slice unsupported\n" ); return -1; } printf(" \n\nbefore mb_type %d %d",*h->cabac.s->p,h->cabac.s->i_left); i_type = x264_cabac_decode_mb_type( h ); //x264_log(h, X264_LOG_DEBUG, "mb_type %d\n", i_type ); printf("\nmb_type %d", i_type ); printf(" \nafter mb_type %d %d",*h->cabac.s->p,h->cabac.s->i_left); if( i_type < i_mb_i_offset ) { if( i_type < i_mb_p_offset ) { h->mb.i_partition = x264_b_mb_type_info[i_type].partition;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?