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

📄 mvmb.c

📁 优化过的xvid1.1.2源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>
#include <string.h>
#include "MVGlobal.h"
#include "MVBitstream.h"
#include "MVCommon.h"
#include "MVMc.h"
#include "MVIdct.h"
#include "MVMb.h"
#include "MVBlock.h"
#include "MVMv.h"

extern VLC const		mcbpc_intra_table[64];
extern VLC const		cbpy_table[64];
extern const int16_t    default_acdc_values[15];
extern VLC const		dc_lum_tab[];
extern const VLC		dcy_tab[511];
extern VLC const		mcbpc_inter_table[257];
extern const int32_t	dquant_table[4];
extern const uint32_t	roundtab_76[16];
extern const uint32_t	roundtab_79[4];

int get_mcbpc_intra(Bitstream * bs)
{

	uint32_t index;

	index = BitstreamShowBits(bs, 9);
	index >>= 3;

	BitstreamSkip(bs, mcbpc_intra_table[index].len);

	return mcbpc_intra_table[index].code;

}

int get_mcbpc_inter(Bitstream * bs)
{

	uint32_t index;

	index = MIN(BitstreamShowBits(bs, 9), 256);

	BitstreamSkip(bs, mcbpc_inter_table[index].len);

	return mcbpc_inter_table[index].code;

}

int get_cbpy(Bitstream * bs, int intra)
{

	int cbpy;
	uint32_t index = BitstreamShowBits(bs, 6);

	BitstreamSkip(bs, cbpy_table[index].len);
	cbpy = cbpy_table[index].code;

	if (!intra)
		cbpy = 15 - cbpy;

	return cbpy;
}

int32_t get_mbtype(Bitstream * bs)
{
  int32_t mb_type;

  for (mb_type = 0; mb_type <= 3; mb_type++)
    if (BitstreamGetBit(bs))
      return (mb_type);

  return -1;
}


int get_dc_size_lum(Bitstream * bs)
{

	int code, i;

	code = BitstreamShowBits(bs, 11);

	for (i = 11; i > 3; i--) {
		if (code == 1) {
			BitstreamSkip(bs, i);
			return i + 1;
		}
		code >>= 1;
	}

	BitstreamSkip(bs, dc_lum_tab[code].len);
	
	return dc_lum_tab[code].code;
}

int get_dc_size_chrom(Bitstream * bs)
{

	uint32_t code, i;
	code = BitstreamShowBits(bs, 12);

	for (i = 12; i > 2; i--) {
		if (code == 1) {
			BitstreamSkip(bs, i);
			return i;
		}
		code >>= 1;
	}

	return 3 - BitstreamGetBits(bs, 2);

}

int get_dc_dif(Bitstream * bs, uint32_t dc_size)
{

	int code = BitstreamGetBits(bs, dc_size);
	int msb = code >> (dc_size - 1);

	if (msb == 0)
		return (-1 * (code ^ ((1 << dc_size) - 1)));

	return code;

}

void predict_acdc(MACROBLOCK * pMBs,
					 uint32_t x,
					 uint32_t y,
					 uint32_t mb_width,
					 uint32_t block,
					 int16_t qcoeff[64],
					 uint32_t current_quant,
					 int32_t iDcScaler,
					 int16_t predictors[8],
					 const int bound)

