📄 mot_est_comp.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_est_comp.c
*
* Copyright (C) 2001 Project Mayo
*
* Adam Li
*
* DivX Advance Research Center <darc@projectmayo.com>
*
**************************************************************************/
/* This file contains some functions to do motion estimation and */
/* for the current image in one pass. */
/* 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 "mom_util.h"
#include "mot_util.h"
#include "mot_est_mb.h"
extern FILE *ftrace;
/* For correct rounding of chrominance vectors */
static Int roundtab16[] = {0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
Void MotionEstCompPicture (
SInt *curr,
SInt *prev,
SInt *prev_ipol_y,
SInt *prev_ipol_u,
SInt *prev_ipol_v,
Int prev_x,
Int prev_y,
Int vop_width,
Int vop_height,
Int enable_8x8_mv,
Int edge,
Int sr_for,
Int f_code,
Int rounding_type,
Int br_x,
Int br_y,
Int br_width,
Int br_height,
SInt *curr_comp_y,
SInt *curr_comp_u,
SInt *curr_comp_v,
Float *mad,
Float *mv16_w,
Float *mv16_h,
Float *mv8_w,
Float *mv8_h,
SInt *mode16
);
Void GetPred_Chroma (
Int x_curr,
Int y_curr,
Int dx,
Int dy,
SInt *prev_u,
SInt *prev_v,
SInt *comp_u,
SInt *comp_v,
Int width,
Int width_prev,
Int prev_x_min,
Int prev_y_min,
Int prev_x_max,
Int prev_y_max,
Int rounding_control
);
/***********************************************************CommentBegin******
*
* -- MotionEstimationCompensation -- Estimates the motion vectors and
* do motion compensation
*
* Purpose :
* Estimates the motion vectors in advanced/not_advanced unrestricted
* mode. The output are four images containing x/y components of
* MV's (one per 8x8 block), modes (one value per MB). The motion
* compensation is also performed.
*
* Description :
* 1) memory is allocated for these images.
* 2) mot_x/mot_y have 4 identical vector for a MB coded inter 16
* 3) mot_x/mot_y have 4 identical zero vectors for a MB coded intra
* 4) if _NO_ESTIMATION_ is used, the output is the following:
* - mot_x : all MV's are 0.0
* - mot_y : all MV's are 0.0
* - mode : all modes are MB_INTRA (IGNORING THE SHAPE)
*
* Based on: CodeOneOrTwo (TMN5, coder.c)
*
***********************************************************CommentEnd********/
Void
MotionEstimationCompensation (
Vop *curr_vop, /* <-- current Vop (for luminance) */
Vop *prev_rec_vop, /* <-- reference Vop (reconstructed)(1/2 pixel) */
Int enable_8x8_mv, /* <-- 8x8 MV (=1) or only 16x16 MV (=0) */
Int edge, /* <-- restricted(==0)/unrestricted(==edge) mode */
Int f_code, /* <-- MV search range 1/2 pel: 1=32,2=64,...,7=2048*/
Vop *curr_comp_vop, /* <-> motion compensated current VOP */
Float *mad, /* <-> mad value of the ME/MC result */
Image **mot_x, /* --> horizontal MV coordinates */
Image **mot_y, /* --> vertical MV coordinates */
Image **mode /* --> modes for each MB */
)
{
Image *pr_rec_y; /* Reference image (reconstructed) */
Image *pi_y; /* Interp.ref.image Y */
Image *mode16;
Image *mv16_w;
Image *mv16_h;
Image *mv8_w;
Image *mv8_h;
SInt *prev_ipol_y, /* Interp.ref.image Y (subimage) */
*prev_orig_y; /* Ref. original image with edge (subimage) */
Int vop_width, vop_height;
Int br_x;
Int br_y;
Int br_height;
Int br_width;
Int mv_h, mv_w;
/*GETBBR*/
br_y=curr_vop->ver_spat_ref;
br_x=curr_vop->hor_spat_ref;
br_height=curr_vop->height;
br_width=curr_vop->width;
mv_h=br_height/MB_SIZE;
mv_w=br_width/MB_SIZE;
/*
** WE SUPPOSE prev_rec_vop & prev_vop HAVE EQUAL SIZE AND POSITIONS
*/
vop_width=prev_rec_vop->width;
vop_height=prev_rec_vop->height;
/*
** Get images and interpolate them
*/
pr_rec_y = prev_rec_vop->y_chan;
prev_orig_y = (SInt*)GetImageData(pr_rec_y);
pi_y = AllocImage (2*vop_width, 2*vop_height, SHORT_TYPE);
InterpolateImage(pr_rec_y, pi_y, GetVopRoundingType(curr_vop));
prev_ipol_y = (SInt*)GetImageData(pi_y);
/*
* allocate memory for mv's and modes data
*
*/
mode16=AllocImage (mv_w,mv_h,SHORT_TYPE);
SetConstantImage (mode16,(Float)MBM_INTRA);
/*
** mv16 have 2x2 repeted the mv value to share the functions of
** mv prediction between CodeVopVotion and MotionEstimation
*/
mv16_w=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
mv16_h=AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
mv8_w =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
mv8_h =AllocImage (mv_w*2,mv_h*2,FLOAT_TYPE);
SetConstantImage (mv16_h,+0.0);
SetConstantImage (mv16_w,+0.0);
SetConstantImage (mv8_h,+0.0);
SetConstantImage (mv8_w,+0.0);
SetConstantImage (curr_comp_vop->u_chan, 0);
SetConstantImage (curr_comp_vop->v_chan, 0);
/* Compute motion vectors and modes for each MB
** (TMN5 functions)
*/
MotionEstCompPicture(
(SInt *)GetImageData(GetVopY(curr_vop)), //curr_vop,
prev_orig_y, /* Y padd with edge */
prev_ipol_y, /* Y interpolated (from pi_y) */
(SInt*)GetImageData(prev_rec_vop->u_chan) + (vop_width/2) * (16/2) + (16/2),
(SInt*)GetImageData(prev_rec_vop->v_chan) + (vop_width/2) * (16/2) + (16/2),
prev_rec_vop->hor_spat_ref,
prev_rec_vop->ver_spat_ref,
vop_width,vop_height,
enable_8x8_mv,
edge,
GetVopSearchRangeFor(curr_vop),
f_code,
GetVopRoundingType(curr_vop),
br_x,br_y, /* pos. of the bounding rectangle */
br_width,br_height, /* dims. of the bounding rectangle */
(SInt*)GetImageData(curr_comp_vop->y_chan),
(SInt*)GetImageData(curr_comp_vop->u_chan),
(SInt*)GetImageData(curr_comp_vop->v_chan),
mad,
(Float*)GetImageData(mv16_w),
(Float*)GetImageData(mv16_h),
(Float*)GetImageData(mv8_w),
(Float*)GetImageData(mv8_h),
(SInt*) GetImageData(mode16)
);
/* Convert output to MOMUSYS format */
GetMotionImages(mv16_w, mv16_h, mv8_w, mv8_h, mode16, mot_x, mot_y, mode);
/* Deallocate dynamic memory */
FreeImage(mv16_w); FreeImage(mv16_h);
FreeImage(mv8_w); FreeImage(mv8_h);
FreeImage(mode16);
FreeImage(pi_y);
}
/***********************************************************CommentBegin******
*
* -- MotionEstCompPicture -- Computes MV's and predictor errors and
* do motion compensation
*
* Purpose :
* Computes MV's (8x8 and 16x16) and predictor errors for the whole
* vop. Perform motion compensation for the whole vop.
*
***********************************************************CommentEnd********/
Void
MotionEstCompPicture(
SInt *curr, /* <-- Current VOP */
SInt *prev, /* <-- Original Y padd with edge */
SInt *prev_ipol, /* <-- Y interpolated (from pi_y) */
SInt *prev_u, /* <-- Original U padd with edge */
SInt *prev_v, /* <-- Original V padd with edge */
Int prev_x, /* <-- absolute horiz. position of previous vop */
Int prev_y, /* <-- absolute verti. position of previous vop */
Int vop_width, /* <-- horizontal previous vop dimension */
Int vop_height, /* <-- vertical previous vop dimension */
Int enable_8x8_mv, /* <-- 8x8 MV (=1) or only 16x16 MV (=0) */
Int edge, /* <-- edge arround the reference vop */
Int sr_for, /* <-- forward search range */
Int f_code, /* MW QPEL 07-JUL-1998 *//* <-- MV search range 1/2 or 1/4 pel: 1=32,2=64,...,7=2048*/
Int rounding_type, /* <-- The rounding type of the current vop */
Int br_x, /* <-- absolute horiz. position of the current vop */
Int br_y, /* <-- absolute verti. position of the current vop */
Int br_width, /* <-- current bounding rectangule width */
Int br_height, /* <-- current bounding rectangle height */
SInt *curr_comp_y, /* <-> motion compensated current Y */
SInt *curr_comp_u, /* <-> motion compensated current U */
SInt *curr_comp_v, /* <-> motion compensated current V */
Float *mad, /* <-> the mad value of current ME/MC result */
Float *mv16_w, /* --> predicted horizontal 16x16 MV(if approp.) */
Float *mv16_h, /* --> predicted vertical 16x16 MV (if approp.) */
Float *mv8_w, /* --> predicted horizontal 8x8 MV (if approp.) */
Float *mv8_h, /* --> predicted vertical 8x8 MV (if approp.) */
SInt *mode16 /* --> mode of the preditect motion vector */
)
{
Int i, j, k;
SInt curr_mb[MB_SIZE][MB_SIZE];
SInt curr_comp_mb_16[MB_SIZE][MB_SIZE];
SInt curr_comp_mb_8[MB_SIZE][MB_SIZE];
Int sad8 = MV_MAX_ERROR, sad16, sad;
Int imas_w, imas_h, Mode;
Int posmode, pos16, pos8;
Int min_error16,
min_error8_0, min_error8_1, min_error8_2, min_error8_3;
// SInt *curr = (SInt *)GetImageData(GetVopY(curr_vop));
/***************************************************************************
array of flags, which contains for the MB and for each one of the 4 Blocks
the following info sequentially:
xm, 1 if the lower search (x axis) is completed (no 1/2 search can be done)
0, do 1/2 search in the lower bound (x axis)
xM, 1 if the upper search (x axis) is completed (no 1/2 search can be done)
0, do 1/2 search in the upper bound (x axis)
ym, 1 if the lower search (y axis) is completed (no 1/2 search can be done)
0, do 1/2 search in the lower bound (y axis)
yM, 1 if the upper search (y axis) is completed (no 1/2 search can be done)
0, do 1/2 search in the upper bound (y axis)
***************************************************************************/
SInt *halfpelflags;
Float hint_mv_w, hint_mv_h;
Int xsum,ysum,dx,dy;
Int prev_x_min,prev_x_max,prev_y_min,prev_y_max;
prev_x_min = 2 * prev_x + 2 * 16;
prev_y_min = 2 * prev_y + 2 * 16;
prev_x_max = prev_x_min + 2 * vop_width - 4 * 16;
prev_y_max = prev_y_min + 2 * vop_height - 4 * 16;
imas_w=br_width/MB_SIZE;
imas_h=br_height/MB_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -