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

📄 mbcoding.c

📁 用MPEG-4对YUV视频文件编码压缩成divx视频文件
💻 C
📖 第 1 页 / 共 2 页
字号:
 /******************************************************************************
  *                                                                            *
  *  This file is part of XviD, a free MPEG-4 video encoder/decoder            *
  *                                                                            *
  *  XviD 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, will have no liability for use of this software or             *
  *  modifications or derivatives thereof.                                     *
  *                                                                            *
  *  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.                                       *
  *                                                                            *
  *  XviD 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  *
  *                                                                            *
  ******************************************************************************/

 /******************************************************************************
  *                                                                            *
  *  mbcoding.c                                                                *
  *                                                                            *
  *  Copyright (C) 2002 - Michael Militzer <isibaar@xvid.org>                  *
  *                                                                            *
  *  For more information visit the XviD homepage: http://www.xvid.org         *
  *                                                                            *
  ******************************************************************************/

 /******************************************************************************
  *																			   *	
  *  Revision history:                                                         *
  *                                                                            *
  *  28.06.2002 added check_resync_marker()                                    *
  *  14.04.2002 bframe encoding												   *
  *  08.03.2002 initial version; isibaar					                   *
  *																			   *
  ******************************************************************************/



#include <stdlib.h>
/*#include <malloc.h>*/
#include "../portab.h"
#include "bitstream.h"
#include "zigzag.h"
#include "vlc_codes.h"
#include "mbcoding.h"
#include "../utils/mbfunctions.h"

/* size=4095*64*2=524160,whq,2002.12-11 */
/* save intra,inter (run,level,last) pair */
VLC intra_table[524160]; 
VLC inter_table[524160];

/*!
 ************************************************************************
 * \replace goto using function run_level_code    
 * \brief
 *    get  vlc code for run-level pair 
 *
 * \author , whq
 ************************************************************************
 */
/*
void run_level_code(VLC **coeff_ptr,VLC *vlc[2],
					int32_t level,ptr_t run,int32_t intra);*/

static __inline
void run_level_code(VLC **coeff_ptr,	/*pointer to the suitable coeff table*/
					VLC *vlc[2],		/*pointer to the array for inter or intra table*/
					int32_t level,		/* level */
					ptr_t run,			/* run */
					int32_t intra)		/* intra or inter*/
{
			int32_t abs_level;
			if (level != 0) {
					abs_level = abs(level)-1;
					vlc[intra]->code =
						(vlc[intra]->
						 code << (coeff_ptr[run][abs_level ].len +
								  1)) | (coeff_ptr[run][abs_level ].code<<1);
												
					vlc[intra]->len =
						(coeff_ptr[run][abs_level ].len + 1) +
						vlc[intra]->len;

					if (level < 0)
						/*vlc[intra]->code += 1;*/
						vlc[intra]->code ++;
					}

				vlc[intra]++;
}


/*!
 ************************************************************************   
 * \brief
 *    init,get vlc code for all (last,run,level) pair 
 *
 * 
 ************************************************************************
 */
