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

📄 mblockcode.c

📁 DM642的mpeg4编码
💻 C
字号:
#include "mblockcode.h"
#include "../mpeg4/mpeg4vlc.h"
#include "../mpeg4/mpeg4.h"

static const int iDQtab[5] = {1, 0, -1, 2, 3};
#define DQ_VALUE2INDEX(value)  iDQtab[(value)+2]

static const short default_acdc_values[15] = 
	{ 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };


static int CalcAcdcCoeff(MacroBlock * pMB,
						 short block,
						 short qcoeff[64],
						 unsigned int iDcScaler,
						 short predictors[8])
{
	short *pCurrent = pMB->PredictValue[block];
	int i;
	int S1 = 0, S2 = 0;

	pCurrent[0] = qcoeff[0] * iDcScaler;
	pCurrent[0] = CLIP(pCurrent[0], -2048, 2047);
	for (i = 1; i < 8; i++) 
	{
		pCurrent[i] = qcoeff[i];
		pCurrent[i + 7] = qcoeff[i * 8];
	}

	qcoeff[0] = qcoeff[0] - predictors[0];

  	if( pMB->PredictDirection[block] == VERTICAL_DIRECTION)
	{
		/* VERTICAL_DIRECTION */
		for (i = 1; i < 8; i++)
		{
			short level;

			level = qcoeff[i];
			S2 += abs(level);
			level -= predictors[i];
			S1 += abs(level);
			predictors[i] = level;
		}
		
	} 
	else
	{	
		
		for (i = 1; i < 8; i++) 
		{
			short level;

			level = qcoeff[i * 8];
			S2 += abs(level);
			level -= predictors[i];
			S1 += abs(level);
			predictors[i] = level;
		}
		
	}
	return S2 - S1;
}

//***********************************************************************************************
//函 数 名:PredictIntraMB
//函数功能:宏块帧内预测
//形式参数:pMB     第一个宏块结构体指针
//		    iMBWidth  行宏块数目
//			iQuant     量化系数
//			x,y        当前宏块的行列标号
//			data       系数块

//返 回 值:void
//***********************************************************************************************

