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

📄 text_code_mb.c

📁 实现在linux下的mpeg4编解码
💻 C
字号:
/************************************************************************** *                                                                        * * This code is developed by Adam Li.  This software is an                * * implementation of a part of one or more MPEG-4 Video tools as          * * specified in ISO/IEC 14496-2 standard.  Those intending to use this    * * software module in hardware or software products are advised that its  * * use may infringe existing patents or copyrights, and any such use      * * would be at such party's own risk.  The original developer of this     * * software module and his/her company, and subsequent editors and their  * * companies (including Project Mayo), will have no liability for use of  * * this software or modifications or derivatives thereof.                 * *                                                                        * * Project Mayo gives users of the Codec a license to this software       * * module or modifications thereof for use in hardware or software        * * products claiming conformance to the MPEG-4 Video Standard as          * * described in the Open DivX license.                                    * *                                                                        * * The complete Open DivX license can be found at                         * * http://www.projectmayo.com/opendivx/license.php .                      * *                                                                        * **************************************************************************//************************************************************************** * *  text_code_mb.c * *  Copyright (C) 2001  Project Mayo * *  Adam Li *  Juice * *  DivX Advance Research Center <darc@projectmayo.com> * **************************************************************************//* This file contains some functions for text coding of MacroBlocks.      *//* Some codes of this project come from MoMuSys MPEG-4 implementation.    *//* Please see seperate acknowledgement file for a list of contributors.   */#include "text_code.h"#include "text_dct.h"#define BLOCK_SIZE 8Void  	BlockPredict (SInt *curr, /*SInt *rec_curr,*/	Int x_pos, Int y_pos, UInt width, Int fblock[][8]);Void  	BlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,	Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]);Void  	BlockQuantH263 (Int *coeff, Int QP, Int mode, Int type,	Int *qcoeff, Int maxDC, Int image_type);Void  	BlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type,	Int *rcoeff, Int image_type, Int short_video_header, Int bits_per_pixel);/***********************************************************CommentBegin****** * * -- CodeMB -- Code, decode and reconstruct Macroblock  *              combined with substraction and addition operation * * Arguments in : *	Int x_pos	x_position of Macroblock *	Int y_pos	y_position of Macroblock *	UInt width	width of Vop bounding box (unpadded size) *	Int QP		Quantization parameter *	Int Mode	Macroblock coding mode * * Arguments in/out : *	Vop *curr	current Vop, uncoded *	Vop *rec_curr	current Vop, decoded and reconstructed *  Vop *comp   current Vop, motion compensated *  Int *qcoeff coefficient block (384 * sizeof(Int)) * ***********************************************************CommentEnd********/Void CodeMB(Vop *curr, Vop *rec_curr, Vop *comp, Int x_pos, Int y_pos, UInt width,Int QP, Int Mode, Int *qcoeff){	Int k;	Int fblock[6][8][8];	Int coeff[384];	Int *coeff_ind;	Int *qcoeff_ind;	Int* rcoeff_ind;	Int x, y;	SInt *current, *recon, *compensated = NULL;	UInt xwidth;	Int iblock[6][8][8];	Int rcoeff[6*64];	Int i, j;	Int type;									  /* luma = 1, chroma = 2 *///	Int *qmat;	SInt tmp[64];	Int s;	int operation = curr->prediction_type;	/* This variable is for combined operation.	If it is an I_VOP, then MB in curr is reconstruct into rec_curr,	and comp is not used at all (i.e., it can be set to NULL).	If it is a P_VOP, then MB in curr is reconstructed, and the result	added with MB_comp is written into rec_curr. 	- adamli 11/19/2000 */	Int max = GetVopBrightWhite(curr);	/* This variable is the max value for the clipping of the reconstructed image. */	coeff_ind = coeff;	qcoeff_ind = qcoeff;	rcoeff_ind = rcoeff;	for (k = 0; k < 6; k++)	{		switch (k)		{			case 0:				x = x_pos;				y = y_pos;				xwidth = width;				current = (SInt *) GetImageData (GetVopY (curr));				break;			case 1:				x = x_pos + 8;				y = y_pos;				xwidth = width;				current = (SInt *) GetImageData (GetVopY (curr));				break;			case 2:				x = x_pos;				y = y_pos + 8;				xwidth = width;				current = (SInt *) GetImageData (GetVopY (curr));				break;			case 3:				x = x_pos + 8;				y = y_pos + 8;				xwidth = width;				current = (SInt *) GetImageData (GetVopY (curr));				break;			case 4:				x = x_pos / 2;				y = y_pos / 2;				xwidth = width / 2;				current = (SInt *) GetImageData (GetVopU (curr));				break;			case 5:				x = x_pos / 2;				y = y_pos / 2;				xwidth = width / 2;				current = (SInt *) GetImageData (GetVopV (curr));				break;			default:				break;		}		BlockPredict (current, x, y, xwidth, fblock[k]);	}	for (k = 0; k < 6; k++)	{		s = 0;		for (i = 0; i < 8; i++)			for (j = 0; j < 8; j++)				tmp[s++] = (SInt) fblock[k][i][j];#ifndef _MMX_		fdct_enc(tmp);#else		fdct_mm32(tmp);#endif		for (s = 0; s < 64; s++)			coeff_ind[s] = (Int) tmp[s];		if (k < 4) type = 1;		else type = 2;		/* For this release, only H263 quantization is supported. - adamli */		BlockQuantH263(coeff_ind,QP,Mode,type,qcoeff_ind,			GetVopBrightWhite(curr),1);		BlockDequantH263(qcoeff_ind,QP,Mode,type,rcoeff_ind,1, 0, GetVopBitsPerPixel(curr));		for (s = 0; s < 64; s++)			tmp[s] = (SInt) rcoeff_ind[s];#ifndef _MMX_		idct_enc(tmp);#else		Fast_IDCT(tmp);#endif		s = 0;		for (i = 0; i < 8; i++)			for (j = 0; j < 8; j++)				iblock[k][i][j] = (Int)tmp[s++];		coeff_ind += 64;		qcoeff_ind += 64;		rcoeff_ind += 64;		if (Mode == MODE_INTRA||Mode==MODE_INTRA_Q)			for (i = 0; i < 8; i++)				for (j = 0; j < 8; j ++)					iblock[k][i][j] = MIN (GetVopBrightWhite(curr), MAX (0, iblock[k][i][j]));		switch (k)		{			case 0:			case 1:			case 2:				continue;			case 3:				recon = (SInt *) GetImageData (GetVopY (rec_curr));				if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopY (comp));				BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos,     width, 16, iblock[0]);				BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos,     width, 16, iblock[1]);				BlockRebuild (recon, compensated, operation, max, x_pos,     y_pos + 8, width, 16, iblock[2]);				BlockRebuild (recon, compensated, operation, max, x_pos + 8, y_pos + 8, width, 16, iblock[3]);				continue;			case 4:				recon = (SInt *) GetImageData (GetVopU (rec_curr));				if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopU (comp));				BlockRebuild (recon, compensated, operation, max,					x_pos/2, y_pos/2, width/2, 8, iblock[4]);				continue;			case 5:				recon = (SInt *) GetImageData (GetVopV (rec_curr));				if (operation == P_VOP) compensated = (SInt *) GetImageData (GetVopV (comp));				BlockRebuild (recon, compensated, operation, max,					x_pos/2, y_pos/2, width/2, 8, iblock[5]);				continue;		}	}	return;}/***********************************************************CommentBegin****** * * -- BlockPredict -- Get prediction for an Intra block * * Purpose : *	Get prediction for an Intra block * * Arguments in : *	Int x_pos	x_position of Macroblock *	Int y_pos	y_position of Macroblock *	UInt width	width of Vop bounding box * * Arguments in/out : *	SInt *curr	current uncoded Vop data *	SInt *rec_curr	reconstructed Vop data area * * Arguments out : *	Int fblock[][8]	the prediction block to be coded for bitstream * ***********************************************************CommentEnd********/VoidBlockPredict (SInt *curr, /*SInt *rec_curr,*/ Int x_pos, Int y_pos,UInt width, Int fblock[][8]){	Int i, j;	for (i = 0; i < 8; i++)	{		for (j = 0; j < 8; j++)		{			fblock[i][j] = curr[(y_pos+i)*width + x_pos+j];		}	}}/***********************************************************CommentBegin****** * * -- BlockRebuild -- Reconstructs a block into data area of Vop * * Purpose : *	Reconstructs a block into data area of Vop * * Arguments in : *	Int x_pos	x_position of Macroblock *	Int y_pos	y_position of Macroblock *	UInt width	width of Vop bounding box * * Arguments in/out : *	SInt *rec_curr	current Vop data area to be reconstructed * * Description : *	Does reconstruction for Intra predicted blocks also * ***********************************************************CommentEnd********/VoidBlockRebuild (SInt *rec_curr, SInt *comp, Int pred_type, Int max,Int x_pos, Int y_pos, UInt width, UInt edge, Int fblock[][8]){	/* this function now does rebuild and generating error at the same time */	Int i, j;	SInt *rec;	Int padded_width;		padded_width = width + 2 * edge;	rec = rec_curr + edge * padded_width + edge;	if (pred_type == I_VOP)	{		SInt *p;		p  = rec + y_pos * padded_width + x_pos;		for (i = 0; i < 8; i++) 		{			for (j = 0; j < 8; j++)			{				SInt temp = fblock[i][j];				*(p++) = CLIP(temp, 0, max);			}			p += padded_width - 8;		}	}	else if (pred_type == P_VOP)	{		SInt *p, *pc; 		p  = rec + y_pos * padded_width + x_pos;		pc = comp     + y_pos * width + x_pos;		for (i = 0; i < 8; i++)		{			for (j = 0; j < 8; j++)			{				SInt temp = *(pc++) + fblock[i][j];				*(p++) = CLIP(temp, 0, max);			}			p += padded_width - 8;			pc += width - 8;		}	}}/***********************************************************CommentBegin****** * * -- BlockQuantH263 -- 8x8 block level quantization * * Purpose : *	8x8 block level quantization * * Arguments in : *	Int *coeff	non-quantized coefficients *	Int QP		quantization parameter *	Int Mode	Macroblock coding mode * * Arguments out : *	Int *qcoeff	quantized coefficients * ***********************************************************CommentEnd********/VoidBlockQuantH263 (Int *coeff, Int QP, Int mode, Int type, Int *qcoeff, Int maxDC, Int image_type){	Int i;	Int level, result;	Int step, offset;	Int dc_scaler;	if (!(QP > 0 && (QP < 32*image_type))) return;	if (!(type == 1 || type == 2)) return;	if (mode == MODE_INTRA || mode == MODE_INTRA_Q)	{										  /* Intra */		dc_scaler = cal_dc_scaler(QP,type);		qcoeff[0] = MAX(1,MIN(maxDC-1, (coeff[0] + dc_scaler/2)/dc_scaler));		step = 2 * QP;		for (i = 1; i < 64; i++)		{			level = (abs(coeff[i]))  / step;			result = (coeff[i] >= 0) ? level : -level;			qcoeff[i] =  MIN(2047, MAX(-2048, result));		}	}	else	{										  /* non Intra */		step = 2 * QP;		offset = QP / 2;		for (i = 0; i < 64; i++)		{			level = (abs(coeff[i]) - offset)  / step;			result = (coeff[i] >= 0) ? level : -level;			qcoeff[i] =  MIN(2047, MAX(-2048, result));		}	}	return;}/***********************************************************CommentBegin****** * * -- BlockDequantH263 -- 8x8 block dequantization * * Purpose : *	8x8 block dequantization * * Arguments in : *	Int *qcoeff	        quantized coefficients *	Int QP		        quantization parameter *	Int mode	        Macroblock coding mode *      Int short_video_header  Flag to signal short video header bitstreams (H.263) * * Arguments out : *	Int *rcoeff	reconstructed (dequantized) coefficients * ***********************************************************CommentEnd********/VoidBlockDequantH263 (Int *qcoeff, Int QP, Int mode, Int type, Int *rcoeff,Int image_type, Int short_video_header, Int bits_per_pixel){	Int i;	Int dc_scaler;	Int lim;	lim = (1 << (bits_per_pixel + 3));	if (QP)	{		for (i = 0; i < 64; i++)		{			if (qcoeff[i])			{				/* 16.11.98 Sven Brandau: "correct saturation" due to N2470, Clause 2.1.6 */				qcoeff[i] =  MIN(2047, MAX(-2048, qcoeff[i] ));				if ((QP % 2) == 1)					rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1);				else					rcoeff[i] = QP * (2*ABS(qcoeff[i]) + 1) - 1;				rcoeff[i] = SIGN(qcoeff[i]) * rcoeff[i];			}			else				rcoeff[i] = 0;		}		if (mode == MODE_INTRA || mode == MODE_INTRA_Q)		{										  /* Intra */			MOMCHECK(QP > 0 && (QP < 32*image_type));			MOMCHECK(type == 1 || type == 2);			if (short_video_header)				dc_scaler = 8;			else				dc_scaler = cal_dc_scaler(QP,type);			rcoeff[0] = qcoeff[0] * dc_scaler;		}	}	else	{		/* No quantizing at all */		for (i = 0; i < 64; i++)		{			rcoeff[i] = qcoeff[i];		}		if (mode == MODE_INTRA || mode == MODE_INTRA_Q)		{										  /* Intra */			rcoeff[0] = qcoeff[0]*8;		}	}	for (i=0;i<64;i++)		if (rcoeff[i]>(lim-1)) rcoeff[i]=(lim-1);		else if (rcoeff[i]<(-lim)) rcoeff[i]=(-lim);	return;}

⌨️ 快捷键说明

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