⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec_cabac.c

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 C
📖 第 1 页 / 共 3 页
字号:
			i_coeff ++;
			//--- read last coefficient symbol ---
			if(T264_cabac_decode_decision(&t->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 ++;
	}
	i1 = i_count - 1;
	for( i = i_coeff - 1; i >= 0; i-- )
	{
		int i_prefix;
		int i_ctxIdxInc;

		i_ctxIdxInc = (i_abslevelgt1 != 0 ? 0 : T264_MIN( 4, i_abslevel1 + 1 )) + coeff_abs_level_m1_offset[i_ctxBlockCat];
		sym = T264_cabac_decode_decision(&t->cabac, 227+i_ctxIdxInc);
		if(sym == 0)
		{
			i_abs = 0;
		}
		else
		{
			i_prefix = 1;
			i_ctxIdxInc = 5 + T264_MIN( 4, i_abslevelgt1 ) + coeff_abs_level_m1_offset[i_ctxBlockCat];
			while(i_prefix<14 && T264_cabac_decode_decision(&t->cabac, 227+i_ctxIdxInc)!=0)
			{
				i_prefix ++;
			}
			/* suffix */
			if(i_prefix >= 14)
			{
				int k = 0;
				int i_suffix = 0;
				while(T264_cabac_decode_bypass(&t->cabac) != 0)
				{
					i_suffix += 1<<k;
					k++;
				}
				while(k--)
				{
					i_suffix += T264_cabac_decode_bypass(&t->cabac)<<k;
				}
				i_abs = i_prefix + i_suffix;
			}
			else
			{
				i_abs = i_prefix;
			}
		}
		/* read the sign */
		sym = T264_cabac_decode_bypass(&t->cabac);
		while(i_coeff_sig_map[i1]==0)
		{
			i1 --;
		}
		l[i1] = (sym==0)?(i_abs+1):(-(i_abs+1));
		i1 --;
		if(i_abs == 0)
		{
			i_abslevel1 ++;
		}
		else
		{
			i_abslevelgt1 ++;
		}
	}
	
	if (i_ctxBlockCat==1 || i_ctxBlockCat==2)
	{
		x = luma_inverse_x[i_idx];
		y = luma_inverse_y[i_idx];
		t->mb.nnz[luma_index[i_idx]] = i_coeff;
		t->mb.nnz_ref[NNZ_LUMA + y * 8 + x] = i_coeff;
	}
	else if (i_ctxBlockCat==4 && i_idx<4)
	{
		int idx = i_idx + 16;
		t->mb.nnz[idx] = i_coeff;
		x = (idx - 16) % 2;
		y = (idx - 16) / 2;
		t->mb.nnz_ref[NNZ_CHROMA0 + y * 8 + x] = i_coeff;
	}
	else if (i_ctxBlockCat==4 && i_idx<8)
	{
		int idx = i_idx + 16;
		t->mb.nnz[idx] = i_coeff;
		x = (idx - 20) % 2;
		y = (idx - 20) / 2;
		t->mb.nnz_ref[NNZ_CHROMA1 + y * 8 + x] = i_coeff;
	}
}


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;	
}
static void __inline mb_get_directMB16x16_mv_cabac(T264_t* t)
{
	int				i, j, i8, k;

	//to be revised. This has a problem
	T264_get_direct_mv(t, t->mb.vec);
	for(k=0; k<16; k++)
	{
		i8 = luma_index[k];
		i = luma_inverse_x[k];
		j = luma_inverse_y[k];
		t->mb.vec_ref[VEC_LUMA+(j<<3)+i].vec[0] = t->mb.vec[0][k];
		t->mb.vec_ref[VEC_LUMA+(j<<3)+i].vec[1] = t->mb.vec[1][k];
	}
	i8 = VEC_LUMA;
	for(j=0; j<4; j++)
	{
		for(i=0; i<4; i++)
		{
			t->mb.mvd_ref[0][i8+i][0] = 0;
			t->mb.mvd_ref[0][i8+i][1] = 0;
			t->mb.mvd_ref[1][i8+i][0] = 0;
			t->mb.mvd_ref[1][i8+i][1] = 0;
		}
		i8 += 8;
	}
	memset(&(t->mb.mvd[0][0][0]), 0, sizeof(t->mb.mvd));
}
void T264_macroblock_read_cabac( T264_t *t, bs_t *s )
{
	int i_mb_type;
	const int i_mb_pos_start = BitstreamPos( s );
	int       i_mb_pos_tex;

	int i, j, cbp_dc;

	/* Write the MB type */
	T264_cabac_mb_type( t );

	/* PCM special block type UNTESTED */
	/* no PCM here*/
	i_mb_type = t->mb.mb_mode;
	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 = T264_cabac_mb_intra4x4_pred_mode( t, i_pred);
				t->mb.i4x4_pred_mode_ref[T264_scan8[i]] = i_mode;
				t->mb.mode_i4x4[i] = i_mode;
			}
		}
		T264_cabac_mb_intra8x8_pred_mode( t );
		/* save ref */
		memset(t->mb.submb_part, -1, sizeof(t->mb.submb_part));
		t->mb.mb_part = -1;