static void PredictIntraMB(MacroBlock* pMB, short iMBWidth, short iQuant, short x, short y, short* data)
{
    int		iMBx = x;	//当前宏块x值
	short     i, j;
	int		iMBNo = y * iMBWidth + x;	//当前宏块号

	short     iDcScalar;

	int     iTotal = 0;

	short     iFlag;
	
	short     Predictors[6][8];
	
	const short *pLeft = default_acdc_values;
	const short *pTop = default_acdc_values;
	const short *pDiag = default_acdc_values;

	short *left, *top, *diag, *current;
	
	int left_quant = iQuant;
	int top_quant = iQuant;

	pMB[iMBNo].pred_mode = INTRA_DCAC_PRED;

  	for (i = 0; i < 6; i++)
	{
			left = top = diag = current = NULL;

            pLeft = default_acdc_values;
	        pTop = default_acdc_values;
	        pDiag = default_acdc_values;
			
			//左
			if ( iMBx && iMBNo >= 1 && (pMB[iMBNo-1].mb_type == MB_INTRA || pMB[iMBNo-1].mb_type == MB_INTRA_Q) )
			{
				left = pMB[iMBNo-1].PredictValue[0];
				left_quant = pMB[iMBNo-1].quant;
			}
			//上
			if ( iMBNo >= iMBWidth && (pMB[iMBNo-iMBWidth].mb_type == MB_INTRA || pMB[iMBNo-iMBWidth].mb_type == MB_INTRA_Q) )
			{				
				top = pMB[iMBNo-iMBWidth].PredictValue[0];
				top_quant = pMB[iMBNo-iMBWidth].quant;
			}
			//对角
			if (iMBx && iMBNo >= iMBWidth + 1 && (pMB[iMBNo-iMBWidth-1].mb_type == MB_INTRA || pMB[iMBNo-iMBWidth-1].mb_type == MB_INTRA_Q)) 
			{
				diag = pMB[iMBNo-iMBWidth-1].PredictValue[0];
			}
			
			current = pMB[iMBNo].PredictValue[0];
    
  
		   iFlag = (i<4)? 1 : 0;

		   iDcScalar = GetDcScaler(iQuant, iFlag);

		    switch (i) 
			{
			case 0:
				if (left)
				{
					pLeft = left + MB_PREDICT;		
				}
				if (top)
				{
					pTop = top + (MB_PREDICT << 1);
				}
				if (diag)
				{
					pDiag = diag + 3 * MB_PREDICT;
				}
				break;		
			case 1:
				pLeft = current;
				left_quant = iQuant;		
				if (top) 
				{
					pTop = top + 3 * MB_PREDICT;
					pDiag = top + (MB_PREDICT << 1);
				}
				break;		
			case 2:
				if (left)
				{
					pLeft = left + 3 * MB_PREDICT;
					pDiag = left + MB_PREDICT;
				}		
				pTop = current;
				top_quant = iQuant;		
				break;		
			case 3:
				pLeft = current + (MB_PREDICT << 1);
				left_quant = iQuant;		
				pTop = current + MB_PREDICT ;
				top_quant = iQuant;		
				pDiag = current;		
				break;		
			case 4:
				if (left)
				{
					pLeft = left + (MB_PREDICT << 2);
				}
				if (top)
				{
					pTop = top + (MB_PREDICT << 2);
				}
				if (diag)
				{
					pDiag = diag + (MB_PREDICT << 2);
				}
				break;		
			case 5:
				if (left)
				{
					pLeft = left + 5 * MB_PREDICT;
				}
				if (top)
				{
					pTop = top + 5 * MB_PREDICT;
				}
				if (diag)
				{
					pDiag = diag + 5 * MB_PREDICT;
				}
				break;
			default:
				break;
			}

			/* get the predict direction */
			if (ABS(pLeft[0] - pDiag[0]) < ABS(pDiag[0] - pTop[0])) 
			{
				pMB[iMBNo].PredictDirection[i] = VERTICAL_DIRECTION;	/* vertical */
				Predictors[i][0] = DIV_DIV(pTop[0], iDcScalar);
				if (pMB[iMBNo].pred_mode == INTRA_DCAC_PRED)
				{
					/* INTRA_ACDC_PRED */
					Predictors[i][1] = rescale(top_quant, iQuant, pTop[1]);
					Predictors[i][2] = rescale(top_quant, iQuant, pTop[2]);
					Predictors[i][3] = rescale(top_quant, iQuant, pTop[3]);
					Predictors[i][4] = rescale(top_quant, iQuant, pTop[4]);
					Predictors[i][5] = rescale(top_quant, iQuant, pTop[5]);
					Predictors[i][6] = rescale(top_quant, iQuant, pTop[6]);
					Predictors[i][7] = rescale(top_quant, iQuant, pTop[7]);
				}
			} 
			else 
			{
				pMB[iMBNo].PredictDirection[i] = HORIZON_DIRECTION;	/* horizontal */
				Predictors[i][0] = DIV_DIV(pLeft[0], iDcScalar);
				if (pMB[iMBNo].pred_mode == INTRA_DCAC_PRED)
				{  
					/* INTRA_ACDC_PRED */
					Predictors[i][1] = rescale(left_quant, iQuant, pLeft[8]);
					Predictors[i][2] = rescale(left_quant, iQuant, pLeft[9]);
					Predictors[i][3] = rescale(left_quant, iQuant, pLeft[10]);
					Predictors[i][4] = rescale(left_quant, iQuant, pLeft[11]);
					Predictors[i][5] = rescale(left_quant, iQuant, pLeft[12]);
					Predictors[i][6] = rescale(left_quant, iQuant, pLeft[13]);
					Predictors[i][7] = rescale(left_quant, iQuant, pLeft[14]);
				}
			}
	        /*  rebuild the DC coeff and AC coeff  */
			iTotal += CalcAcdcCoeff(&pMB[iMBNo], i, data+i*64, iDcScalar, Predictors[i]);

    }
     
	//如果只有DC预测
	if (iTotal <=  0)
	{
		pMB[iMBNo].pred_mode = INTRA_DC_PRED;
	}
	else 
	{
         for (j = 0; j < 6; j++)
		 {
			 if (pMB[iMBNo].PredictDirection[j] == HORIZON_DIRECTION)
			 {
				   /* HORIZON_DIRECTION */
				 	data[8]  = Predictors[j][1];
					data[16] = Predictors[j][2];
					data[24] = Predictors[j][3];
					data[32] = Predictors[j][4];
					data[40] = Predictors[j][5];
					data[48] = Predictors[j][6];
					data[56] = Predictors[j][7];
			 }
			 else 
			 {
                  	data[1] = Predictors[j][1];
					data[2] = Predictors[j][2];
					data[3] = Predictors[j][3];
					data[4] = Predictors[j][4];
					data[5] = Predictors[j][5];
					data[6] = Predictors[j][6];
					data[7] = Predictors[j][7];
			 }
			 data += 64;
		 }
	}
	
	return;
}

