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

📄 mvcommon.c

📁 优化过的xvid1.1.2源代码
💻 C
字号:
#include "MVCommon.h"
#include "MVBitstream.h"

extern const uint8_t default_intra_matrix[64];
extern const uint8_t default_inter_matrix[64];
extern VLC 	   sprite_trajectory_len[15];
extern const uint32_t multipliers[32];

int mavrix_fine_start_code(Bitstream * bs)
{
      unsigned int  start_tag = 0x00000001;
      unsigned int  start_code;
	  
      BitstreamByteAlign(bs);

repeat:
      while(BitstreamShowBits(bs, 24) != start_tag)
     {
           BitstreamSkip(bs, 8);
          if((uint32_t)((bs->tail - bs->start)<<2) >= bs->length)
		  	return -1;
     }

     start_code = BitstreamGetBits(bs, 32);
     if((start_code >> 4) == 0x12)
           return VIDOBJLAY_START_CODE;
     else
	    if(start_code == VOP_START_CODE)
			return VOP_START_CODE;
        else
	        goto repeat;
		
	return -1;
	
}

uint32_t log2bin(uint32_t value)
{
  int n = 0;

  while (value)
  {
		value >>= 1;
		n++;
  }

  return n;
}

const uint16_t *get_intra_matrix(const uint16_t * mpeg_quant_matrices)
{
	return(mpeg_quant_matrices + 0*64);
}

const uint16_t *get_inter_matrix(const uint16_t * mpeg_quant_matrices)
{
	return(mpeg_quant_matrices + 4*64);
}

const uint8_t *get_default_intra_matrix(void)
{
	return default_intra_matrix;
}

const uint8_t *get_default_inter_matrix(void)
{
	return default_inter_matrix;
}


void set_intra_matrix(uint16_t * mpeg_quant_matrices, const uint8_t * matrix)
{
	int i;
	uint16_t *intra_matrix = mpeg_quant_matrices + 0*64;
	uint16_t *intra_matrix1 = mpeg_quant_matrices + 1*64;
	uint16_t *intra_matrix_fix = mpeg_quant_matrices + 2*64;
	uint16_t *intra_matrix_fixl = mpeg_quant_matrices + 3*64;

	for (i = 0; i < 64; i++)
	{
		intra_matrix[i] = (!i) ? (uint16_t)8: (uint16_t)matrix[i];
		intra_matrix1[i] = (intra_matrix[i]>>1);
		intra_matrix1[i] += ((intra_matrix[i] == 1) ? 1: 0);
		intra_matrix_fix[i] = FIX(intra_matrix[i]);
		intra_matrix_fixl[i] = FIXL(intra_matrix[i]);
	}
}

void set_inter_matrix(uint16_t * mpeg_quant_matrices, const uint8_t * matrix)
{
	int i;
	uint16_t *inter_matrix = mpeg_quant_matrices + 4*64;
	uint16_t *inter_matrix1 = mpeg_quant_matrices + 5*64;
	uint16_t *inter_matrix_fix = mpeg_quant_matrices + 6*64;
	uint16_t *inter_matrix_fixl = mpeg_quant_matrices + 7*64;

	for (i = 0; i < 64; i++)
	{
		inter_matrix1[i] = ((inter_matrix[i] = (int16_t) matrix[i])>>1);
		inter_matrix1[i] += ((inter_matrix[i] == 1) ? 1: 0);
		inter_matrix_fix[i] = FIX(inter_matrix[i]);
		inter_matrix_fixl[i] = FIXL(inter_matrix[i]);
	}
}

int bs_get_spritetrajectory(Bitstream * bs)
{
	int i;
	for (i = 0; i < 12; i++)
	{
		if (BitstreamShowBits(bs, sprite_trajectory_len[i].len) == sprite_trajectory_len[i].code)
		{
			BitstreamSkip(bs, sprite_trajectory_len[i].len);
			return i;
		}
	}
	return -1;
}