#define INITINVALIDVEC(vec) vec.refno = -1; vec.x = vec.y = 0;
		for(i = 0 ; i < 2 ; i ++)
		{
			for(j = 0 ; j < 16 ; j ++)
			{
				INITINVALIDVEC(t->mb.vec[i][j]);
			}
		}
#undef INITINVALIDVEC
	}
	else if( i_mb_type == P_MODE )
	{
		int i_ref_max = t->refl0_num;
		if( t->mb.mb_part == MB_16x16 )
		{
			T264_cabac_mb_ref( t, 0, 0, 4, 4, i_ref_max);
			T264_cabac_mb_mvd( t, 0, 0, 4, 4 );
		}
		else if( t->mb.mb_part == MB_16x8 )
		{
			T264_cabac_mb_ref( t, 0, 0, 4, 2, i_ref_max );
			T264_cabac_mb_ref( t, 0, 8, 4, 2, i_ref_max );
			
			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 )
		{
			T264_cabac_mb_ref( t, 0, 0, 2, 4, i_ref_max );
			T264_cabac_mb_ref( t, 0, 4, 2, 4, i_ref_max );
			
			T264_cabac_mb_mvd( t, 0, 0, 2, 4 );
			T264_cabac_mb_mvd( t, 0, 4, 2, 4 );
		}
		else	/* 8x8 */
		{
			/* sub mb type */
			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] = T264_cabac_mb_sub_p_partition( t );

			/* ref 0 */
			T264_cabac_mb_ref( t, 0, 0, 2, 2, i_ref_max );
			T264_cabac_mb_ref( t, 0, 4, 2, 2, i_ref_max );
			T264_cabac_mb_ref( t, 0, 8, 2, 2, i_ref_max );
			T264_cabac_mb_ref( t, 0, 12, 2, 2, i_ref_max);
			
			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];
			}
