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

📄 mbcoding.c

📁 mpeg4代码,比较具体
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * *  XVID MPEG-4 VIDEO CODEC *  - Macro Block coding functions - * *  Copyright(C) 2002 Michael Militzer <isibaar@xvid.org> * *  This file is part of XviD, a free MPEG-4 video encoder/decoder * *  XviD 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 * *  Under section 8 of the GNU General Public License, the copyright *  holders of XVID explicitly forbid distribution in the following *  countries: * *    - Japan *    - United States of America * *  Linking XviD statically or dynamically with other modules is making a *  combined work based on XviD.  Thus, the terms and conditions of the *  GNU General Public License cover the whole combination. * *  As a special exception, the copyright holders of XviD give you *  permission to link XviD with independent modules that communicate with *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the *  license terms of these independent modules, and to copy and distribute *  the resulting combined work under terms of your choice, provided that *  every copy of the combined work is accompanied by a complete copy of *  the source code of XviD (the version of XviD used to produce the *  combined work), being distributed under the terms of the GNU General *  Public License plus this exception.  An independent module is a module *  which is not derived from or based on XviD. * *  Note that people who make modified versions of XviD are not obligated *  to grant this special exception for their modified versions; it is *  their choice whether to do so.  The GNU General Public License gives *  permission to release a modified version without this exception; this *  exception also makes it possible to release a modified version which *  carries forward this exception. * * $Id: mbcoding.c,v 1.41 2003/02/13 17:31:33 edgomez Exp $ * ****************************************************************************/#include <stdlib.h>#include "../portab.h"#include "bitstream.h"#include "zigzag.h"#include "vlc_codes.h"#include "mbcoding.h"#include "../utils/mbfunctions.h"#define ABS(X) (((X)>0)?(X):-(X))#define CLIP(X,A) (X > A) ? (A) : (X)/* #define BIGLUT */#ifdef BIGLUT#define LEVELOFFSET 2048#else#define LEVELOFFSET 32#endif/***************************************************************************** * Local data ****************************************************************************/static REVERSE_EVENT DCT3D[2][4096];#ifdef BIGLUTstatic VLC coeff_VLC[2][2][4096][64];static VLC *intra_table, *inter_table; #elsestatic VLC coeff_VLC[2][2][64][64];#endif/***************************************************************************** * Vector Length Coding Initialization ****************************************************************************/voidinit_vlc_tables(void){	uint32_t i, j, intra, last, run,  run_esc, level, level_esc, escape, escape_len, offset;#ifdef BIGLUT	intra_table = (VLC*)coeff_VLC[1];	inter_table = (VLC*)coeff_VLC[0]; #endif	for (intra = 0; intra < 2; intra++)		for (i = 0; i < 4096; i++)			DCT3D[intra][i].event.level = 0;	for (intra = 0; intra < 2; intra++)		for (last = 0; last < 2; last++)		{			for (run = 0; run < 63 + last; run++)				for (level = 0; level < (uint32_t)(32 << intra); level++)				{#ifdef BIGLUT					offset = LEVELOFFSET;#else					offset = !intra * LEVELOFFSET;#endif					coeff_VLC[intra][last][level + offset][run].len = 128;				}		}	for (intra = 0; intra < 2; intra++)		for (i = 0; i < 102; i++)		{#ifdef BIGLUT			offset = LEVELOFFSET;#else			offset = !intra * LEVELOFFSET;#endif			for (j = 0; j < (uint32_t)(1 << (12 - coeff_tab[intra][i].vlc.len)); j++)			{				DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].len	 = coeff_tab[intra][i].vlc.len;				DCT3D[intra][(coeff_tab[intra][i].vlc.code << (12 - coeff_tab[intra][i].vlc.len)) | j].event = coeff_tab[intra][i].event;			}			coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].code				= coeff_tab[intra][i].vlc.code << 1;			coeff_VLC[intra][coeff_tab[intra][i].event.last][coeff_tab[intra][i].event.level + offset][coeff_tab[intra][i].event.run].len				= coeff_tab[intra][i].vlc.len + 1;#ifndef BIGLUT			if (!intra)#endif			{				coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].code					= (coeff_tab[intra][i].vlc.code << 1) | 1;				coeff_VLC[intra][coeff_tab[intra][i].event.last][offset - coeff_tab[intra][i].event.level][coeff_tab[intra][i].event.run].len					= coeff_tab[intra][i].vlc.len + 1;			}		}	for (intra = 0; intra < 2; intra++)		for (last = 0; last < 2; last++)			for (run = 0; run < 63 + last; run++)			{				for (level = 1; level < (uint32_t)(32 << intra); level++)				{					if (level <= max_level[intra][last][run] && run <= max_run[intra][last][level])					    continue;#ifdef BIGLUT					offset = LEVELOFFSET;#else					offset = !intra * LEVELOFFSET;#endif                    level_esc = level - max_level[intra][last][run];					run_esc = run - 1 - max_run[intra][last][level];					if (level_esc <= max_level[intra][last][run] && run <= max_run[intra][last][level_esc])					{						escape     = ESCAPE1;						escape_len = 7 + 1;						run_esc    = run;					}					else					{						if (run_esc <= max_run[intra][last][level] && level <= max_level[intra][last][run_esc])						{							escape     = ESCAPE2;							escape_len = 7 + 2;							level_esc  = level;						}						else						{#ifndef BIGLUT							if (!intra)#endif							{								coeff_VLC[intra][last][level + offset][run].code									= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1;								coeff_VLC[intra][last][level + offset][run].len = 30;									coeff_VLC[intra][last][offset - level][run].code									= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-level & 0xfff) << 1) | 1;								coeff_VLC[intra][last][offset - level][run].len = 30;							}							continue;						}					}					coeff_VLC[intra][last][level + offset][run].code						= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len)						|  coeff_VLC[intra][last][level_esc + offset][run_esc].code;					coeff_VLC[intra][last][level + offset][run].len						= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len;#ifndef BIGLUT					if (!intra)#endif					{						coeff_VLC[intra][last][offset - level][run].code							= (escape << coeff_VLC[intra][last][level_esc + offset][run_esc].len)							|  coeff_VLC[intra][last][level_esc + offset][run_esc].code | 1;						coeff_VLC[intra][last][offset - level][run].len							= coeff_VLC[intra][last][level_esc + offset][run_esc].len + escape_len;					}				}#ifdef BIGLUT				for (level = (uint32_t)(32 << intra); level < 2048; level++)				{					coeff_VLC[intra][last][level + offset][run].code						= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((level & 0xfff) << 1) | 1;					coeff_VLC[intra][last][level + offset][run].len = 30;					coeff_VLC[intra][last][offset - level][run].code						= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-level & 0xfff) << 1) | 1;					coeff_VLC[intra][last][offset - level][run].len = 30;				}#else				if (!intra)				{					coeff_VLC[intra][last][0][run].code						= (ESCAPE3 << 21) | (last << 20) | (run << 14) | (1 << 13) | ((-32 & 0xfff) << 1) | 1;					coeff_VLC[intra][last][0][run].len = 30;				}#endif			}	/* Shut up the compiler -- gcc 3.3 pre release */	i = dc_threshold[0];}/***************************************************************************** * Local inlined functions for MB coding ****************************************************************************/static __inline voidCodeVector(Bitstream * bs,		   int32_t value,		   int32_t f_code,		   Statistics * pStat){	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;	pStat->iMvSum += value * value;	pStat->iMvCount++;	if (value == 0) {		BitstreamPutBits(bs, mb_motion_table[32].code,						 mb_motion_table[32].len);	} else {		uint16_t 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;		BitstreamPutBits(bs, mb_motion_table[code].code,						 mb_motion_table[code].len);		if (f_code)			BitstreamPutBits(bs, mv_res, f_code);	}}#ifdef BIGLUTstatic __inline voidCodeCoeff(Bitstream * bs,		  const int16_t qcoeff[64],		  VLC * table,		  const uint16_t * zigzag,		  uint16_t intra){	uint32_t j, last;	short v;	VLC *vlc;	j = intra;	last = intra;	while (j < 64 && (v = qcoeff[zigzag[j]]) == 0)		j++;	do {		vlc = table + 64 * 2048 + (v << 6) + j - last;		last = ++j;		/* count zeroes */		while (j < 64 && (v = qcoeff[zigzag[j]]) == 0)			j++;		/* write code */		if (j != 64) {			BitstreamPutBits(bs, vlc->code, vlc->len);		} else {			vlc += 64 * 4096;			BitstreamPutBits(bs, vlc->code, vlc->len);			break;		}	} while (1);}#elsestatic __inline voidCodeCoeffInter(Bitstream * bs,		  const int16_t qcoeff[64],		  const uint16_t * zigzag){	uint32_t i, run, prev_run, code, len;	int32_t level, prev_level, level_shifted;	i	= 0;	run = 0;	while (!(level = qcoeff[zigzag[i++]]))		run++;	prev_level = level;	prev_run   = run;	run = 0;	while (i < 64)	{		if ((level = qcoeff[zigzag[i++]]) != 0)		{			level_shifted = prev_level + 32;			if (!(level_shifted & -64))			{				code = coeff_VLC[0][0][level_shifted][prev_run].code;				len	 = coeff_VLC[0][0][level_shifted][prev_run].len;			}			else			{				code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;				len  = 30;			}			BitstreamPutBits(bs, code, len);			prev_level = level;			prev_run   = run;			run = 0;		}		else			run++;	}	level_shifted = prev_level + 32;	if (!(level_shifted & -64))	{		code = coeff_VLC[0][1][level_shifted][prev_run].code;		len	 = coeff_VLC[0][1][level_shifted][prev_run].len;	}	else	{		code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;		len  = 30;	}	BitstreamPutBits(bs, code, len);}static __inline voidCodeCoeffIntra(Bitstream * bs,		  const int16_t qcoeff[64],		  const uint16_t * zigzag){	uint32_t i, abs_level, run, prev_run, code, len;	int32_t level, prev_level;	i	= 1;	run = 0;	while (!(level = qcoeff[zigzag[i++]]))		run++;	prev_level = level;	prev_run   = run;	run = 0;	while (i < 64)	{		if ((level = qcoeff[zigzag[i++]]) != 0)		{			abs_level = ABS(prev_level);			abs_level = abs_level < 64 ? abs_level : 0;			code	  = coeff_VLC[1][0][abs_level][prev_run].code;			len		  = coeff_VLC[1][0][abs_level][prev_run].len;			if (len != 128)				code |= (prev_level < 0);			else			{		        code = (ESCAPE3 << 21) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;				len  = 30;			}			BitstreamPutBits(bs, code, len);			prev_level = level;			prev_run   = run;			run = 0;		}		else			run++;	}	abs_level = ABS(prev_level);	abs_level = abs_level < 64 ? abs_level : 0;	code	  = coeff_VLC[1][1][abs_level][prev_run].code;	len		  = coeff_VLC[1][1][abs_level][prev_run].len;	if (len != 128)		code |= (prev_level < 0);	else	{		code = (ESCAPE3 << 21) | (1 << 20) | (prev_run << 14) | (1 << 13) | ((prev_level & 0xfff) << 1) | 1;		len  = 30;	}	BitstreamPutBits(bs, code, len);}#endif/***************************************************************************** * Local functions ****************************************************************************/static voidCodeBlockIntra(const FRAMEINFO * frame,			   const MACROBLOCK * pMB,			   int16_t qcoeff[6 * 64],			   Bitstream * bs,			   Statistics * pStat){	uint32_t i, mcbpc, cbpy, bits;	cbpy = pMB->cbp >> 2;	/* write mcbpc */	if (frame->coding_type == I_VOP) {		mcbpc = ((pMB->mode >> 1) & 3) | ((pMB->cbp & 3) << 2);		BitstreamPutBits(bs, mcbpc_intra_tab[mcbpc].code,						 mcbpc_intra_tab[mcbpc].len);	} else {		mcbpc = (pMB->mode & 7) | ((pMB->cbp & 3) << 3);		BitstreamPutBits(bs, mcbpc_inter_tab[mcbpc].code,						 mcbpc_inter_tab[mcbpc].len);

⌨️ 快捷键说明

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