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

📄 vlc.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
*
*******************************************************************************/
int EncCoeff(putstrm *putstrmctrl, int intra, int CBP, INT16 *qcoeff, int ncoeffs)
{
	int bits = 0;
    int i, j;
	
	if (!intra)
	{
		for (i = 0; i < 6; i++) 
		{
			if ((i==0 && CBP&32) || 
				(i==1 && CBP&16) ||
				(i==2 && CBP&8) || 
				(i==3 && CBP&4) ||
				(i==4 && CBP&2) ||
				(i==5 && CBP&1)) 
			{
				bits += CodeCoeff(putstrmctrl, intra, qcoeff, i, ncoeffs);
			}
		}
	}
	else if (2 == intra)
	{
		for (i = 0; i < 6; i++) 
		{
			if ((i==0 && CBP&32) || 
				(i==1 && CBP&16) ||
				(i==2 && CBP&8) || 
				(i==3 && CBP&4) ||
				(i==4 && CBP&2) ||
				(i==5 && CBP&1)) 
			{
				bits += CodeCoeff_AIC(putstrmctrl, qcoeff, i, ncoeffs);
			}
		}
	}
    else  
	{
		for (i = 0; i < 6; i++) 
		{
			bits += CodeCoeff(putstrmctrl, intra, qcoeff, i, ncoeffs);
		}
	}
	return bits;
}

//Name    : vlcmcbpcI;
//Input   : CBP & mode of a MB, CBP & mode;
//Output  : number of bits put into bitstream;
//Discription : this function is for INTRA MB
//              usage: vlcstr * cbpcI = vlcmcbpcI (CBP, mode);
int vlcmcbpcI (putstrm *putstrmctrl, int CBP, int mode)
{
	int CBPC = CBP & 3;
	int index = (mode == MODE_INTRA) ?  CBPC : (CBPC & 4);
	if ((index <8) && (index >= 0))
	{
		putbits (putstrmctrl, mcbpctabI[index].cdwd, mcbpctabI[index].len);
		return mcbpctabI[index].len;
	}
	else                  //!< ??should be considered carefully later
	{
		putbits (putstrmctrl, mcbpctabI[8].cdwd, mcbpctabI[8].len);
		return mcbpctabI[8].len;
	}
}

//Name    : vlcmcbpcP;
//Input   : CBP & mode of a MB, CBP & mode;
//Output  : number of bits put into bitstream;
//Discription : this function is for INTER MB
//              usage: vlcstr * cbpcI = vlcmcbpcI (CBP, mode);
int vlcmcbpcP(putstrm *putstrmctrl, int CBP, int mode)
{
	int CBPC = CBP & 3;
	int index = CBPC | (mode << 2);
	if ((index < 20) && (index >= 0))
	{
		putbits (putstrmctrl, mcbpctabP[index].cdwd, mcbpctabP[index].len);
		return mcbpctabP[index].len;
	}
	else                 //!<  ??should be considered carefully later
	{
		putbits (putstrmctrl, mcbpctabP[20].cdwd, mcbpctabP[20].len);
		return mcbpctabP[20].len;
	}
}

//Name    : vlccbpy;
//Input   : CBP & mode of a MB, CBP & mode;
//Output  : a vlcstr type pointer, pointing to the position in cbpytab, which is determined
//          by CBPY & mode;
//Discription : 
//              usage: vlcstr * cbpcI = vlcmcbpcI (CBP, mode);
int vlccbpy (putstrm *putstrmctrl, int CBP, int mode)
{
	int CBPY = CBP >> 2;
	int index = (mode == MODE_INTRA)||(mode == MODE_INTRA_Q) ? CBPY : CBPY ^ 15;
	
	putbits (putstrmctrl, cbpytab [index].cdwd, cbpytab[index].len);
	return cbpytab[index].len;
}