#define INITINVALIDVEC(vec) vec.refno = -1; vec.x = vec.y = 0;
			for( i_list = 0; i_list < 2; i_list++ )
			{
				const int i_ref_max = i_list == 0 ? t->refl0_num:t->refl1_num;//t->ps.num_ref_idx_l0_active_minus1+1 : t->ps.num_ref_idx_l1_active_minus1+1;
				if( t->mb.mb_part == MB_16x16 )
				{
					if( b_list[i_list][0] ) 
						T264_cabac_mb_ref( t, i_list, 0, 4, 4, i_ref_max );
					else
					{
						INITINVALIDVEC(t->mb.vec[i_list][0]);
						copy_nvec(&t->mb.vec[i_list][0], &t->mb.vec[i_list][0], 4, 4, 4);
					}
				}
				else if( t->mb.mb_part == MB_16x8 )
				{
					if( b_list[i_list][0] ) 
						T264_cabac_mb_ref( t, i_list, 0, 4, 2, i_ref_max );
					else
					{
						INITINVALIDVEC(t->mb.vec[i_list][0]);
						copy_nvec(&t->mb.vec[i_list][0], &t->mb.vec[i_list][0], 4, 2, 4);
						INITINVALIDVEC(t->mb.vec_ref[VEC_LUMA+8].vec[i_list]);
					}
					if( b_list[i_list][1] ) 
						T264_cabac_mb_ref( t, i_list, 8, 4, 2, i_ref_max );
					else
					{
						INITINVALIDVEC(t->mb.vec[i_list][8]);
						copy_nvec(&t->mb.vec[i_list][8], &t->mb.vec[i_list][8], 4, 2, 4);
					}

				}
				else if( t->mb.mb_part == MB_8x16 )
				{
					if( b_list[i_list][0] )
						T264_cabac_mb_ref( t, i_list, 0, 2, 4, i_ref_max );
					else
					{
						INITINVALIDVEC(t->mb.vec[i_list][0]);
						copy_nvec(&t->mb.vec[i_list][0], &t->mb.vec[i_list][0], 2, 4, 4);
						INITINVALIDVEC(t->mb.vec_ref[VEC_LUMA+1].vec[i_list]);
					}
					if( b_list[i_list][1] )
						T264_cabac_mb_ref( t, i_list, 4, 2, 4, i_ref_max );
					else
					{
						INITINVALIDVEC(t->mb.vec[i_list][2]);
						copy_nvec(&t->mb.vec[i_list][2], &t->mb.vec[i_list][2], 2, 4, 4);
					}
				}
			}