{
	const int mbpos = (y * mb_width) + x;
	int16_t *left, *top, *diag, *current;

	int32_t left_quant = current_quant;
	int32_t top_quant = current_quant;

	const int16_t *pLeft = default_acdc_values;
	const int16_t *pTop = default_acdc_values;
	const int16_t *pDiag = default_acdc_values;

	uint32_t index = x + y * mb_width;	/* current macroblock */
	int *acpred_direction = &pMBs[index].acpred_directions[block];
	uint32_t i;

	left = top = diag = current = NULL;


	if (x && mbpos >= bound + 1  &&
		(pMBs[index - 1].mode == MODE_INTRA ||
		 pMBs[index - 1].mode == MODE_INTRA_Q)) 
	{

		left = (int16_t*)pMBs[index - 1].pred_values[0];
		left_quant = pMBs[index - 1].quant;
	}
	/* top macroblock */

	if (mbpos >= bound + (int)mb_width &&
		(pMBs[index - mb_width].mode == MODE_INTRA ||
		 pMBs[index - mb_width].mode == MODE_INTRA_Q)) 
	{

		top = (int16_t*)pMBs[index - mb_width].pred_values[0];
		top_quant = pMBs[index - mb_width].quant;
	}
	/* diag macroblock */

	if (x && mbpos >= bound + (int)mb_width + 1 &&
		(pMBs[index - 1 - mb_width].mode == MODE_INTRA ||
		 pMBs[index - 1 - mb_width].mode == MODE_INTRA_Q)) 
	{

		diag = (int16_t*)pMBs[index - 1 - mb_width].pred_values[0];
	}

	current = (int16_t*)pMBs[index].pred_values[0];

	switch (block) 
	{

		case 0:
			if (left)
				pLeft = left + MBPRED_SIZE;

			if (top)
				pTop = top + (MBPRED_SIZE << 1);

			if (diag)
				pDiag = diag + 3 * MBPRED_SIZE;

			break;

		case 1:
			pLeft = current;
			left_quant = current_quant;

			if (top)
			{
				pTop = top + 3 * MBPRED_SIZE;
				pDiag = top + (MBPRED_SIZE << 1);
			}
			break;

		case 2:
			if (left) 
			{
				pLeft = left + 3 * MBPRED_SIZE;
				pDiag = left + MBPRED_SIZE;
			}

			pTop = current;
			top_quant = current_quant;

			break;

		case 3:
			pLeft = current + (MBPRED_SIZE << 1);
			left_quant = current_quant;

			pTop = current + MBPRED_SIZE;
			top_quant = current_quant;

			pDiag = current;

			break;

		case 4:
			if (left)
				pLeft = left + (MBPRED_SIZE << 2);
			if (top)
				pTop = top + (MBPRED_SIZE << 2);
			if (diag)
				pDiag = diag + (MBPRED_SIZE << 2);
			break;

		case 5:
			if (left)
				pLeft = left + 5 * MBPRED_SIZE;
			if (top)
				pTop = top + 5 * MBPRED_SIZE;
			if (diag)
				pDiag = diag + 5 * MBPRED_SIZE;
			break;
	}

	if (abs(pLeft[0] - pDiag[0]) < abs(pDiag[0] - pTop[0])) 
	{
		*acpred_direction = 1;	/* vertical */
		predictors[0] = DIV_DIV(pTop[0], iDcScaler);
		for (i = 1; i < 8; i++) 
		{
			predictors[i] = rescale(top_quant, current_quant, pTop[i]);
		}
	} 
	else
	{
		*acpred_direction = 2;	/* horizontal */
		predictors[0] = DIV_DIV(pLeft[0], iDcScaler);
		for (i = 1; i < 8; i++) 
		{
			predictors[i] = rescale(left_quant, current_quant, pLeft[i + 7]);
		}
	}

	return ;
}

void add_acdc(MACROBLOCK * pMB, uint32_t block,
		 	  int16_t dct_codes[64], uint32_t iDcScaler,
		 	  int16_t predictors[8], const int bsversion)
{
	uint8_t acpred_direction = pMB->acpred_directions[block];
	int16_t *pCurrent = (int16_t*)pMB->pred_values[block];
	uint32_t i;

	dct_codes[0] += predictors[0];	/* dc prediction */
	pCurrent[0] = dct_codes[0]*iDcScaler;
	if (!bsversion || bsversion > BS_VERSION_BUGGY_DC_CLIPPING)
	{
		pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
	}

	if (acpred_direction == 1)
	{
		for (i = 1; i < 8; i++)
		{
			int level = dct_codes[i] + predictors[i];

			dct_codes[i] = level;
			pCurrent[i] = level;
			pCurrent[i + 7] = dct_codes[i * 8];
		}
	}
	else
	    if(acpred_direction == 2)
	    {
				for (i = 1; i < 8; i++)
				{
					int level = dct_codes[i * 8] + predictors[i];
					dct_codes[i * 8] = level;
					pCurrent[i + 7] = level;
					pCurrent[i] = dct_codes[i];
				}
		}
		else
		{
				for (i = 1; i < 8; i++)
				{
					pCurrent[i] = dct_codes[i];
					pCurrent[i + 7] = dct_codes[i * 8];
				}
		}
}