//Name    : vlcmv;
//Input   : difference of mv and pmv
//Output  : number of bits of vlc-encoded mv
//Discription : put vlc-codeword of mv into bitstream. for mv should return two parameter
//              vlcstr, and sign, this function will put bits into bitstream to avoid return
//              so many parameters;
int vlcmv (putstrm *putstrmctrl, int dmv)
{
	int index,sign = 0;
	if(dmv)
	{
		if (dmv >= 0)
		{
			if (dmv < 32)
				index = dmv;
			else if (dmv <= 63)
			{
				index = 64 - dmv;
				sign = 1;
			}
			else
			{
				printf ("ERROR HAPPENED IN VLC-ENCODE OF MV! MV>63.\n");
				exit (0);
			}
		}
		else
		{
			if (dmv >= -32)
			{
				index = -dmv;
				sign = 1;
			}
			else if (dmv >= -63)
				index = 64 + dmv;
			else
			{
				printf ("ERROR HAPPENED IN VLC-ENCODE OF MV! MV<-63.\n");
				exit (0);
			}
		}
		/*
		if (dmv >= 0 && dmv <= 32)
		index = dmv;
		else if (dmv < 0 && dmv >= -32)
		{
		index = -dmv;
		sign = 1;
		}
		else if (dmv < -32 && dmv >= -63)
		index = 64 + dmv;
		else if (dmv > 32 && dmv <= 63)
		{
		index = 64 - dmv;
		sign = 1;
		}
		else
		{
		printf ("ERROR HAPPENED WHEN VLCMV.\n");
		exit (0);
		}
		*/
		putbits (putstrmctrl, mvtab[index].cdwd, mvtab[index].len);
		putbits (putstrmctrl, sign, 1);
		return mvtab[index].len + 1;
	}
	else
	{
		putbits (putstrmctrl, 1,1);
		return 1;
		
	}
	
}

/*!
*******************************************************************************
*
*   Name:          
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 
*
*******************************************************************************/
int CodeCoeff(putstrm *putstrmctrl, int intra, INT16 *qcoeff, int block, int ncoeffs)
{
    int j, bits;
    int prev_run, run, prev_level, level, first;
    int prev_s, s, length;
	
    run = bits = 0;
    first = 1;
    prev_run = prev_level = level = s = prev_s = 0;
	
	for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++)
	{
		/* Do this block's DC-coefficient first */
		if (!(j%ncoeffs) && intra)
		{
			/* DC coeff */
			
			if (qcoeff[block*ncoeffs] != 128)
				putbits(putstrmctrl, qcoeff[block*ncoeffs], 8);
			else
				putbits(putstrmctrl, 255, 8);
			bits += 8;
		}
		else {
			/* AC coeff */
			s = 0;
			/* Increment run if coeff is zero */
			if ((level = qcoeff[j]) == 0) 
			{
				run++;
			}
			else 
			{
				/* code run & level and count bits */
				if (level < 0) 
				{
					s = 1;
					level = -level;
				}
				if (!first) 
				{
					/* Encode the previous coefficient */
					if (prev_level  < 13 && prev_run < 64)
						length = put_coeff (putstrmctrl, prev_run, prev_level, 0);  
					else
						length = 0;
					if (length == 0)
					{  /* Escape coding */
						if (prev_s == 1)
						{
							prev_level = (prev_level^0xff)+1;
						}
						putbits(putstrmctrl, 3, 7);	/* Escape code */
						putbits(putstrmctrl, 0, 1);
						putbits(putstrmctrl, prev_run, 6);
						putbits(putstrmctrl, prev_level, 8);
						bits += 22;
					}
					else
					{
						putbits(putstrmctrl, prev_s, 1);
						bits += length + 1;
					}
				}
				prev_run = run; prev_s = s;
				prev_level = level; 
				run = first = 0;
			}
		}
	}
	/* Encode the last coeff */
	if (!first) 
	{
		
		if (prev_level  < 13 && prev_run < 64) 
			length = put_coeff (putstrmctrl, prev_run, prev_level, 1);   
		else
			length = 0;
		if (length == 0) 
		{  /* Escape coding */
			if (prev_s == 1) 
			{
				prev_level = (prev_level^0xff)+1;
			}
			putbits (putstrmctrl, 3, 7);	/* Escape code */
			putbits(putstrmctrl, 1, 1);
			putbits(putstrmctrl, prev_run, 6);
			putbits(putstrmctrl, prev_level, 8);
			bits += 22;
		}
		else {
			putbits(putstrmctrl, prev_s, 1);
			bits += length + 1;
		}
	}
	return bits;
}
/*!
*******************************************************************************
*
*   Name:          
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 
*
*******************************************************************************/
int put_coeff (putstrm *putstrmctrl, int run, int level, int last)
{
	int length = 0;
	
	assert (last >= 0 && last < 2);
	assert (run >= 0 && run < 64);
	assert (level > 0 && level < 128);
	
	if (last == 0) 
	{
		if (run < 2 && level < 13 ) 
		{
			putbits (putstrmctrl, coeff_tab0[run][level-1].cdwd, coeff_tab0[run][level-1].len);			
			length = coeff_tab0[run][level-1].len;
		}
		else if (run > 1 && run < 27 && level < 5) 
		{
			putbits (putstrmctrl, coeff_tab1[run-2][level-1].cdwd, coeff_tab1[run-2][level-1].len);
			length = coeff_tab1[run-2][level-1].len;
		}
	}
	else if (last == 1) 
	{
		if (run < 2 && level < 4) 
		{
			putbits (putstrmctrl, coeff_tab2[run][level-1].cdwd, coeff_tab2[run][level-1].len);
			length = coeff_tab2[run][level-1].len;
		}
		else if (run > 1 && run < 42 && level == 1) 
		{
			putbits (putstrmctrl, coeff_tab3[run-2].cdwd, coeff_tab3[run-2].len);			
			length = coeff_tab3[run-2].len;
		}
	}
	return length;
}

