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

📄 bitstream.cpp

📁 一个优化的H.263解码器,性能达到商用级
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					val = 256 - level;
				else
					val = level;

				if (level == 128 && modified_quantization_mode)
				{
					level = store_code[coeff_ind].extended_level;
					level = (level >> 6 & 0x001F) | level << 5;
					/* correctly set the sign */
					level = (level << (sizeof (int) * 8 - 11)) >> (sizeof (int) * 8 - 11);
					if (level >= 0)
						sign = 0;
					else
					sign = 1;
					val = abs (level);
				}
			} 
			else
			{
				sign = store_code[coeff_ind].sign;
				i += run;
				val = level;
			}
			coeff_ind += 1;
		} 
		else
		{
			code = showbits (12);
			if ((advanced_intra_coding) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q))
			{
				if (code >= 512)
					tab = &INTRA_DCT3Dtab0[(code >> 5) - 16];
				else if (code >= 128)
					tab = &INTRA_DCT3Dtab1[(code >> 2) - 32];
				else if (code >= 8)
					tab = &INTRA_DCT3Dtab2[(code >> 0) - 8];
				else
				{
					fault = 1;
					return;
				}
				run = (tab->val >> 6) & 63;
				level = tab->val & 63;
				last = (tab->val >> 12) & 1;
			} 
			else
			{
				if (code >= 512)
					tab = &De_DCT3Dtab0[(code >> 5) - 16];
				else if (code >= 128)
					tab = &De_DCT3Dtab1[(code >> 2) - 32];
				else if (code >= 8)
					tab = &De_DCT3Dtab2[(code >> 0) - 8];
				else
				{
					fault = 1;
					return;
				}

				run = (tab->val >> 4) & 255;
				level = tab->val & 15;
				last = (tab->val >> 12) & 1;
			}
			flushbits (tab->len);

			if (tab->val == ESCAPE)
			{                         /* escape */
				//last = getbits1 ();
				last = getbits (1);
				i += run = getbits (6);
				level = getbits (8);

				if ((sign = (level >= 128)))
					val = 256 - level;
				else
					val = level;

				if (level == 128 && modified_quantization_mode)
				{
					/* extended escape code was received */
					level = getbits (11);
					level = (level >> 6 & 0x001F) | level << 5;
					/* correctly set the sign */
					level = (level << (sizeof (int) * 8 - 11)) >> (sizeof (int) * 8 - 11);
					if (level >= 0)
						sign = 0;
					else
						sign = 1;
					val = abs (level);
				}
			} 
			else
			{
				i += run;
				val = level;
				sign = getbits (1);
			}
		}

		if (i >= 64)
		{
			fault = 1;
			return;
		}

		/* Descan in the proper order in advanced intra coding mode */
		if (advanced_intra_coding && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q))
		{
			switch (INTRA_AC_DC)
			{
			case INTRA_MODE_DC:
				j = De_zig_zag_scan[i];
				break;
			case INTRA_MODE_VERT_AC:
				j = De_alternate_horizontal_scan[i];
				break;
			case INTRA_MODE_HORI_AC:
				j = De_alternate_vertical_scan[i];
				break;
			default:
				//exit (-1);
				break;
			}
		} 
		else
		{
			j = De_zig_zag_scan[i];
		}
		qval = &bp[j];
		if (comp >= 6)
			QP = mmax (1, mmin (31, (De_bquant_tab[De_bquant] * quant) >> 2));
		else
			QP = quant;

		if (modified_quantization_mode && (comp == 4 || comp == 5 || comp == 10 || comp == 11))
		{
		  /* when modified quantization mode is on, use modified quantizer for
		   * chorominance coefficients */

			QP = De_MQ_chroma_QP_table[QP];
		}
		if ((advanced_intra_coding) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q))
		{
		  /* Advanced intra coding dequantization */
			val2 = QP* (val << 1);
			*qval = (sign ? -val2 : val2);
		} 
		else
		{
		  /* TMN3 dequantization */
			//if ((QP % 2) == 1)
			val2 = QP * ((val << 1) + 1);
			if ((QP - (QP >> 1)) == 1)
				*qval = (sign ? -val2 : val2);
			else
				*qval = (sign ? -(val2 - 1) : val2 - 1);
		}
		if (last)
		{                           /* That's it */
			return;
		}
	}
}