//***********************************************************************************************
//函 数 名:PutIntraMBToBitstream()
//函数功能:将宏块写入码流
//形式参数: bs  比特流指针
//	         pEncoder  编码器结构体指针
//           pCurMB  当前宏块指针
//           iCbp   宏块编码类型
//           data   系数矩阵

//返 回 值:void
//***********************************************************************************************

static short PutIntraMBToBitstream(Stream* bs, Encoder* pEncoder, MacroBlock* pCurMB, short iCbp, short* data)
{
	short iMcbpc; 
	short i;
	short iCbpy = iCbp>>2;
	short iMBMode = pCurMB->mb_type;

	unsigned int iBits;

	iBits = GetStreamPosition(bs);

	if (pEncoder->pCurFrameInfo->vop_coding_type == I_VOP)
	{
       iMcbpc = ((iMBMode >> 1) & 3) | ((iCbp & 3)<<2) ;
	   StreamPutBits(bs, IntraMBTypeTab[iMcbpc].code, IntraMBTypeTab[iMcbpc].len);
	}
	else
	{
       /* not_coded */
	   StreamPutBit(bs, 0);	
	   iMcbpc = ( ((iCbp & 3)<<3) | (iMBMode & 7) );
       StreamPutBits(bs, InterMBTypeTab[iMcbpc].code, InterMBTypeTab[iMcbpc].len);
	}

	iBits = GetStreamPosition(bs);

	/*   ac_pred_flag  */
	if (pCurMB->pred_mode == INTRA_DCAC_PRED)
	{
		StreamPutBit(bs, 1);
	}
	else
	{
		StreamPutBit(bs, 0);
	}

	/*  cbpy  */
	StreamPutBits(bs, ChroTypeTab[iCbpy].code, ChroTypeTab[iCbpy].len);

	/*  dquant  */
	if (iMBMode == MB_INTRA_Q)
	{
		StreamPutBits(bs, DQ_VALUE2INDEX(pCurMB->dquant), 2);
	}

	/*  code dct coeff */
	for (i = 0; i < 6; i++)
	{
		if (i < 4)
		{
			/*  dct_dc_size_luminance  */
			StreamPutBits(bs, LumTab[data[i * 64 + 0] + 255].code, LumTab[data[i * 64 + 0] + 255].len);
		}
		else 
		{
			StreamPutBits(bs, chrotab[data[i * 64 + 0] + 255].code, chrotab[data[i * 64 + 0] + 255].len);
		}

		if (iCbp & (1<<(5-i)) )
		{
			int ScanMode;
            if (pEncoder->pCurFrameInfo->alternate_vertical_scan_flag)
			{
               ScanMode = 2;
			}
			else if (pCurMB->pred_mode == INTRA_DCAC_PRED) 
			{
				ScanMode = (pCurMB->PredictDirection[i] == VERTICAL_DIRECTION)? 1 : 2; 
			}
			else 
			{
				/* default: zizag  */
				ScanMode = 0;
			}
     
			CodeCoeffIntra(bs, data+i*64, Table[ScanMode]);

			GetStreamPosition(bs);

		}
		
	}

	return 1;
}

//***********************************************************************************************
//函 数 名:RecoverIntraMB()
//函数功能:预测恢复
//形式参数: pCurMB  当前宏块指针
//			 data     系数块

//返 回 值:void
//***********************************************************************************************
static short RecoverIntraMB(MacroBlock* pCurMB, short* data)
{
	int i;
	int iDcScaler;
	short *Block, *Predictors;

	short iFlag;

	for (i = 0; i < 6; i++)
	{
		iFlag = (i < 4)? 1: 0;

		iDcScaler = GetDcScaler(pCurMB->quant, iFlag);

		Block = &data[i * 64];
		Block[0] = DIV_DIV( pCurMB->PredictValue[i][0], iDcScaler );

		Predictors = pCurMB->PredictValue[i];

		if (pCurMB->pred_mode == INTRA_DCAC_PRED)
		{
			if (pCurMB->PredictDirection[i] == VERTICAL_DIRECTION)
			{
				Block[1] = Predictors[1];
				Block[2] = Predictors[2];
				Block[3] = Predictors[3];
				Block[4] = Predictors[4];
				Block[5] = Predictors[5];
				Block[6] = Predictors[6];
				Block[7] = Predictors[7];
			}
			else
			{
				Block[8]  = Predictors[8];
				Block[16] = Predictors[9];
				Block[24] = Predictors[10];
				Block[32] = Predictors[11];
				Block[40] = Predictors[12];
				Block[48] = Predictors[13];
				Block[56] = Predictors[14];
			}
		}
	}

	return 0;
} 

