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

📄 vlc.cpp

📁 H.263的编码程序,加了CPU指令优化,VC版.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
	int bits = 0;
	int QUANT = encoder->total_Q ;
	int UFEP = 1;
	

		
	/*! PSC(Picture Start Code) */
	putbits(&(encoder->putstrmctrl), 1, 17);
	bits += 17;
	putbits(&(encoder->putstrmctrl), 0, 5);
	bits += 5;
	
	/*! TR(Temporal Reference) */
	if (B_IMG == encoder->PTYPE)
	{
		putbits(&(encoder->putstrmctrl), encoder->TRB, 8);
	}
	else
	{
		putbits(&(encoder->putstrmctrl), encoder->TR, 8);
	}
	bits += 8;
	
	/*! PTYPE(Type Information) */
	putbits(&(encoder->putstrmctrl), 1, 1);  //!< always '1', in order to avoid code emulation
	putbits(&(encoder->putstrmctrl), 0, 1);  //!< always '0', for distinction with H.261
	putbits(&(encoder->putstrmctrl), 0, 1);  //!< spilt screen indicator, set off currently
	putbits(&(encoder->putstrmctrl), 0, 1);  //!< document camera indicator, set off currently
	putbits(&(encoder->putstrmctrl), 0, 1);  //!< freeze picture release, set off currently
	putbits(&(encoder->putstrmctrl), 7, 3);  //!< indicating PLUSPTYPE will be added
	bits += 8;
	
	/*! PLUSPTYPE */
	putbits(&(encoder->putstrmctrl), UFEP, 3); //!< update full extended PTYPE when UFEP is set to zero
	bits += 3;
	if (UFEP)
	{
		putbits(&(encoder->putstrmctrl), encoder->sourceFormat, 3); 
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< optional custum PCF, set off currently
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< optional unrestricted motion vector mode, set off currently
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< optional syntax-based arithmetic coding mode, set off currently
		putbits(&(encoder->putstrmctrl), encoder->annex.Advanced_Prediction ? 1 : 0, 1);
		putbits(&(encoder->putstrmctrl), encoder->annex.AIC, 1);    //!< optional advanced INTRA coding mode, set off currently
		putbits(&(encoder->putstrmctrl), encoder->annex.Deblocking_Filter ? 1 : 0, 1);   
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< optional slice structure mode, set off currently
		putbits(&(encoder->putstrmctrl), encoder->annex.RPS ? 1 : 0, 1);    
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< optional independent segment decoding mode, set off currently
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< optional alternative INTER VLC mode, set off currently
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< optional modified quantization mode, set off currently
		putbits(&(encoder->putstrmctrl), 1, 1);    //!< equal to "1" to prevent start code emulation
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< reserved
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< reserved
		putbits(&(encoder->putstrmctrl), 0, 1);    //!< reserved
		bits += 18;
	}
	putbits(&(encoder->putstrmctrl), encoder->PTYPE, 3);
	putbits(&(encoder->putstrmctrl), 0, 1);     //!< optional reference picture resampling mode, set off currently
	putbits(&(encoder->putstrmctrl), 0, 1);     //!< optional reduced-resolution update mode, set off currently
	putbits(&(encoder->putstrmctrl), 0, 1);     //!< rounding type, equal to "0" currently
	putbits(&(encoder->putstrmctrl), 0, 1);     //!< reserved
	putbits(&(encoder->putstrmctrl), 0, 1);     //!< reserved
	putbits(&(encoder->putstrmctrl), 1, 1);     //!< equal to "1" to prevent start code emulation
	bits += 9;
	
	/*! CPM(Continuous Presence Multipoint) */
	putbits(&(encoder->putstrmctrl), 0, 1);
	bits++;

	/*! CPFMT information */
	if (encoder->sourceFormat == _CPFMT)
	{
		int PWI = encoder->pels/4 - 1;
		int PHI = encoder->lines/4;

		putbits(&(encoder->putstrmctrl), 0, 4);  
		putbits(&(encoder->putstrmctrl), PWI, 9);
		putbits(&(encoder->putstrmctrl), 1, 1);
		putbits(&(encoder->putstrmctrl), PHI, 9);
	}
	
	/*! PLUSPTYPE related information
	It would be added according to successive changes of encoder in future */
	//! B picture related information
	if (encoder->PTYPE == B_IMG)
	{
		putbits(&(encoder->putstrmctrl), 1, 4);      //!< Enhanced Layer Number. equal to '0001' now
		bits += 4;
		if (UFEP)
		{
			putbits(&(encoder->putstrmctrl), 1, 4);  //!< Reference Layer Number. equal to '0001' now
			bits += 4;
		}
	}
	if (encoder->annex.RPS)
	{
		int trp = encoder->TRP[encoder->ref_index];
		
		if (trp < 0)
		{
			trp += 256;
		}
		if (UFEP)
		{
			putbits(&(encoder->putstrmctrl), 4, 3);  //! Reference Picture Selection Mode Flags. equal to '100' now
			bits += 3;
		}
		if (encoder->PTYPE == INTRA)
		{
			putbits(&(encoder->putstrmctrl), 0, 1);  //! Temporal reference for prediction indication
			bits++;
		}
		else
		{
			putbits(&(encoder->putstrmctrl), 1, 1);  //! Temporal reference for prediction indication. 
			bits++;
			putbits(&(encoder->putstrmctrl), trp, 10);  //! Temporal Reference for Prediction.
			bits += 10;
		}
		putbits(&(encoder->putstrmctrl), 1, 2);  //! Back-Channel message indication.
		bits += 2;
	}
	
	/*! PQUANT(Quantizer Information) */
	putbits(&(encoder->putstrmctrl), QUANT, 5);
	bits += 5;
	
	/*! PEI(Extra Insertion Information) */
	putbits(&(encoder->putstrmctrl), 0, 1);
	bits ++;
	
	return bits;
	
}