int check_resync_marker(Bitstream * bs, int addbits)
{
	uint32_t nbits;
	uint32_t code;
	uint32_t nbitsresyncmarker = NUMBITS_VP_RESYNC_MARKER + addbits;

	nbits = BitstreamNumBitsToByteAlign(bs);
	code = BitstreamShowBits(bs, nbits);

	if (code == (((uint32_t)1 << (nbits - 1)) - 1))
	{
		return BitstreamShowBitsFromByteAlign(bs, nbitsresyncmarker) == RESYNC_MARKER;
	}

	return 0;
}

uint32_t get_dc_scaler(uint32_t quant,
			                 uint32_t lum)
{
	if (quant < 5)
		return 8;

	if (quant < 25 && !lum)
		return (quant + 13) / 2;

	if (quant < 9)
		return 2 * quant;

	if (quant < 25)
		return quant + 8;

	if (lum)
		return 2 * quant - 16;
	else
		return quant - 6;
}

uint32_t quant_h263_intra(int16_t * coeff,
						   const int16_t * data,
						   const uint32_t quant,
						   const uint32_t dcscalar,
						   const uint16_t * mpeg_quant_matrices)
{
	const uint32_t mult = multipliers[quant];
	const uint16_t quant_m_2 = quant << 1;
	int i;

	coeff[0] = DIV_DIV(data[0], (int32_t) dcscalar);

	for (i = 1; i < 64; i++)
	{
		int16_t acLevel = data[i];

		if (acLevel < 0)
		{
			acLevel = -acLevel;
			if (acLevel < quant_m_2) 
			{
				coeff[i] = 0;
				continue;
			}
			acLevel = (acLevel * mult) >> SCALEBITS;
			coeff[i] = -acLevel;
		} 
		else
		{
			if (acLevel < quant_m_2)
			{
				coeff[i] = 0;
				continue;
			}
			acLevel = (acLevel * mult) >> SCALEBITS;
			coeff[i] = acLevel;
		}
	}

	return(0);
	
}

int dequant_h263_intra(int16_t * data,
					 const int16_t * coeff,
					 const uint32_t quant,
					 const uint32_t dcscalar,
					 const uint16_t * mpeg_quant_matrices)
{
	const int32_t quant_m_2 = quant << 1;
	const int32_t quant_add = (quant & 1 ? quant : quant - 1);
	int i;

	data[0] = coeff[0] * dcscalar;
	if (data[0] < -2048)
	{
		data[0] = -2048;
	}
	else 
	   if(data[0] > 2047)
	   {
		   data[0] = 2047;
	   }

	for (i = 1; i < 64; i++)
	{
			int32_t acLevel = coeff[i];
	
			if (acLevel == 0) 
			{
				data[i] = 0;
			}
			else 
			    if (acLevel < 0)
			    {
						acLevel = quant_m_2 * -acLevel + quant_add;
						data[i] = (acLevel <= 2048 ? -acLevel : -2048);
					}
					else
					{
						acLevel = quant_m_2 * acLevel + quant_add;
						data[i] = (acLevel <= 2047 ? acLevel : 2047);
					}
	}

	return(0);
}

uint32_t quant_mpeg_intra(int16_t * coeff,
						   const int16_t * data,
						   const uint32_t quant,
						   const uint32_t dcscalar,
						   const uint16_t * mpeg_quant_matrices)
{
	const uint32_t quantd = ((VM18P * quant) + (VM18Q / 2)) / VM18Q;
	const uint32_t mult = multipliers[quant];
	const uint16_t *intra_matrix = get_intra_matrix(mpeg_quant_matrices);
	int i;

	coeff[0] = DIV_DIV(data[0], (int32_t) dcscalar);

	for (i = 1; i < 64; i++)
	{
			if (data[i] < 0)
			{
				uint32_t level = -data[i];
	
				level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
				level = ((level + quantd) * mult) >> SCALEBITS;
				coeff[i] = -(int16_t) level;
			}
			else
					if (data[i] > 0)
					{
						uint32_t level = data[i];
			
						level = ((level << 4) + (intra_matrix[i] >> 1)) / intra_matrix[i];
						level = ((level + quantd) * mult) >> SCALEBITS;
						coeff[i] = level;
					}
					else
					{
						coeff[i] = 0;
					}
	}

	return(0);
}