//***********************************************************************************************
//函 数 名:CodeIntraMB
//函数功能:
//形式参数:bs:
//		  :pEncoder:
//		  :
//
//
//
//返 回 值:void
//***********************************************************************************************
void CodeIntraMB(Stream* bs, Encoder* pEncoder, MacroBlock* pCurMB, short x, short y, short* data)
{
	short iMBWidth = pEncoder->pCurFrameInfo->vop_width/16;
	
    short iCBP;

	MacroBlock* pMB = pEncoder->pCurFrameInfo->pMB;

	/*  intra predict  */
	PredictIntraMB(pMB, iMBWidth, pCurMB->quant, x, y, data);
    
	/*  coding macroblock DCT coeff and MV  */
	iCBP = GetMBlockCBP(data, pCurMB->mb_type);

    PutIntraMBToBitstream(bs, pEncoder, pCurMB, iCBP, data);

	/*  recover intra predict  */
	RecoverIntraMB(pCurMB, data);
}

static void CodeVector(Stream * bs, int value, int f_code)
{
	const int scale_factor = 1 << (f_code - 1);
	const int cmp = scale_factor << 5;

	if (value < (-1 * cmp))
	{
		value += 64 * scale_factor;
    }

	if (value > (cmp - 1))
	{
		value -= 64 * scale_factor;
	}

	if (value == 0) 
	{
		StreamPutBits(bs, mb_motion_table[32].code, mb_motion_table[32].len);
	} 
	else
	{
		unsigned short length, code, mv_res, sign;

		length = 16 << f_code;
		f_code--;

		sign = (value < 0);

		if (value >= length)
		{
			value -= 2 * length;
		}
		else if (value < -length)
		{
			value += 2 * length;
		}

		if (sign)
		{
			value = -value;
        }

		value--;
		mv_res = value & ((1 << f_code) - 1);
		code = ((value - mv_res) >> f_code) + 1;

		if (sign)
		{
			code = -code;
        }

		code += 32;
		StreamPutBits(bs, mb_motion_table[code].code,
						 mb_motion_table[code].len);

		if (f_code)
		{
			StreamPutBits(bs, mv_res, f_code);
		}
	}
}


void CodeInterMB(Stream* bs, Encoder* pEncoder, MacroBlock* pCurMB, short x, short y, short* data)
{
	int i;
	unsigned int iMcbpc, iCbpy;
	unsigned short *scan_table = pEncoder->pCurFrameInfo->alternate_vertical_scan_flag ? Table[2] : Table[0];

    /* write the bitstream */
	StreamPutBit(bs, 0);

	iMcbpc = (pCurMB->mb_type & 7) | ((pCurMB->cbp & 3) << 3);
	iCbpy = 15 - (pCurMB->cbp >> 2);

	/* write mcbpc */
	StreamPutBits(bs, InterMBTypeTab[iMcbpc].code,InterMBTypeTab[iMcbpc].len);

	/* write cbpy */
	StreamPutBits(bs, ChroTypeTab[iCbpy].code, ChroTypeTab[iCbpy].len);

	/* write dquant */
	if (pCurMB->mb_type == MB_INTER_Q)
	{
		StreamPutBits(bs, DQ_VALUE2INDEX(pCurMB->dquant), 2);
	}	

	CodeVector(bs, pCurMB->PredMv[0].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
	CodeVector(bs, pCurMB->PredMv[0].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
	
	if (pCurMB->mb_type == MB_INTER_4V)
	{
        CodeVector(bs, pCurMB->PredMv[1].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
		CodeVector(bs, pCurMB->PredMv[1].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
		CodeVector(bs, pCurMB->PredMv[2].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
		CodeVector(bs, pCurMB->PredMv[2].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
		CodeVector(bs, pCurMB->PredMv[3].x, pEncoder->pCurFrameInfo->vop_fcode_forward);
		CodeVector(bs, pCurMB->PredMv[3].y, pEncoder->pCurFrameInfo->vop_fcode_forward);
	}

	/* code block coeffs */
	for (i = 0; i < 6; i++)
	{
		if (pCurMB->cbp & (1 << (5 - i))) 
		{
			CodeCoeffInter(bs, &data[i * 64], scan_table);
		}
    }
	
	return ;
	 
}




⌨️ 快捷键说明

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