/*!
*******************************************************************************
*
*   Name:          
*   Description:   
*   Input:         
*   Output:        
*   Last modified: 
*
*******************************************************************************/
int EncGOBHdr(putstrm *putstrmctrl, int gob_nbr, int gob_fid, int gob_quant, int gob_tr, int gob_trp)
{
	int bits = 0;
	int rps_flag = 0;
	
	bits += alignbits(putstrmctrl);        //< GSTUF
	putbits(putstrmctrl, 1, 17);             //< GBSC
	bits += 17;
	putbits(putstrmctrl, gob_nbr, 5);        //< GN  
	bits += 5;
	putbits(putstrmctrl, gob_fid, 2);        //< GFID
	bits +=2;
	putbits(putstrmctrl, gob_quant, 5);      //< GQUANT
	bits += 5;
	
	if(rps_flag)
	{
		putbits(putstrmctrl, 1, 1);             //< TRI
		bits++;
		putbits(putstrmctrl, gob_tr, 8);        //< TR
		bits += 8;
		if (gob_trp)
		{
			putbits(putstrmctrl, 1, 1);         //< TRPI
			bits++;
			putbits(putstrmctrl, gob_trp, 8);   //< TRP
			bits += 8;
		}
		else
		{
			putbits(putstrmctrl, 0, 1);         //< TRPI
			bits++;
		}
		putbits(putstrmctrl, 0, 1);             //< BCI
		bits++;
	}
	
	return bits;
}
/*!
*******************************************************************************
*
*   Name:          EncMBHdr
*   Description:   Encode MB header and send bits to stream
*   Input:         Picture type, MB mode, cod, cbp and dquant
*   Output:        
*   Return:        The number of bits 
*   Side effect:   Write bits to global stream structure putstrmctrl 
*   Last modified: 2002/12/5
*
*******************************************************************************/
int EncMBHdr(putstrm *putstrmctrl, int p_type, int mode, int cod, int cbp, int dquant)
{
	int bits = 0;
	int intra_mode = cbp>>16;

	cbp &= 0x0000ffff;
    
	/* COD(Coded macroblock indication) */
	if (p_type == INTER)
	{
		putbits(putstrmctrl, cod, 1);
		bits++;
	}
	if (cod)
	{
		return bits;
	}
	
	/* MCBPC(Macroblock type & Code block pattern for chrominance) */
	if (p_type == INTRA)
	{
		bits += vlcmcbpcI(putstrmctrl, cbp, mode);
	}
    else 
	{
		bits += vlcmcbpcP(putstrmctrl, cbp, mode);
	}
	/* if current MB is intra coded, write intra mode */
	if (mode == MODE_INTRA)
	{
		switch(intra_mode)
		{
		case INTRA_MODE_DC:
			putbits(putstrmctrl, 0, 1);
			bits += 1;
			break;
		case INTRA_MODE_VERT_AC:
			putbits(putstrmctrl, 2, 2);
			bits += 2;
			break;
		case INTRA_MODE_HORI_AC:
			putbits(putstrmctrl, 3, 2);
			bits += 2;
			break;
		default:
			break;
		}
	}	
	/* CBPY(Coded block pattern for luminance) */
    bits += vlccbpy(putstrmctrl, cbp, mode);
	
	/* DQUANT(Quantizer Information) */
	if (mode == MODE_INTRA_Q || mode ==MODE_INTER_Q)
	{
		switch(dquant)
		{
		case -1:
			putbits(putstrmctrl, 0, 2);
			break;
		case -2:
			putbits(putstrmctrl, 1, 2);
			break;
		case  1:
			putbits(putstrmctrl, 2, 2);
			break;
		case  2:
			putbits(putstrmctrl, 3, 2);
			break;
		default:
			printf("error dquant!");
			exit(-1);
		}
		bits += 2;
	}
	return bits;
}


