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

📄 mbtransquant.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * *  XVID MPEG-4 VIDEO CODEC *  - MB Transfert/Quantization functions - * *  Copyright(C) 2001-2003  Peter Ross <pross@xvid.org> *               2001-2003  Michael Militzer <isibaar@xvid.org> *               2003       Edouard Gomez <ed.gomez@free.fr> * *  This program is free software ; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation ; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY ; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program ; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * * $Id: mbtransquant.c,v 1.29 2005/11/22 10:23:01 suxen_drol Exp $ * ****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "../portab.h"#include "mbfunctions.h"#include "../global.h"#include "mem_transfer.h"#include "timer.h"#include "../bitstream/mbcoding.h"#include "../bitstream/zigzag.h"#include "../dct/fdct.h"#include "../dct/idct.h"#include "../quant/quant.h"#include "../encoder.h"#include  "../quant/quant_matrix.h"MBFIELDTEST_PTR MBFieldTest;/* * Skip blocks having a coefficient sum below this value. This value will be * corrected according to the MB quantizer to avoid artifacts for quant==1 */#define PVOP_TOOSMALL_LIMIT 1#define BVOP_TOOSMALL_LIMIT 3/***************************************************************************** * Local functions ****************************************************************************//* permute block and return field dct choice */static __inline uint32_tMBDecideFieldDCT(int16_t data[6 * 64]){	uint32_t field = MBFieldTest(data);	if (field)		MBFrameToField(data);	return field;}/* Performs Forward DCT on all blocks */static __inline voidMBfDCT(const MBParam * const pParam,	   const FRAMEINFO * const frame,	   MACROBLOCK * const pMB,	   uint32_t x_pos,	   uint32_t y_pos,	   int16_t data[6 * 64]){	/* Handles interlacing */	start_timer();	pMB->field_dct = 0;	if ((frame->vol_flags & XVID_VOL_INTERLACING) &&		(x_pos>0) && (x_pos<pParam->mb_width-1) &&		(y_pos>0) && (y_pos<pParam->mb_height-1)) {		pMB->field_dct = MBDecideFieldDCT(data);	}	stop_interlacing_timer();	/* Perform DCT */	start_timer();	fdct((short * const)&data[0 * 64]);	fdct((short * const)&data[1 * 64]);	fdct((short * const)&data[2 * 64]);	fdct((short * const)&data[3 * 64]);	fdct((short * const)&data[4 * 64]);	fdct((short * const)&data[5 * 64]);	stop_dct_timer();}/* Performs Inverse DCT on all blocks */static __inline voidMBiDCT(int16_t data[6 * 64],	   const uint8_t cbp){	start_timer();	if(cbp & (1 << (5 - 0))) idct((short * const)&data[0 * 64]);	if(cbp & (1 << (5 - 1))) idct((short * const)&data[1 * 64]);	if(cbp & (1 << (5 - 2))) idct((short * const)&data[2 * 64]);	if(cbp & (1 << (5 - 3))) idct((short * const)&data[3 * 64]);	if(cbp & (1 << (5 - 4))) idct((short * const)&data[4 * 64]);	if(cbp & (1 << (5 - 5))) idct((short * const)&data[5 * 64]);	stop_idct_timer();}/* Quantize all blocks -- Intra mode */static __inline voidMBQuantIntra(const MBParam * pParam,			 const FRAMEINFO * const frame,			 const MACROBLOCK * pMB,			 int16_t qcoeff[6 * 64],			 int16_t data[6*64]){	int mpeg;	int scaler_lum, scaler_chr;	quant_intraFuncPtr const quant[2] =		{			quant_h263_intra,			quant_mpeg_intra		};	mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);	scaler_lum = get_dc_scaler(pMB->quant, 1);	scaler_chr = get_dc_scaler(pMB->quant, 0);	/* Quantize the block */	start_timer();	quant[mpeg](&data[0 * 64], &qcoeff[0 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);	quant[mpeg](&data[1 * 64], &qcoeff[1 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);	quant[mpeg](&data[2 * 64], &qcoeff[2 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);	quant[mpeg](&data[3 * 64], &qcoeff[3 * 64], pMB->quant, scaler_lum, pParam->mpeg_quant_matrices);	quant[mpeg](&data[4 * 64], &qcoeff[4 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);	quant[mpeg](&data[5 * 64], &qcoeff[5 * 64], pMB->quant, scaler_chr, pParam->mpeg_quant_matrices);	stop_quant_timer();}/* DeQuantize all blocks -- Intra mode */static __inline voidMBDeQuantIntra(const MBParam * pParam,			   const int iQuant,			   int16_t qcoeff[6 * 64],			   int16_t data[6*64]){	int mpeg;	int scaler_lum, scaler_chr;	quant_intraFuncPtr const dequant[2] =		{			dequant_h263_intra,			dequant_mpeg_intra		};	mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);	scaler_lum = get_dc_scaler(iQuant, 1);	scaler_chr = get_dc_scaler(iQuant, 0);	start_timer();	dequant[mpeg](&qcoeff[0 * 64], &data[0 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);	dequant[mpeg](&qcoeff[1 * 64], &data[1 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);	dequant[mpeg](&qcoeff[2 * 64], &data[2 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);	dequant[mpeg](&qcoeff[3 * 64], &data[3 * 64], iQuant, scaler_lum, pParam->mpeg_quant_matrices);	dequant[mpeg](&qcoeff[4 * 64], &data[4 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);	dequant[mpeg](&qcoeff[5 * 64], &data[5 * 64], iQuant, scaler_chr, pParam->mpeg_quant_matrices);	stop_iquant_timer();}static intdct_quantize_trellis_c(int16_t *const Out,					   const int16_t *const In,					   int Q,					   const uint16_t * const Zigzag,					   const uint16_t * const QuantMatrix,					   int Non_Zero,					   int Sum);/* Quantize all blocks -- Inter mode */static __inline uint8_tMBQuantInter(const MBParam * pParam,			 const FRAMEINFO * const frame,			 const MACROBLOCK * pMB,			 int16_t data[6 * 64],			 int16_t qcoeff[6 * 64],			 int bvop,			 int limit){	int i;	uint8_t cbp = 0;	int sum;	int code_block, mpeg;	quant_interFuncPtr const quant[2] =		{			quant_h263_inter,			quant_mpeg_inter		};	mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);	for (i = 0; i < 6; i++) {		/* Quantize the block */		start_timer();		sum = quant[mpeg](&qcoeff[i*64], &data[i*64], pMB->quant, pParam->mpeg_quant_matrices);		if(sum && (pMB->quant > 2) && (frame->vop_flags & XVID_VOP_TRELLISQUANT)) {			const uint16_t *matrix;			const static uint16_t h263matrix[] =				{					16, 16, 16, 16, 16, 16, 16, 16,					16, 16, 16, 16, 16, 16, 16, 16,					16, 16, 16, 16, 16, 16, 16, 16,					16, 16, 16, 16, 16, 16, 16, 16,					16, 16, 16, 16, 16, 16, 16, 16,					16, 16, 16, 16, 16, 16, 16, 16,					16, 16, 16, 16, 16, 16, 16, 16,					16, 16, 16, 16, 16, 16, 16, 16				};			matrix = (mpeg)?get_inter_matrix(pParam->mpeg_quant_matrices):h263matrix;			sum = dct_quantize_trellis_c(&qcoeff[i*64], &data[i*64],										 pMB->quant, &scan_tables[0][0],										 matrix,										 63,										 sum);		}		stop_quant_timer();		/*		 * We code the block if the sum is higher than the limit and if the first		 * two AC coefficients in zig zag order are not zero.		 */		code_block = 0;		if ((sum >= limit) || (qcoeff[i*64+1] != 0) || (qcoeff[i*64+8] != 0)) {			code_block = 1;		} else {			if (bvop && (pMB->mode == MODE_DIRECT || pMB->mode == MODE_DIRECT_NO4V)) {				/* dark blocks prevention for direct mode */				if ((qcoeff[i*64] < -1) || (qcoeff[i*64] > 0))					code_block = 1;			} else {				/* not direct mode */				if (qcoeff[i*64] != 0)					code_block = 1;			}		}		/* Set the corresponding cbp bit */		cbp |= code_block << (5 - i);	}	return(cbp);}/* DeQuantize all blocks -- Inter mode */static __inline voidMBDeQuantInter(const MBParam * pParam,			   const int iQuant,			   int16_t data[6 * 64],			   int16_t qcoeff[6 * 64],			   const uint8_t cbp){	int mpeg;	quant_interFuncPtr const dequant[2] =		{			dequant_h263_inter,			dequant_mpeg_inter		};	mpeg = !!(pParam->vol_flags & XVID_VOL_MPEGQUANT);	start_timer();	if(cbp & (1 << (5 - 0))) dequant[mpeg](&data[0 * 64], &qcoeff[0 * 64], iQuant, pParam->mpeg_quant_matrices);	if(cbp & (1 << (5 - 1))) dequant[mpeg](&data[1 * 64], &qcoeff[1 * 64], iQuant, pParam->mpeg_quant_matrices);	if(cbp & (1 << (5 - 2))) dequant[mpeg](&data[2 * 64], &qcoeff[2 * 64], iQuant, pParam->mpeg_quant_matrices);	if(cbp & (1 << (5 - 3))) dequant[mpeg](&data[3 * 64], &qcoeff[3 * 64], iQuant, pParam->mpeg_quant_matrices);	if(cbp & (1 << (5 - 4))) dequant[mpeg](&data[4 * 64], &qcoeff[4 * 64], iQuant, pParam->mpeg_quant_matrices);	if(cbp & (1 << (5 - 5))) dequant[mpeg](&data[5 * 64], &qcoeff[5 * 64], iQuant, pParam->mpeg_quant_matrices);	stop_iquant_timer();}typedef void (transfer_operation_8to16_t) (int16_t *Dst, const uint8_t *Src, int BpS);typedef void (transfer_operation_16to8_t) (uint8_t *Dst, const int16_t *Src, int BpS);static __inline voidMBTrans8to16(const MBParam * const pParam,			 const FRAMEINFO * const frame,			 const MACROBLOCK * const pMB,			 const uint32_t x_pos,			 const uint32_t y_pos,			 int16_t data[6 * 64]){	uint32_t stride = pParam->edged_width;	uint32_t stride2 = stride / 2;	uint32_t next_block = stride * 8;	uint8_t *pY_Cur, *pU_Cur, *pV_Cur;	const IMAGE * const pCurrent = &frame->image;	/* Image pointers */	pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);	pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);	pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);	/* Do the transfer */	start_timer();	transfer_8to16copy(&data[0 * 64], pY_Cur, stride);	transfer_8to16copy(&data[1 * 64], pY_Cur + 8, stride);	transfer_8to16copy(&data[2 * 64], pY_Cur + next_block, stride);	transfer_8to16copy(&data[3 * 64], pY_Cur + next_block + 8, stride);	transfer_8to16copy(&data[4 * 64], pU_Cur, stride2);	transfer_8to16copy(&data[5 * 64], pV_Cur, stride2);	stop_transfer_timer();}static __inline voidMBTrans16to8(const MBParam * const pParam,			 const FRAMEINFO * const frame,			 const MACROBLOCK * const pMB,			 const uint32_t x_pos,			 const uint32_t y_pos,			 int16_t data[6 * 64],			 const uint32_t add, /* Must be 1 or 0 */			 const uint8_t cbp){	uint8_t *pY_Cur, *pU_Cur, *pV_Cur;	uint32_t stride = pParam->edged_width;	uint32_t stride2 = stride / 2;	uint32_t next_block = stride * 8;	const IMAGE * const pCurrent = &frame->image;	/* Array of function pointers, indexed by [add] */	transfer_operation_16to8_t  * const functions[2] =		{			(transfer_operation_16to8_t*)transfer_16to8copy,			(transfer_operation_16to8_t*)transfer_16to8add,		};	transfer_operation_16to8_t *transfer_op = NULL;	/* Image pointers */	pY_Cur = pCurrent->y + (y_pos << 4) * stride  + (x_pos << 4);	pU_Cur = pCurrent->u + (y_pos << 3) * stride2 + (x_pos << 3);	pV_Cur = pCurrent->v + (y_pos << 3) * stride2 + (x_pos << 3);	if (pMB->field_dct) {		next_block = stride;		stride *= 2;	}	/* Operation function */	transfer_op = functions[add];	/* Do the operation */	start_timer();	if (cbp&32) transfer_op(pY_Cur,						&data[0 * 64], stride);	if (cbp&16) transfer_op(pY_Cur + 8,					&data[1 * 64], stride);	if (cbp& 8) transfer_op(pY_Cur + next_block,		&data[2 * 64], stride);	if (cbp& 4) transfer_op(pY_Cur + next_block + 8,	&data[3 * 64], stride);	if (cbp& 2) transfer_op(pU_Cur,						&data[4 * 64], stride2);	if (cbp& 1) transfer_op(pV_Cur,						&data[5 * 64], stride2);	stop_transfer_timer();}/***************************************************************************** * Module functions ****************************************************************************/voidMBTransQuantIntra(const MBParam * const pParam,				  const FRAMEINFO * const frame,				  MACROBLOCK * const pMB,				  const uint32_t x_pos,				  const uint32_t y_pos,				  int16_t data[6 * 64],				  int16_t qcoeff[6 * 64]){	/* Transfer data */	MBTrans8to16(pParam, frame, pMB, x_pos, y_pos, data);	/* Perform DCT (and field decision) */	MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);	/* Quantize the block */	MBQuantIntra(pParam, frame, pMB, data, qcoeff);	/* DeQuantize the block */	MBDeQuantIntra(pParam, pMB->quant, data, qcoeff);	/* Perform inverse DCT*/	MBiDCT(data, 0x3F); 	/* Transfer back the data -- Don't add data */	MBTrans16to8(pParam, frame, pMB, x_pos, y_pos, data, 0, 0x3F);}uint8_tMBTransQuantInter(const MBParam * const pParam,				  const FRAMEINFO * const frame,				  MACROBLOCK * const pMB,				  const uint32_t x_pos,				  const uint32_t y_pos,				  int16_t data[6 * 64],				  int16_t qcoeff[6 * 64]){	uint8_t cbp;	uint32_t limit;	/* There is no MBTrans8to16 for Inter block, that's done in motion compensation	 * already */	/* Perform DCT (and field decision) */	MBfDCT(pParam, frame, pMB, x_pos, y_pos, data);	/* Set the limit threshold */	limit = PVOP_TOOSMALL_LIMIT + ((pMB->quant == 1)? 1 : 0);	if (frame->vop_flags & XVID_VOP_CARTOON)

⌨️ 快捷键说明

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