void decoder_mbintra(DECODER * dec,
							        MACROBLOCK * pMB,
							        const uint32_t x_pos,
							        const uint32_t y_pos,
							        const uint32_t acpred_flag,
							        const uint32_t cbp,
							        Bitstream * bs,
							        const uint32_t quant,
							        const uint32_t intra_dc_threshold,
							        const unsigned int bound)
{
          /* wuhaibin 2007-01-17*/
	      uint8_t block_header  [1024];
		  uint8_t data_header   [1024];
          int16_t* block = (int16_t*)((uint32_t)(block_header + CACHE_LINE - 1)
			                          &(~(uint32_t)(CACHE_LINE - 1)));
          int16_t* data = (int16_t*)((uint32_t)(data_header + CACHE_LINE - 1)
			                          &(~(uint32_t)(CACHE_LINE - 1)));
          
	      //DECLARE_ALIGNED_MATRIX(block, 6, 64, int16_t, CACHE_LINE);
		  //DECLARE_ALIGNED_MATRIX(data, 6, 64, int16_t, CACHE_LINE);
		
		  uint32_t stride = dec->edged_width;
		  uint32_t stride2 = stride / 2;
		  uint32_t next_block = stride * 8;
		  uint32_t i;
		  uint32_t iQuant = pMB->quant;
		  uint8_t *pY_Cur, *pU_Cur, *pV_Cur;
		
		  pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
		  pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
		  pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
		
		  memset(block, 0, 6 * 64 * sizeof(int16_t)); /* clear */

		  for (i = 0; i < 6; i++)
		  {
		    uint32_t iDcScaler = get_dc_scaler(iQuant, i < 4);
		    int16_t predictors[8];
		    int start_coeff;
		
		    predict_acdc(dec->mbs, x_pos, y_pos, dec->mb_width, i, &block[i * 64],
		                 iQuant, iDcScaler, predictors, bound);
		    if (!acpred_flag)
		    {
		      pMB->acpred_directions[i] = 0;
		    }
		    
		    if (quant < intra_dc_threshold)
		    {
		      int dc_size;
		      int dc_dif;
		
		      dc_size = i < 4 ? get_dc_size_lum(bs) : get_dc_size_chrom(bs);
		      dc_dif = dc_size ? get_dc_dif(bs, dc_size) : 0;
		
		      if (dc_size > 8)
		      {
		        BitstreamSkip(bs, 1); /* marker */
		      }
		
		      block[i * 64 + 0] = dc_dif;
		      start_coeff = 1;
		
		   }
		   else
       {
          start_coeff = 0;
       }

		   if (cbp & (1 << (5 - i))) /* coded */
		   {
		          int direction = dec->alternate_vertical_scan ?
		                          2 : pMB->acpred_directions[i];
		
		          get_intra_block(bs, &block[i * 64], direction, start_coeff);
		   }
		    
   		 add_acdc(pMB, i, &block[i * 64], iDcScaler, predictors, dec->bs_version);
       if (dec->quant_type == 0)
    	 {
         dequant_h263_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices);
       }
       else
       {
         dequant_mpeg_intra(&data[i * 64], &block[i * 64], iQuant, iDcScaler, dec->mpeg_quant_matrices);
       }
    
       idct_int32((short * const)&data[i * 64]);
     }

 		 if(dec->interlacing && pMB->field_dct)
     {
        next_block = stride;
    		stride *= 2;
  	 }

		 transfer_16to8copy(pY_Cur, &data[0 * 64], stride);
		 transfer_16to8copy(pY_Cur + 8, &data[1 * 64], stride);
		 transfer_16to8copy(pY_Cur + next_block, &data[2 * 64], stride);
		 transfer_16to8copy(pY_Cur + 8 + next_block, &data[3 * 64], stride);
		 transfer_16to8copy(pU_Cur, &data[4 * 64], stride2);
		 transfer_16to8copy(pV_Cur, &data[5 * 64], stride2);
 
}

void decoder_mbinter(DECODER * dec,
							        const MACROBLOCK * pMB,
							        const uint32_t x_pos,
							        const uint32_t y_pos,
							        const uint32_t cbp,
							        Bitstream * bs,
							        const uint32_t rounding,
							        const int ref,
											const int bvop)
{
  uint32_t stride = dec->edged_width;
  uint32_t stride2 = stride / 2;
  uint32_t i;

  uint8_t *pY_Cur, *pU_Cur, *pV_Cur;

  int uv_dx, uv_dy;
  VECTOR mv[4]; /* local copy of mvs */

  pY_Cur = dec->cur.y + (y_pos << 4) * stride + (x_pos << 4);
  pU_Cur = dec->cur.u + (y_pos << 3) * stride2 + (x_pos << 3);
  pV_Cur = dec->cur.v + (y_pos << 3) * stride2 + (x_pos << 3);
  for (i = 0; i < 4; i++)
    mv[i] = pMB->mvs[i];

⌨️ 快捷键说明

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