/*!
*******************************************************************************
*
*   Name:          EncMBHdr_B
*   Description:   Encode MB header for B picture and send bits to stream
*   Input:         mb_type, cbp and dequant
*   Output:        
*   Return:        The number of bits 
*   Side effect:   Write bits to global stream structure putstrmctrl 
*   Last modified: 2002/1/13
*
*******************************************************************************/
int EncMBHdr_B(putstrm *putstrmctrl, int mb_type, int cbp, int dquant)
{

	int bits = 0;
	int cbpc, cbpy;
	int intra_mode = cbp>>16;

	cbp &= 0x0000ffff;
	cbpc = cbp&3;
	cbpy = (cbp&60)>>2;
	
	if ((mb_type != 11) && (mb_type != 12))
	{
		cbpy = cbpy ^ 15;           //!< intra
	}
	
	/* COD(coded macroblock indication */
	if (-1 == mb_type)
	{
		putbits(putstrmctrl, 1, 1);
		return 1;
	}
	else
	{
		putbits(putstrmctrl, 0, 1);
	}
	bits++;
	
	/* MBTYPE */
	putbits(putstrmctrl, mbtypetab[mb_type].cdwd, mbtypetab[mb_type].len);
	bits += mbtypetab[mb_type].len;

	/* if current MB is intra coded, write intra mode */
	if (mb_type == 11 || mb_type == 12)
	{
		switch(intra_mode)
		{
		case INTRA_MODE_DC:
			putbits(putstrmctrl, 0, 1);
			bits += 1;
			break;
		case INTRA_MODE_VERT_AC:
			putbits(putstrmctrl, 2, 2);
			bits += 2;
			break;
		case INTRA_MODE_HORI_AC:
			putbits(putstrmctrl, 3, 2);
			bits += 2;
			break;
		default:
			break;
		}
	}
	/* CBPC, CBPY and DQUANT */
	if ((mb_type == 2) || (mb_type == 5) || (mb_type == 8))
	{
		return bits;
	}
	else
	{
		putbits(putstrmctrl, cbpctab[cbpc].cdwd, cbpctab[cbpc].len);
		bits += cbpctab[cbpc].len;
		putbits(putstrmctrl, cbpytab[cbpy].cdwd, cbpytab[cbpy].len);
		bits += cbpytab[cbpy].len;
		if ((mb_type == 0) || (mb_type == 3) || (mb_type == 6) || (mb_type == 9) || (mb_type == 11))
		{
			return bits;
		}
		else
		{
			switch(dquant)
			{
			case -1:
				putbits(putstrmctrl, 0, 2);
				break;
			case -2:
				putbits(putstrmctrl, 1, 2);
				break;
			case  1:
				putbits(putstrmctrl, 2, 2);
				break;
			case  2:
				putbits(putstrmctrl, 3, 2);
				break;
			default:
				printf("error dquant!");
				exit(-1);
			}
			bits += 2;
		}
	}
	return bits;
} 