void
init_vlc_tables(void)
{

	int32_t k, l, i, intra, last;
/*	int32_t temp;*//*用于保存level,run值改变之前的值,用于后来恢复使用*/
	VLC *vlc[2];
	VLC **coeff_ptr;
	/* move variable out of loop */
	/* whq,2002.12.19,save array index */
	int32_t index;
	int8_t *max_level_ptr;
	int8_t *max_run_ptr;
	int32_t level,abs_level;
	uint32_t run;
	/* whq,2002.12.19 */

	vlc[0] = intra_table;
	vlc[1] = inter_table;
	/* generate encoding vlc lookup tables*/
	/* the lookup table idea is taken from the excellent fame project by Vivien Chapellier*/
	for (i = 0; i < 4; i++) {
		/* to be optimize */
		intra = i % 2;
		last = i / 2;
		index = last + 2 * intra;
		coeff_ptr = coeff_vlc[index];

		for (k = -2047; k < 2048; k++) {	/* level*/
			max_level_ptr = max_level[index];
			max_run_ptr = max_run[index];

			for (l = 0; l < 64; l++) {	/* run*/
				 level = k;
				 abs_level = abs(level);
				 run = l;

				if ((abs_level <= max_level_ptr[run]) && (run <= (uint32_t) max_run_ptr[abs_level])) {	/* level < max_level and run < max_run*/

					vlc[intra]->code = 0;
					vlc[intra]->len = 0;

			/*	if (level != 0) {
					vlc[intra]->code =
						(vlc[intra]->
						 code << (coeff_ptr[run][abs(level) - 1].len +
								  1)) | (coeff_ptr[run][abs(level) -
														1].code << 1);
					vlc[intra]->len =
						(coeff_ptr[run][abs(level) - 1].len + 1) +
						vlc[intra]->len;

					if (level < 0)
						vlc[intra]->code += 1;
				}

				vlc[intra]++;        */
				run_level_code(coeff_ptr,vlc,level,run,intra);
				continue;
					/*goto loop_end;*/
				} 
				else 
				{
					if (level > 0)	/* correct level*/
						level -= max_level_ptr[run];
					else
						level += max_level_ptr[run];
					abs_level = abs(level);
				
					if ((abs_level <= max_level_ptr[run]) &&
						(run <= (uint32_t) max_run_ptr[abs_level])) {

						vlc[intra]->code = 0x06;
						vlc[intra]->len = 8;
						
				/*	if (level != 0) {
					vlc[intra]->code =
						(vlc[intra]->
						 code << (coeff_ptr[run][abs(level) - 1].len +
								  1)) | (coeff_ptr[run][abs(level) -
														1].code << 1);
					vlc[intra]->len =
						(coeff_ptr[run][abs(level) - 1].len + 1) +
						vlc[intra]->len;

					if (level < 0)
						vlc[intra]->code += 1;
					}

				vlc[intra]++;*/
                run_level_code(coeff_ptr,vlc,level,run,intra);
						
				continue;
						/*goto loop_end;*/
				}
					/* restore level*/
				level=k;
				abs_level = abs(level);
				run -= max_run_ptr[abs_level] + 1;	/* and change run*/

				if ((abs_level <= max_level_ptr[run]) &&
					(run <= (uint32_t) max_run_ptr[abs_level])) {

					vlc[intra]->code = 0x0e;
					vlc[intra]->len = 9;


				/*	if (level != 0) {
					vlc[intra]->code =
						(vlc[intra]->
						 code << (coeff_ptr[run][abs(level) - 1].len +
								  1)) | (coeff_ptr[run][abs(level) -
														1].code << 1);
					vlc[intra]->len =
						(coeff_ptr[run][abs(level) - 1].len + 1) +
						vlc[intra]->len;

					if (level < 0)
						vlc[intra]->code += 1;
				}

				vlc[intra]++; */       

					run_level_code(coeff_ptr,vlc,level,run,intra);
					continue;
					/*	goto loop_end;*/
					}
					/*restore run*/
					/*run += max_run_ptr[abs(level)] + 1;*/
				run=l;
				}

				vlc[intra]->code =
					(uint32_t) ((l << 14) | (0x1e + last) << 20) | (1 << 13) |
					((k & 0xfff) << 1) | 1;

				vlc[intra]->len = 30;
				vlc[intra]++;
				continue;

	/*		  loop_end:
				if (level != 0) {
					vlc[intra]->code =
						(vlc[intra]->
						 code << (coeff_ptr[run][abs(level) - 1].len +
								  1)) | (coeff_ptr[run][abs(level) -
														1].code << 1);
					vlc[intra]->len =
						(coeff_ptr[run][abs(level) - 1].len + 1) +
						vlc[intra]->len;

					if (level < 0)
						vlc[intra]->code += 1;
				}

				vlc[intra]++;              */
			}
		}
	}
}

/*!
 ************************************************************************   
 * \brief
 *    get vlc code for motion vector
 *
 ************************************************************************
 */

static /*__inline*/ int16_t				/* ==> return the bits for vector */
CodeVector(Bitstream * bs,			/*<--> bitstream buffer */
		   int32_t value,           /*<--  vector value */
		   int32_t f_code,			/*<--  range of vector */
		   Statistics * pStat       /*<--> stat  vector count and value  */
		   )/*修改此函数使其返回运动向量占的位数 modify by lxq*/
{
	int16_t vector_length=0;	
	uint16_t code;
	const int scale_factor = 1 << (f_code - 1);
	const int cmp = scale_factor << 5;

    
	if (value < (-1 * cmp))
		/*value += 64 * scale_factor;*/
		value += scale_factor<<6;


	if (value > (cmp - 1))
		/*value -= 64 * scale_factor;*/
		value -= scale_factor<<6;


	pStat->iMvSum += value * value;
	pStat->iMvCount++;
	code =value + 32;
	BitstreamPutBits(bs, mb_motion_table[code].code,
						 mb_motion_table[code].len);
	vector_length+=mb_motion_table[code].len;

/*	if (value == 0) {
		BitstreamPutBits(bs, mb_motion_table[32].code,
						 mb_motion_table[32].len);
		vector_length+=mb_motion_table[32].len;
	} else {*/
			
/*		f_code--;
		sign = (value < 0);
*/
/*whq,2002,12,25*/
/*
		if (value >= length)*/
		/*	value -= 2 * length;*/
		/*	value -= length<<1;*/

/*		else if (value < -length)*/

⌨️ 快捷键说明

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