int put_intra_coeff (putstrm *putstrmctrl, int run, int level, int last)
{
	int length = 0;
	
	assert (last >= 0 && last < 2);
	assert (run >= 0 && run < 64);
	assert (level > 0 && level < 128);
	
	if (last == 0)
	{
		if (run < 2 && level < 26)
		{
			putbits (putstrmctrl, intra_coeff_tab0[run][level - 1].cdwd, intra_coeff_tab0[run][level - 1].len);
			length = intra_coeff_tab0[run][level - 1].len;
		}
		else if (run > 1 && run < 14 && level < 5)
		{
			putbits (putstrmctrl, intra_coeff_tab1[run - 2][level - 1].cdwd, intra_coeff_tab1[run - 2][level - 1].len);
			length = intra_coeff_tab1[run - 2][level - 1].len;
		}
	} 
	else if (last == 1)
	{
		if (run < 2 && level < 11)
		{
			putbits (putstrmctrl, intra_coeff_tab2[run][level - 1].cdwd, intra_coeff_tab2[run][level - 1].len);
			length = intra_coeff_tab2[run][level - 1].len;
		} 
		else if (run > 1 && run < 24 && level < 4)
		{
			putbits (putstrmctrl, intra_coeff_tab3[run - 2][level - 1].cdwd, intra_coeff_tab3[run - 2][level - 1].len);
			length = intra_coeff_tab3[run - 2][level - 1].len;
		}
	}
	return length;
}

int CodeCoeff_AIC(putstrm *putstrmctrl, INT16 *qcoeff, int block, int ncoeffs)
{

	int bits = 0;
    int run = 0;
	int first = 1;
	int prev_level = 0;
	int prev_run = 0;
	int level = 0;
	int s = 0;
	int prev_s = 0;
	int length;
	int j;
	
	for (j = block * ncoeffs; j < (block + 1) * ncoeffs; j++)
	{
		/*  DC/AC in advanced intra coding mode */
		s = 0;
		/* Increment run if coeff is zero */
		if ((level = qcoeff[j]) == 0)
		{
			run++;
		} 
		else
		{
			/* code run & level and count bits */
			if (-127 <= level && level < 0)
			{
				s = 1;
				level = -level;
			}
			if (!first)
			{
				/* Encode the previous coefficient */
				if (prev_level >= 0 && prev_level < 26 && prev_run < 64)
				{

					length = put_intra_coeff (putstrmctrl, prev_run, prev_level, 0);
				} 
				else
				{
					length = 0;
				}
				if (length == 0)
				{                     /* Escape coding */
					if (prev_s == 1)
					{
						prev_level = (prev_level ^ 0xffff) + 1;
					}
					
					putbits (putstrmctrl, 3, 7);     /* Escape code */
					putbits (putstrmctrl, 0, 1);
					putbits (putstrmctrl, prev_run, 6);
					putbits (putstrmctrl, prev_level, 8);
					bits += 22;
					
				} 
				else
				{
					putbits (putstrmctrl, prev_s, 1);
					bits += length + 1;
				}
			}
			prev_run = run;
			prev_s = s;
			prev_level = level;
			run = first = 0;
		}
	}
	
	/* Encode the last coeff */
	if (!first)
	{
		
		if (prev_level >= 0 && prev_level < 26 && prev_run < 64)
		{
			length = put_intra_coeff (putstrmctrl, prev_run, prev_level, 1);
		}
		else
			length = 0;
		
		if (length == 0)
		{                           /* Escape coding */
			if (prev_s == 1)
			{
				prev_level = (prev_level ^ 0xffff) + 1;
			}
			
			putbits (putstrmctrl, 3, 7);           /* Escape code */
			putbits (putstrmctrl, 1, 1);
			putbits (putstrmctrl, prev_run, 6);
			putbits (putstrmctrl, prev_level, 8);
			bits += 22;
			
		} else
		{
			putbits (putstrmctrl, prev_s, 1);
			bits += length + 1;
		}
	}
	return bits;
}

⌨️ 快捷键说明

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