/*********************************************************************
 *
 *        Name:        get_sac_block
 *
 *	Description:	Decodes blocks of Arithmetic Encoded DCT Coeffs.
 *        and performs Run Length Decoding and Coefficient
 *        Dequantisation.
 *
 *	Input:        Picture block type and number.
 *
 *	Returns:	Nothing.
 *
 *	Side Effects:
 *
 *	Author:        Wayne Ellis <ellis_w_wayne@bt-web.bt.co.uk>
 *
 *********************************************************************/


void CBitStream::get_sac_block (int comp, int ptype, int INTRA_AC_DC, int Mode)
{
	int position = 0;
	int TCOEF_index, symbol_word;
	int last = 0, QP, i, j;
	short *qval;
	short *bp;
	De_RunCoef DCTcoef;
	int intra;


	bp = ld->block[comp];

	i = (ptype == 0);
	intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);

	while (!last)
	{                             /* while there are DCT coefficients
								 * remaining */
		position++;                 /* coefficient counter relates to Coeff.
									 * model */
		TCOEF_index = DecodeTCoef(position, intra);

		if (TCOEF_index == ESCAPE_INDEX)
		{                           /* ESCAPE code encountered */
			DCTcoef = Decode_Escape_Char (intra, &last);
		} 
		else
		{
			symbol_word = De_tcoeftab[TCOEF_index];
			DCTcoef = vlc_word_decode(symbol_word, &last);
		}

		i += DCTcoef.run;
		if (advanced_intra_coding && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q))
		{
			switch (INTRA_AC_DC)
			{
			case INTRA_MODE_DC:
				j = De_zig_zag_scan[i];
				break;
			case INTRA_MODE_VERT_AC:
				j = De_alternate_horizontal_scan[i];
				break;
			case INTRA_MODE_HORI_AC:
				j = De_alternate_vertical_scan[i];
				break;
			default:
				//exit (-1);
				break;
			}
		} 
		else
		{
			j = De_zig_zag_scan[i];
		}

		qval = &bp[j];
		i++;

		if (comp >= 6)
			QP = mmax (1, mmin (31, (De_bquant_tab[De_bquant] * quant) >> 2));
		else
			QP = quant;
		if ((advanced_intra_coding) && (Mode == MODE_INTRA || Mode == MODE_INTRA_Q))
		{
		  /* Advanced intra coding dequantization */
			*qval = (DCTcoef.sign ? -(QP * (2 * DCTcoef.val)) : QP * (2 * DCTcoef.val));
		} 
		else
		{
			if ((QP % 2) == 1)
				*qval = ((DCTcoef.sign) ? -(QP * (2 * (DCTcoef.val) + 1)) :
					 QP * (2 * (DCTcoef.val) + 1));
			else
				*qval = ((DCTcoef.sign) ? -(QP * (2 * (DCTcoef.val) + 1) - 1) :
					 QP * (2 * (DCTcoef.val) + 1) - 1);
		}
	}
	return;
}

/*********************************************************************
 *
 *        Name:        vlc_word_decode
 *
 *	Description:	Fills Decoder FIFO after a fixed word length
 *        string has been detected.
 *
 *	Input:        Symbol to be decoded, last data flag.
 *
 *	Returns:	Decoded Symbol via the structure DCTcoeff.
 *
 *	Side Effects:	Updates last flag.
 *
 *	Author:        Wayne Ellis <ellis_w_wayne@bt-web.bt.co.uk>
 *
 *********************************************************************/

De_RunCoef CBitStream::vlc_word_decode(int symbol_word, int *last)
{
	int sign_index;
	De_RunCoef DCTcoef;

	*last = (symbol_word >> 12) & 01;
	DCTcoef.run = (symbol_word >> 4) & 255;
	DCTcoef.val = (symbol_word) & 15;
	sign_index = decode_a_symbol (De_cumf_SIGN);
	DCTcoef.sign = De_signtab[sign_index];

	return (DCTcoef);
}

/*********************************************************************
 *
 *        Name:        Decode_Escape_Char
 *
 *	Description:	Decodes all components for a Symbol when an
 *        ESCAPE character has been detected.
 *
 *	Input:        Picture Type and last data flag.
 *
 *	Returns:	Decoded Symbol via the structure DCTcoeff.
 *
 *	Side Effects:	Modifies last data flag.
 *
 *	Author:        Wayne Ellis <ellis_w_wayne@bt-web.bt.co.uk>
 *
 *********************************************************************/