#undef INITINVALIDVEC
			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)
		{
			mb_get_directMB16x16_mv_cabac(t);
		}
		else /* B8x8 */
		{
			/* TODO */
			int i_list;
			/* sub mb type */
			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] = T264_cabac_mb_sub_b_partition( t );

			/* ref */
			for( i_list = 0; i_list < 2; i_list++ )
			{
				int i_ref_max = (i_list==0)?t->refl0_num:t->refl1_num;
				for( i = 0; i < 4; i++ )
				{
					int luma_idx = luma_index[i<<2];
					int sub_part = t->mb.submb_part[luma_idx]-B_DIRECT_8x8;
					if( T264_mb_partition_listX_table[sub_part][i_list] == 1 )
					{
						T264_cabac_mb_ref( t, i_list, 4*i, 2, 2, i_ref_max );
					}
					else
					{
						int i8 = i / 2 * 16 + i % 2 * 2;
#define INITINVALIDVEC(vec) vec.refno = -1; vec.x = vec.y = 0;
						INITINVALIDVEC(t->mb.vec[i_list][luma_idx]);
						copy_nvec(&t->mb.vec[i_list][luma_idx], &t->mb.vec[i_list][luma_idx], 2, 2, 4);
						t->mb.vec_ref[VEC_LUMA + i8 + 0].vec[i_list] =
							t->mb.vec_ref[VEC_LUMA + i8 + 1].vec[i_list] =
							t->mb.vec_ref[VEC_LUMA + i8 + 8].vec[i_list] =
							t->mb.vec_ref[VEC_LUMA + i8 + 9].vec[i_list] = t->mb.vec[i_list][luma_idx];
#undef INITINVALIDVEC
					}
				}
			}
			T264_cabac_mb8x8_mvd( t, 0 );
			T264_cabac_mb8x8_mvd( t, 1 );
			for(i=0; i<4; i++)
			{
				int i_part = luma_index[i<<2];
				int sub_part = t->mb.submb_part[i_part] - B_DIRECT_8x8;
				t->mb.submb_part[i_part] = T264_map_btype_mbpart[sub_part];
			}
		}
	}

	i_mb_pos_tex = BitstreamPos( s );

	if( i_mb_type != I_16x16 )
	{
		T264_cabac_mb_cbp_luma( t );
		T264_cabac_mb_cbp_chroma( t );
	}

	cbp_dc = 0;
	if( t->mb.cbp_y > 0 || t->mb.cbp_c > 0 || i_mb_type == I_16x16 )
	{
		T264_cabac_mb_qp_delta( t );

		/* read residual */
		if( i_mb_type == I_16x16 )
		{
			/* DC Luma */
			int dc_nz;
			block_residual_read_cabac( t, 0, 0, t->mb.dc4x4_z, 16 );
			//for CABAC, record the DC non_zero
			dc_nz = array_non_zero_count(&(t->mb.dc4x4_z[0]), 16);
			if(dc_nz != 0)
			{
				cbp_dc = 1;
			}

			if( t->mb.cbp_y != 0 )
			{
				/* AC Luma */
				for( i = 0; i < 16; i++ )
				{
					block_residual_read_cabac( t, 1, i, &(t->mb.dct_y_z[i][1]), 15 );
					t->mb.dct_y_z[i][0] = t->mb.dc4x4_z[i];
				}
			}
		}
		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_read_cabac( t, 2, i, &(t->mb.dct_y_z[i][0]), 16 );
				}
			}
		}

		if( t->mb.cbp_c&0x03 )    /* Chroma DC residual present */
		{
			int dc_nz0, dc_nz1;
			block_residual_read_cabac( t, 3, 0, &(t->mb.dc2x2_z[0][0]), 4 );
			block_residual_read_cabac( t, 3, 1, &(t->mb.dc2x2_z[1][0]), 4 );
			//for CABAC, chroma dc pattern
			dc_nz0 = array_non_zero_count(t->mb.dc2x2_z[0], 4) > 0;
			dc_nz1 = array_non_zero_count(t->mb.dc2x2_z[1], 4) > 0;
			if(dc_nz0)
				cbp_dc |= 0x02;
			if(dc_nz1)
				cbp_dc |= 0x04;
		}
		if( t->mb.cbp_c&0x02 ) /* Chroma AC residual present */
		{
			for( i = 0; i < 8; i++ )
			{
				block_residual_read_cabac( t, 4, i, &(t->mb.dct_uv_z[i>>2][i&0x03][1]), 15);
				t->mb.dct_uv_z[i>>2][i&0x03][0] = t->mb.dc2x2_z[i>>2][i&0x03];
			}
		}
		else
		{
			for(i = 0 ; i < 4 ; i ++)
			{
				t->mb.dct_uv_z[0][i][0] = t->mb.dc2x2_z[0][i];
				t->mb.dct_uv_z[1][i][0] = t->mb.dc2x2_z[1][i];
			}
		}
	}
	//for CABAC, cbp
	t->mb.cbp = t->mb.cbp_y | (t->mb.cbp_c<<4) | (cbp_dc << 8);
	/*
	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;
	*/
}
int T264dec_mb_read_cabac(T264_t *t)
{
	int skip;
	//for dec CABAC, set MVD to zero
	memset(&(t->mb.mvd[0][0][0]), 0, sizeof(t->mb.mvd));
	t->mb.cbp = t->mb.cbp_y = t->mb.cbp_c = t->mb.mb_qp_delta = 0;
	if (t->slice_type != SLICE_I)
		skip = T264_cabac_dec_mb_skip(t);
	else
		skip = 0;
	if(skip)
	{
		/* skip mb block */
		if (t->slice_type == SLICE_P)
		{
			T264_predict_mv_skip(t, 0, &t->mb.vec[0][0]);
			copy_nvec(&t->mb.vec[0][0], &t->mb.vec[0][0], 4, 4, 4);
			t->mb.mb_mode = P_MODE;     /* decode as MB_16x16 */
			t->mb.mb_part = MB_16x16;
		}
		else if(t->slice_type == SLICE_B)
		{
			mb_get_directMB16x16_mv_cabac(t);
            t->mb.is_copy = 1;
			t->mb.mb_mode = B_MODE;     /* decode as MB_16x16 */                
			t->mb.mb_part = MB_16x16;
		}
		else
		{
			assert(0);
		}				
	}
	else
	{
		T264_macroblock_read_cabac(t, t->bs);					
	}
	return skip;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -