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

📄 mbcoding.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************** * *  XVID MPEG-4 VIDEO CODEC *  - MB coding - * *  Copyright (C) 2002 Michael Militzer <isibaar@xvid.org> * *  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: mbcoding.c,v 1.52.2.2 2007/06/28 15:00:11 Isibaar Exp $ * ****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "../portab.h"#include "../global.h"#include "bitstream.h"#include "zigzag.h"#include "vlc_codes.h"#include "mbcoding.h"#include "../utils/mbfunctions.h"#define LEVELOFFSET 32/* Initialized once during xvid_global call * RO access is thread safe */static REVERSE_EVENT DCT3D[2][4096];static VLC coeff_VLC[2][2][64][64];/* not really MB related, but VLCs are only available here */void bs_put_spritetrajectory(Bitstream * bs, const int val){	const int code = sprite_trajectory_code[val+16384].code;	const int len = sprite_trajectory_code[val+16384].len;	const int code2 = sprite_trajectory_len[len].code;	const int len2 = sprite_trajectory_len[len].len;#if 0	printf("GMC=%d Code/Len  = %d / %d ",val, code,len);	printf("Code2 / Len2 = %d / %d \n",code2,len2);#endif	BitstreamPutBits(bs, code2, len2);	if (len) BitstreamPutBits(bs, code, len);}int bs_get_spritetrajectory(Bitstream * bs){	int i;	for (i = 0; i < 12; i++)	{		if (BitstreamShowBits(bs, sprite_trajectory_len[i].len) == sprite_trajectory_len[i].code)		{			BitstreamSkip(bs, sprite_trajectory_len[i].len);			return i;		}	}	return -1;}voidinit_vlc_tables(void){	uint32_t i, j, k, intra, last, run,  run_esc, level, level_esc, escape, escape_len, offset;	int32_t l;	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++) {					offset = !intra * LEVELOFFSET;					coeff_VLC[intra][last][level + offset][run].len = 128;				}			}		}	}	for (intra = 0; intra < 2; intra++) {		for (i = 0; i < 102; i++) {			offset = !intra * LEVELOFFSET;			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;			if (!intra) {				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;					offset = !intra * LEVELOFFSET;                    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 {							if (!intra) {								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) | ((-(int32_t)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;					if (!intra) {						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;					}				}				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;				}			}		}	}	/* init sprite_trajectory tables	 * even if GMC is not specified (it might be used later...) */	sprite_trajectory_code[0+16384].code = 0;	sprite_trajectory_code[0+16384].len = 0;	for (k=0;k<14;k++) {		int limit = (1<<k);		for (l=-(2*limit-1); l <= -limit; l++) {			sprite_trajectory_code[l+16384].code = (2*limit-1)+l;			sprite_trajectory_code[l+16384].len = k+1;		}		for (l=limit; l<= 2*limit-1; l++) {			sprite_trajectory_code[l+16384].code = l;			sprite_trajectory_code[l+16384].len = k+1;		}	}}static __inline voidCodeVector(Bitstream * bs,		   int32_t value,		   int32_t 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) {		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);	}}static __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 (i<64 && !(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);}/* returns the number of bits required to encode qcoeff */intCodeCoeffIntra_CalcBits(const int16_t qcoeff[64], const uint16_t * zigzag){	int bits = 0;	uint32_t i, abs_level, run, prev_run, len;	int32_t level, prev_level;	i	= 1;	run = 0;	while (i<64 && !(level = qcoeff[zigzag[i++]]))		run++;	if (i >= 64) return 0;	/* empty block */	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;			len		  = coeff_VLC[1][0][abs_level][prev_run].len;			bits      += len!=128 ? len : 30;			prev_level = level;			prev_run   = run;			run = 0;		}		else			run++;	}	abs_level = abs(prev_level);	abs_level = abs_level < 64 ? abs_level : 0;	len		  = coeff_VLC[1][1][abs_level][prev_run].len;	bits      += len!=128 ? len : 30;	return bits;}intCodeCoeffInter_CalcBits(const int16_t qcoeff[64], const uint16_t * zigzag){	uint32_t i, run, prev_run, len;	int32_t level, prev_level, level_shifted;	int bits = 0;	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))				len	 = coeff_VLC[0][0][level_shifted][prev_run].len;			else				len  = 30;			bits += len;			prev_level = level;			prev_run   = run;			run = 0;		}		else			run++;	}	level_shifted = prev_level + 32;	if (!(level_shifted & -64))		len	 = coeff_VLC[0][1][level_shifted][prev_run].len;	else		len  = 30;	bits += len;	return bits;}static const int iDQtab[5] = {	1, 0, -1 /* no change */, 2, 3};#define DQ_VALUE2INDEX(value)  iDQtab[(value)+2]static __inline voidCodeBlockIntra(const FRAMEINFO * const 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);	}	/* ac prediction flag */	if (pMB->acpred_directions[0])		BitstreamPutBits(bs, 1, 1);	else		BitstreamPutBits(bs, 0, 1);	/* write cbpy */	BitstreamPutBits(bs, xvid_cbpy_tab[cbpy].code, xvid_cbpy_tab[cbpy].len);

⌨️ 快捷键说明

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