mot_code.c

来自「实现在linux下的mpeg4编解码」· C语言 代码 · 共 582 行 · 第 1/2 页

C
582
字号
/************************************************************************** *                                                                        * * 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 .                      * *                                                                        * **************************************************************************//************************************************************************** * *  mot_code.c * *  Copyright (C) 2001  Project Mayo * *  Adam Li * *  DivX Advance Research Center <darc@projectmayo.com> * **************************************************************************//* This file contains some functions to code the motion data of the image.*//* Some codes of this project come from MoMuSys MPEG-4 implementation.    *//* Please see seperate acknowledgement file for a list of contributors.   */#include "vm_common_defs.h"#include "bitstream.h"#include "putvlc.h"/* ------------------------------------------------------------------------- *//* Specific macros (include references to internal vars. of the functions) *//* 16x16 MV obtainment */#define MBV_H(h,v)      (ph[2*(v)*2*hdim+2*(h)])#define MBV_V(h,v)      (pv[2*(v)*2*hdim+2*(h)])/* 8x8 MV obtainment */#define BV_H(h,v,h2,v2) (ph[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])#define BV_V(h,v,h2,v2) (pv[(2*(v)+(v2))*2*hdim+2*(h)+(h2)])/* MB mode obtainment */#define MB_MODE(h,v)    ( ((h)<0||(h)>=hdim||(v)<0||(v)>=vdim ? MBM_OUT : (pm[(v)*hdim+(h)])) )/* get 8x8 MV component */#define BV(p,xdim,h,v,h2,v2) (p[(2*(v)+(v2))*(xdim)+2*(h)+(h2)])/* ------------------------------------------------------------------------- *//* declaration for functions in this file */Int WriteMVcomponent(Int f_code, Int dmv, Image *bs);Void ScaleMVD (Int f_code, Int diff_vector, Int *residual, Int *vlc_code_mag);Void  	find_pmvs (Image *mot_x, Image *mot_y, Image *MB_decisions, Image *B_decisions,	Int x, Int y, Int block, Int transparent_value, Int quarter_pel, Int *error_flag,	Int *mvx, Int *mvy, Int newgob);SInt ModeMB (Image *MB_decision, Int i, Int j);/***********************************************************CommentBegin****** * * -- Bits_CountMB_Motion -- * * Purpose : *      Encodes the MV's Images acording to modes and alpha Images *      (see notes below). The codewords are appended to the bitstream. *      Included in text_code.h . * * Return values : *      Int     mv_bits   Returns the number of bits sent to the bitstream * * Description : *      1) No checking is made for the consistence of image sizes *      2) It assumes the output image has been previously allocated. *      3) Transparent MB's are not coded (no codeword is transmited). *      4) Motion vectors for 8x8 transparent blocks within *         non-totally-transparent MB's are transmitted as MV (0,0) (not MVD *         (0,0)). This is made in the  hope that this MV's are neither *         employed for block reconstruction nor for MV prediction. * ***********************************************************CommentEnd********/IntBits_CountMB_Motion(Image   *mot_h,									  /* <-- motion vectors (Float) - per block    */Image   *mot_v,									  /* <-- motion vectors (Float) - per block    */Image   *alpha,									  /* <-- macroblocks modes (SInt) - per block  */Image   *modes,									  /* <-- macroblocks modes (SInt) - per MB     */Int     h,										  /* <-- horizontal coordinate of the MB       */Int     v,										  /* <-- vertical coordinate of the MB         */Int     f_code,									  /* <-- MV range in 1/2 or 1/4 pel units 1=32,2=64,...,7=2048 */												  /* <-- flag for quarter pel MC mode     */Int     quarter_pel,       /* MW QPEL 07-JUL-1998 */Image   *bs,									  /* --> output (SInt)                         */Int     error_res_disable,Int     after_marker,Int     **slice_nb,Int arbitrary_shape){	Int     vdim, hdim;							  /* Dimensions in macroblocks */		Float   *ph, *pv;						  /* Motion vectors            */		SInt    *pm;							  /* Modes                     */		SInt    *pa;							  /* Alpha                     */		Int     mode;		Int     bits_mot = 0;	/* From switch statement */		Int     i, error_flag=0,mvx=0,mvy=0;		Float   pred_h, pred_v;		Float   diff_h, diff_v;		Int     bh, bv;		Int     local_f_code;					  /* MW QPEL 07-JUL-1998 */		Float   subdim;							  /* MW QPEL 07-JUL-1998 */		vdim = (Int)modes->y;		hdim = (Int)modes->x;		ph=(Float*)GetImageData(mot_h);		pv=(Float*)GetImageData(mot_v);		pm=(SInt*)GetImageData(modes);		pa=NULL;//(SInt*)GetImageData(alpha);	/* MW QPEL 07-JUL-1998 >> */	/* Set local_f_code and subdim according to quarter_pel */		if (quarter_pel)	{		local_f_code = f_code+1;			subdim = 4.0;	}	else	{		local_f_code = f_code;			subdim = 2.0;	}	/* << MW QPEL 07-JUL-1998 */	switch (mode=MB_MODE(h,v))	{		case MBM_INTRA:		break;		case MBM_INTER16:		/* Prediction obtainment */		find_pmvs(mot_h,mot_v,modes,alpha,h,v,0,MBM_TRANSPARENT,									  /* MW QPEL 07-JUL-1998 */		quarter_pel,&error_flag,&mvx,&mvy,0);		pred_h=((Float)mvx)/subdim;			  /* MW QPEL 07-JUL-1998 */		pred_v=((Float)mvy)/subdim;		  /* MW QPEL 07-JUL-1998 */										  /* MW QPEL 07-JUL-1998 */		bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*(MBV_H(h,v) - pred_h)), bs);										  /* MW QPEL 07-JUL-1998 */		bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*(MBV_V(h,v) - pred_v)), bs);		break;		case MBM_INTER8:		i=1;		for (bv=0; bv<=1; bv++)			for (bh=0; bh<=1; bh++)		{			find_pmvs(mot_h,mot_v,modes,alpha,h,v,i,MBM_TRANSPARENT,								  /* MW QPEL 07-JUL-1998 */			quarter_pel,&error_flag,&mvx,&mvy,0);			pred_h=((Float)mvx)/subdim;		  /* MW QPEL 07-JUL-1998 */			pred_v=((Float)mvy)/subdim;	  /* MW QPEL 07-JUL-1998 */			i++;			diff_h=BV_H(h,v,bh,bv)-pred_h;			diff_v=BV_V(h,v,bh,bv)-pred_v;									  /* MW QPEL 07-JUL-1998 */			bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*diff_h), bs);									  /* MW QPEL 07-JUL-1998 */			bits_mot += WriteMVcomponent(local_f_code, (Int)(subdim*diff_v), bs);		}		break;	}	return bits_mot;}/***********************************************************CommentBegin****** * * -- WriteMVcomponent -- Encodes a single motion vector component * * Purpose : *      Scales the motion vector difference, VLC the most significant part, *      then outputs the residual (least significant part) as a FLC. * * Arguments in : *      Int   f_code,         Range for MV, (1/2/3) => (32/64/128) 1/2 units *      Float diff_vector,    MV Diff. component (in 1/2 units (in field)) *      Image bs              Bitstream output * * Return values : *      The number of bits for this encoding * * Side effects : *      The encoded motion vector is added to the bitstream * ***********************************************************CommentEnd********/IntWriteMVcomponent(	Int     f_code,	Int     dmv,	Image   *bs){	Int   residual, vlc_code_mag, bits, entry;		ScaleMVD(f_code, dmv, &residual, &vlc_code_mag);		if (vlc_code_mag < 0)		entry = vlc_code_mag + 65;		else		entry = vlc_code_mag;		bits = PutMV (entry, bs);		if ((f_code != 1) && (vlc_code_mag != 0))	{		BitstreamPutBits(bs, residual, f_code-1);			bits += f_code - 1;	}	return(bits);}/***********************************************************CommentBegin****** * * -- ScaleMVD -- Scales MVD component acording to the MV range * * Purpose : *      Scales a Motion Vector Difference (MVD) component (x or y) according *      to the MV range. The maximum range that can be represented is *      determined by the f_code encoded in the VOP header. Two values, *      vlc_code_mag and residual, are generated. * * Description : *      1) The range of the MV's is computed according to the f_code. *      2) The range of the MVD component is reduced to fall in the *         correct range. *      3) Two values are generated: *         vlc_code_mag: It will be VLC coded in other function. *         residual    : It will be FLC coded in other function. * ***********************************************************CommentEnd********/VoidScaleMVD (	Int  f_code,									  /* <-- MV range in 1/2 units: 1=32,2=64,...,7=2048     */	Int  diff_vector,								  /* <-- MV Difference commponent in 1/2 units           */	Int  *residual,									  /* --> value to be FLC coded                           */	Int  *vlc_code_mag								  /* --> value to be VLC coded                           */){	Int   range;		Int   scale_factor;		Int   r_size;		Int   low;		Int   high;		Int   aux;		r_size = f_code-1;		scale_factor = 1<<r_size;		range = 32*scale_factor;		low   = -range;		high  =  range-1;		if (diff_vector < low)

⌨️ 快捷键说明

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