/*!
*******************************************************************************
*
*   Name:          EncMVD
*   Description:   Encode MV data and send bits to stream
*   Input:         MCParam structure, the position and mode of current MB, gob identification 
*   Output:        
*   Return:        The number of bits 
*   Side effect:   Write bits to global stream structure putstrmctrl 
*   Last modified: 2002/12/5
*
*******************************************************************************/
int EncMVD(putstrm *putstrmctrl, MCParam *MC, int x, int y, int mode, int newgob)
{
	int bits = 0;
	int dmvx;
	int dmvy;
	
	if ((mode == MODE_INTER4V) || (mode == MODE_INTER4V_Q))
	{
		for (int block = 1; block < 5; block++)
		{
			FindPMV(MC->mv_frame, x+1, y+1, &dmvx, &dmvy, block, newgob, 1);
			dmvx = (MC->mv_frame[block][y+1][x+1])->x*2 + (MC->mv_frame[block][y+1][x+1])->x_half - dmvx;
			dmvy = (MC->mv_frame[block][y+1][x+1])->y*2 + (MC->mv_frame[block][y+1][x+1])->y_half - dmvy;
			bits += vlcmv(putstrmctrl, dmvx);
			bits += vlcmv(putstrmctrl, dmvy);
		}
	}
	else
	{
		FindPMV(MC->mv_frame, x+1, y+1, &dmvx, &dmvy, 0, newgob, 1);
		dmvx = (MC->mv_frame[0][y+1][x+1])->x*2 + (MC->mv_frame[0][y+1][x+1])->x_half - dmvx;
		dmvy = (MC->mv_frame[0][y+1][x+1])->y*2 + (MC->mv_frame[0][y+1][x+1])->y_half - dmvy;
		bits += vlcmv(putstrmctrl, dmvx);
		bits += vlcmv(putstrmctrl, dmvy);
	}
	
	return bits;
}

/*!
*******************************************************************************
*
*   Name:          EncMVD_B
*   Description:   Encode MV data for B picture and send bits to stream
*   Input:         MCParam structure, the position and mode of current MB, gob identification 
*   Output:        
*   Return:        The number of bits 
*   Side effect:   Write bits to global stream structure putstrmctrl 
*   Last modified: 2002/1/13
*
*******************************************************************************/
int EncMVD_B(putstrm *putstrmctrl, MCParam *MC, int x, int y, int mode, int newgob)
{
	int bits = 0;
	int dmvx, dmvy;
	
	if (B_DIRECT == mode)
	{
		return 0;
	}
	if ((B_FORWARD == mode) || (B_BIDIRECTIONAL == mode))
	{
		FindPMV_B(MC->mv_frame, x+1, y+1, &dmvx, &dmvy, newgob, 1, 0);
		dmvx = (MC->mv_frame[0][y+1][x+1])->x*2 + (MC->mv_frame[0][y+1][x+1])->x_half - dmvx;
		dmvy = (MC->mv_frame[0][y+1][x+1])->y*2 + (MC->mv_frame[0][y+1][x+1])->y_half - dmvy;
		bits += vlcmv(putstrmctrl, dmvx);
		bits += vlcmv(putstrmctrl, dmvy);
	}
	if ((B_BACKWARD == mode) || (B_BIDIRECTIONAL == mode))
	{
		FindPMV_B(MC->mv_frame, x+1, y+1, &dmvx, &dmvy, newgob, 1, 1);
		dmvx = (MC->mv_frame[5][y+1][x+1])->x*2 + (MC->mv_frame[5][y+1][x+1])->x_half - dmvx;
		dmvy = (MC->mv_frame[5][y+1][x+1])->y*2 + (MC->mv_frame[5][y+1][x+1])->y_half - dmvy;
		bits += vlcmv(putstrmctrl, dmvx);
		bits += vlcmv(putstrmctrl, dmvy);
	}
	
	return bits;
}

/*!
*******************************************************************************
*
*   Name:          EncCoeff
*   Description:   Encode transform coefficients and send bits to stream
*   Input:         MB mode, cbp value, address of transform coefficients, 
*                  number of coefficients to be coded
*   Output:        
*   Return:        The number of bits 
*   Side effect:   Write bits to global stream structure putstrmctrl 
*   Last modified: 2002/12/5

⌨️ 快捷键说明

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