De_RunCoef CBitStream::Decode_Escape_Char (int intra, int *last)
{
	int last_index, run, run_index, level, level_index;
	De_RunCoef DCTcoef;

	if (intra)
	{
		last_index = decode_a_symbol (De_cumf_LAST_intra);
		*last = De_last_intratab[last_index];
	} 
	else
	{
		last_index = decode_a_symbol (De_cumf_LAST);
		*last = De_lasttab[last_index];
	}

	if (intra)
		run_index = decode_a_symbol (De_cumf_RUN_intra);
	else
		run_index = decode_a_symbol (De_cumf_RUN);

	run = De_runtab[run_index];

	/* $if (mrun) run|=64;$ */

	DCTcoef.run = run;

	if (intra)
		level_index = decode_a_symbol (De_cumf_LEVEL_intra);
	else
		level_index = decode_a_symbol (De_cumf_LEVEL);

	level = De_leveltab[level_index];
	if (level > 128)
		level -= 256;

	if (level < 0)
	{
		DCTcoef.sign = 1;
		DCTcoef.val = abs (level);
	} else
	{
		DCTcoef.sign = 0;
		DCTcoef.val = level;
	}

	return (DCTcoef);

}
/*********************************************************************
 *
 *        Name:        DecodeTCoef
 *
 *	Description:	Decodes a.c DCT Coefficients using the
 *        relevant arithmetic decoding model.
 *
 *	Input:        DCT Coeff count and Picture Type.
 *
 *	Returns:	Index to LUT
 *
 *	Side Effects:	None
 *
 *	Author:        Wayne Ellis <ellis_w_wayne@bt-web.bt.co.uk>
 *
 *********************************************************************/
int CBitStream::DecodeTCoef(int position, int intra)
{
	int index;

	switch (position)
	{
	case 1:
		if (intra)
			index = decode_a_symbol (De_cumf_TCOEF1_intra);
		else
			index = decode_a_symbol (De_cumf_TCOEF1);
		break;
	case 2:
		if (intra)
			index = decode_a_symbol (De_cumf_TCOEF2_intra);
		else
			index = decode_a_symbol (De_cumf_TCOEF2);
		break;
	case 3:
		if (intra)
			index = decode_a_symbol (De_cumf_TCOEF3_intra);
		else
			index = decode_a_symbol (De_cumf_TCOEF3);
		break;
	default:
		if (intra)
			index = decode_a_symbol (De_cumf_TCOEFr_intra);
		else
			index = decode_a_symbol (De_cumf_TCOEFr);
		break;
	}

	return (index);
}
//////////////functions in getblk.cpp end /////////
//////////////functions in gethdr.cpp start ///////

int CBitStream::getheader (int *iWidth,int *iHeight)
{
	unsigned int code, gob;
	int iiWidth,iiHeight;

	/* look for startcode */
	startcode ();
	code = getbits (PSC_LENGTH);
	gob = getbits (5);
	if (gob == SE_CODE)
		return 0;
	if (gob == 0)
	{
		getpicturehdr (&iiWidth,&iiHeight);
		if (syntax_arith_coding)    /* reset decoder after receiving */
			decoder_reset ();         /* fixed length PSC string */
	} 
	else
	{
		;
	}

	*iWidth = iiWidth;
	*iHeight = iiHeight;

	return gob + 1;
}


/* align to start of next startcode */

void CBitStream::startcode ()
{
  /* search for new picture start code */
	while (showbits (PSC_LENGTH) != 1l)
		flushbits (1);
}

/* decode picture header */

void CBitStream::getpicturehdr (int *ImageWidth,int *ImageHeight)
{
	int pos, pei, tmp;
	int TRPI = 0;
	int BCI = 0;
	int clock_conversion_code = 0;
	int clock_divisor = 0;
	int extended_temporal_reference = 0;
	int custwid = 0,custhei = 0;

	UFEP = 0;
	pos = ld->bitcnt;
	temp_ref = getbits (8);

	if (De_trd < 0)
		De_trd += 256;

	tmp = getbits (1);            /* always "1" */
	tmp = getbits (1);            /* always "0" */
	tmp = getbits (1);            /* split_screen_indicator */
	if (tmp)
	{
		return;
		//exit (-1);
	}
	tmp = getbits (1);            /* document_camera_indicator */
	tmp = getbits (1);            /* freeze_picture_release */
	/********************get the pic format and set perls and lines here*************************/

	tmp = getbits (3);
	if (tmp == 0)
	{
		return;
		//exit (-1);
	}

	if (tmp == EXTENDED_PTYPE)
	{
		plus_type = 1;
		UFEP = getbits (3);
		if (UFEP == 1)
		{                           /* OPPTYPE */
			source_format = getbits (3);
			/********************************************************************************/

			/* optional custom picture clock frequency */

⌨️ 快捷键说明

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