/* quantize inter-block
 *
 * level = DIV_DIV(16 * data[i], default_intra_matrix[i]);
 * coeff[i] = (level + quantd) / quant2;
 * sum += abs(level);
 */

uint32_t quant_mpeg_inter(int16_t * coeff,
						   const int16_t * data,
						   const uint32_t quant,
						   const uint16_t * mpeg_quant_matrices)
{
	const uint32_t mult = multipliers[quant];
	const uint16_t *inter_matrix = get_inter_matrix(mpeg_quant_matrices);
	uint32_t sum = 0;
	int i;

	for (i = 0; i < 64; i++)
	{
		if (data[i] < 0)
		{
			uint32_t level = -data[i];

			level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
			level = (level * mult) >> 17;
			sum += level;
			coeff[i] = -(int16_t) level;
		}
		else 
		   if (data[i] > 0)
		   {
					uint32_t level = data[i];
		
					level = ((level << 4) + (inter_matrix[i] >> 1)) / inter_matrix[i];
					level = (level * mult) >> 17;
					sum += level;
					coeff[i] = level;
			 }
			 else
			 {
					coeff[i] = 0;
			 }
	}

	return(sum);
	
}

/* dequantize intra-block & clamp to [-2048,2047]
 *
 * data[i] = (coeff[i] * default_intra_matrix[i] * quant2) >> 4;
 */

uint32_t dequant_mpeg_intra(int16_t * data,
							 const int16_t * coeff,
							 const uint32_t quant,
							 const uint32_t dcscalar,
							 const uint16_t * mpeg_quant_matrices)
{
	const uint16_t *intra_matrix = get_intra_matrix(mpeg_quant_matrices);
	int i;

	data[0] = coeff[0] * dcscalar;
	if (data[0] < -2048)
	{
		data[0] = -2048;
	}
	else 
	  if(data[0] > 2047)
	  {
		   data[0] = 2047;
	  }

	for (i = 1; i < 64; i++)
	{
		if (coeff[i] == 0)
		{
			data[i] = 0;
		}
		else
		  if(coeff[i] < 0)
		  {
			  uint32_t level = -coeff[i];

			  level = (level * intra_matrix[i] * quant) >> 3;
			  data[i] = (level <= 2048 ? -(int16_t) level : -2048);
		  }
		  else
		  {
			  uint32_t level = coeff[i];

			  level = (level * intra_matrix[i] * quant) >> 3;
			  data[i] = (level <= 2047 ? level : 2047);
		  }
	}

	return(0);
}


/* dequantize inter-block & clamp to [-2048,2047]
 * data = ((2 * coeff + SIGN(coeff)) * inter_matrix[i] * quant) / 16
 */

uint32_t dequant_mpeg_inter(int16_t * data,
							 const int16_t * coeff,
							 const uint32_t quant,
							 const uint16_t * mpeg_quant_matrices)
{
	uint32_t sum = 0;
	const uint16_t *inter_matrix = get_inter_matrix(mpeg_quant_matrices);
	int i;

	for (i = 0; i < 64; i++) 
	{
		if (coeff[i] == 0)
		{
			data[i] = 0;
		}
		else 
		   if (coeff[i] < 0)
		   {
			   int32_t level = -coeff[i];

			   level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
			   data[i] = (level <= 2048 ? -level : -2048);
		   }
		   else
		   {
			   uint32_t level = coeff[i];

			   level = ((2 * level + 1) * inter_matrix[i] * quant) >> 4;
			   data[i] = (level <= 2047 ? level : 2047);
		   }

		   sum ^= data[i];
	}

	/*	mismatch control */
	if ((sum & 1) == 0)
	{
		data[63] ^= 1;
	}

	return(0);
	
}
 

void init_mpeg_matrix(uint16_t * mpeg_quant_matrices) 
{

	set_intra_matrix(mpeg_quant_matrices, default_intra_matrix);
	set_inter_matrix(mpeg_quant_matrices, default_inter_matrix);
}

⌨️ 快捷键说明

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