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 + -
显示快捷键?