📄 mot_code.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 . *
* *
**************************************************************************/
/**************************************************************************
*
* 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********/
Int
Bits_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********/
Int
WriteMVcomponent(
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********/
Void
ScaleMVD (
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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -