142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* ------------------------------------------------------------------
242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * Copyright (C) 1998-2009 PacketVideo
342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *
442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * Licensed under the Apache License, Version 2.0 (the "License");
542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * you may not use this file except in compliance with the License.
642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * You may obtain a copy of the License at
742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *
842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *      http://www.apache.org/licenses/LICENSE-2.0
942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong *
1042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * Unless required by applicable law or agreed to in writing, software
1142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * distributed under the License is distributed on an "AS IS" BASIS,
1242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * express or implied.
1442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * See the License for the specific language governing permissions
1542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * and limitations under the License.
1642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong * -------------------------------------------------------------------
1742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong */
1842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "mp4def.h"
1942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "mp4enc_lib.h"
2042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "mp4lib_int.h"
2142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#include "m4venc_oscl.h"
2242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
2342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//#define PRINT_MV
2442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define MIN_GOP 1   /* minimum size of GOP,  1/23/01, need to be tested */
2542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
2642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define CANDIDATE_DISTANCE  0 /* distance candidate from one another to consider as a distinct one */
2742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* shouldn't be more than 3 */
2842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
2942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define ZERO_MV_PREF    0 /* 0: bias (0,0)MV before full-pel search, lowest complexity*/
3042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* 1: bias (0,0)MV after full-pel search, before half-pel, highest comp */
3142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* 2: bias (0,0)MV after half-pel, high comp, better PSNR */
3242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
3342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define RASTER_REFRESH  /* instead of random INTRA refresh, do raster scan,  2/26/01 */
3442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
3542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef RASTER_REFRESH
3642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define TARGET_REFRESH_PER_REGION 4 /* , no. MB per frame to be INTRA refreshed */
3742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#else
3842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define TARGET_REFRESH_PER_REGION 1 /* , no. MB per region to be INTRA refreshed */
3942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
4042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
4142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define ALL_CAND_EQUAL  10  /*  any number greater than 5 will work */
4242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
4342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define NumPixelMB  256     /*  number of pixels used in SAD calculation */
4442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
4542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define DEF_8X8_WIN 3   /* search region for 8x8 MVs around the 16x16 MV */
4642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define MB_Nb  256
4742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
4842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define PREF_NULL_VEC 129   /* for zero vector bias */
4942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define PREF_16_VEC 129     /* 1MV bias versus 4MVs*/
5042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define PREF_INTRA  512     /* bias for INTRA coding */
5142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
5242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongconst static Int tab_exclude[9][9] =  // [last_loc][curr_loc]
5342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
5442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 0, 0, 0, 0, 0, 0, 0, 0},
5542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 0, 0, 0, 1, 1, 1, 0, 0},
5642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 0, 0, 0, 1, 1, 1, 1, 1},
5742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 0, 0, 0, 0, 0, 1, 1, 1},
5842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 1, 1, 0, 0, 0, 1, 1, 1},
5942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 1, 1, 0, 0, 0, 0, 0, 1},
6042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 1, 1, 1, 1, 0, 0, 0, 1},
6142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 0, 1, 1, 1, 0, 0, 0, 0},
6242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 0, 1, 1, 1, 1, 1, 0, 0}
6342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}; //to decide whether to continue or compute
6442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
6542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongconst static Int refine_next[8][2] =    /* [curr_k][increment] */
6642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
6742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {0, 0}, {2, 0}, {1, 1}, {0, 2}, { -1, 1}, { -2, 0}, { -1, -1}, {0, -2}
6842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong};
6942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
7042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef __cplusplus
7142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongextern "C"
7242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
7342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
7442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
7542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void MBMotionSearch(VideoEncData *video, UChar *cur, UChar *best_cand[],
7642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i0, Int j0, Int type_pred, Int fullsearch, Int *hp_guess);
7742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
7842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int  fullsearch(VideoEncData *video, Vol *currVol, UChar *ref, UChar *cur,
7942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh);
8042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int fullsearchBlk(VideoEncData *video, Vol *currVol, UChar *cent, UChar *cur,
8142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                      Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh, Int range);
8242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void CandidateSelection(Int *mvx, Int *mvy, Int *num_can, Int imb, Int jmb,
8342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            VideoEncData *video, Int type_pred);
8442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void RasterIntraUpdate(UChar *intraArray, UChar *Mode, Int totalMB, Int numRefresh);
8542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void ResetIntraUpdate(UChar *intraArray, Int totalMB);
8642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void ResetIntraUpdateRegion(UChar *intraArray, Int start_i, Int rwidth,
8742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                Int start_j, Int rheight, Int mbwidth, Int mbheight);
8842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
8942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void MoveNeighborSAD(Int dn[], Int new_loc);
9042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int FindMin(Int dn[]);
9142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void PrepareCurMB(VideoEncData *video, UChar *cur);
9242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
9342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef __cplusplus
9442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
9542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
9642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
9742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/***************************************/
9842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*  2/28/01, for HYPOTHESIS TESTING */
9942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef HTFM     /* defined in mp4def.h */
10042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef __cplusplus
10142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongextern "C"
10242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
10342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
10442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void CalcThreshold(double pf, double exp_lamda[], Int nrmlz_th[]);
10542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void    HTFMPrepareCurMB(VideoEncData *video, HTFM_Stat *htfm_stat, UChar *cur);
10642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef __cplusplus
10742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
10842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
10942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
11042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
11142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#define HTFM_Pf  0.25   /* 3/2/1, probability of false alarm, can be varied from 0 to 0.5 */
11242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/***************************************/
11342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
11442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
11542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef _SAD_STAT
11642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong num_MB = 0;
11742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong num_HP_MB = 0;
11842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong num_Blk = 0;
11942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong num_HP_Blk = 0;
12042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong num_cand = 0;
12142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong num_better_hp = 0;
12242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong i_dist_from_guess = 0;
12342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong j_dist_from_guess = 0;
12442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongULong num_hp_not_zero = 0;
12542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
12642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
12742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
12842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
12942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*==================================================================
13042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   MotionEstimation
13142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       10/3/2000
13242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Go through all macroblock for motion search and
13342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                determine scene change detection.
13442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong====================================================================*/
13542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
13642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid MotionEstimation(VideoEncData *video)
13742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
13842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar use_4mv = video->encParams->MV8x8_Enabled;
13942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vol *currVol = video->vol[video->currLayer];
14042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vop *currVop = video->currVop;
14142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    VideoEncFrameIO *currFrame = video->input;
14242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i, j, comp;
14342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbwidth = currVol->nMBPerRow;
14442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbheight = currVol->nMBPerCol;
14542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int totalMB = currVol->nTotalMB;
14642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int width = currFrame->pitch;
14742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *mode_mb, *Mode = video->headerInfo.Mode;
14842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    MOT *mot_mb, **mot = video->mot;
14942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *intraArray = video->intraArray;
15042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int FS_en = video->encParams->FullSearch_Enabled;
15142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void (*ComputeMBSum)(UChar *, Int, MOT *) = video->functionPointer->ComputeMBSum;
15242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void (*ChooseMode)(UChar*, UChar*, Int, Int) = video->functionPointer->ChooseMode;
15342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
15442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int numIntra, start_i, numLoop, incr_i;
15542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbnum, offset;
15642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *cur, *best_cand[5];
15742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int sad8 = 0, sad16 = 0;
15842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int totalSAD = 0;   /* average SAD for rate control */
15942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int skip_halfpel_4mv;
16042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int f_code_p, f_code_n, max_mag = 0, min_mag = 0;
16142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int type_pred;
16242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int xh[5] = {0, 0, 0, 0, 0};
16342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int yh[5] = {0, 0, 0, 0, 0}; /* half-pel */
16442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar hp_mem4MV[17*17*4];
16542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
16642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef HTFM
16742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /***** HYPOTHESIS TESTING ********/  /* 2/28/01 */
16842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int collect = 0;
16942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    HTFM_Stat htfm_stat;
17042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    double newvar[16];
17142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    double exp_lamda[15];
17242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /*********************************/
17342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
17442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int hp_guess = 0;
17542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
17642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    FILE *fp_debug;
17742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
17842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
17942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//  FILE *fstat;
18042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//  static int frame_num = 0;
18142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
18242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset = 0;
18342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
18442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (video->currVop->predictionType == I_VOP)
18542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {   /* compute the SAV */
18642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mbnum = 0;
18742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        cur = currFrame->yChan;
18842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
18942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (j = 0; j < mbheight; j++)
19042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
19142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            for (i = 0; i < mbwidth; i++)
19242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
19342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->mbnum = mbnum;
19442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot_mb = mot[mbnum];
19542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
19642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                (*ComputeMBSum)(cur + (i << 4), width, mot_mb);
19742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
19842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                totalSAD += mot_mb[0].sad;
19942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
20042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mbnum++;
20142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
20242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            cur += (width << 4);
20342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
20442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
20542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->sumMAD = (float)totalSAD / (float)NumPixelMB;
20642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
20742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ResetIntraUpdate(intraArray, totalMB);
20842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
20942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        return  ;
21042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
21142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
21242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* 09/20/05 */
21342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (video->prevBaseVop->padded == 0 && !video->encParams->H263_Enabled)
21442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
21542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        PaddingEdge(video->prevBaseVop);
21642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->prevBaseVop->padded = 1;
21742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
21842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
21942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* Random INTRA update */
22042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /*  suggest to do it in CodeMB */
22142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /*  2/21/2001 */
22242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    //if(video->encParams->RC_Type == CBR_1 || video->encParams->RC_Type == CBR_2)
22342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (video->currLayer == 0 && video->encParams->Refresh)
22442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
22542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        RasterIntraUpdate(intraArray, Mode, totalMB, video->encParams->Refresh);
22642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
22742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
22842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    video->sad_extra_info = NULL;
22942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
23042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef HTFM
23142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /***** HYPOTHESIS TESTING ********/  /* 2/28/01 */
23242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    InitHTFM(video, &htfm_stat, newvar, &collect);
23342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /*********************************/
23442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
23542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
23642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if ((video->encParams->SceneChange_Det == 1) /*&& video->currLayer==0 */
23742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            && ((video->encParams->LayerFrameRate[0] < 5.0) || (video->numVopsInGOP > MIN_GOP)))
23842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        /* do not try to detect a new scene if low frame rate and too close to previous I-frame */
23942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
24042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        incr_i = 2;
24142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        numLoop = 2;
24242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        start_i = 1;
24342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        type_pred = 0; /* for initial candidate selection */
24442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
24542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
24642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
24742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        incr_i = 1;
24842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        numLoop = 1;
24942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        start_i = 0;
25042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        type_pred = 2;
25142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
25242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
25342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* First pass, loop thru half the macroblock */
25442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* determine scene change */
25542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* Second pass, for the rest of macroblocks */
25642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    numIntra = 0;
25742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    while (numLoop--)
25842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
25942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (j = 0; j < mbheight; j++)
26042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
26142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (incr_i > 1)
26242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                start_i = (start_i == 0 ? 1 : 0) ; /* toggle 0 and 1 */
26342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
26442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            offset = width * (j << 4) + (start_i << 4);
26542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
26642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mbnum = j * mbwidth + start_i;
26742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
26842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            for (i = start_i; i < mbwidth; i += incr_i)
26942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
27042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->mbnum = mbnum;
27142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot_mb = mot[mbnum];
27242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mode_mb = Mode + mbnum;
27342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
27442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cur = currFrame->yChan + offset;
27542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
27642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
27742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (*mode_mb != MODE_INTRA)
27842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
27942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#if defined(HTFM)
28042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    HTFMPrepareCurMB(video, &htfm_stat, cur);
28142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#else
28242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    PrepareCurMB(video, cur);
28342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
28442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /************************************************************/
28542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /******** full-pel 1MV and 4MVs search **********************/
28642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
28742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef _SAD_STAT
28842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    num_MB++;
28942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
29042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    MBMotionSearch(video, cur, best_cand, i << 4, j << 4, type_pred,
29142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                   FS_en, &hp_guess);
29242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
29342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
29442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
29542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fprintf(fp_debug, "#%d (%d,%d,%d) : ", mbnum, mot_mb[0].x, mot_mb[0].y, mot_mb[0].sad);
29642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fprintf(fp_debug, "(%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) : ==>\n",
29742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            mot_mb[1].x, mot_mb[1].y, mot_mb[1].sad,
29842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            mot_mb[2].x, mot_mb[2].y, mot_mb[2].sad,
29942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            mot_mb[3].x, mot_mb[3].y, mot_mb[3].sad,
30042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            mot_mb[4].x, mot_mb[4].y, mot_mb[4].sad);
30142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fclose(fp_debug);
30242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
30342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    sad16 = mot_mb[0].sad;
30442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef NO_INTER4V
30542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    sad8 = sad16;
30642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#else
30742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    sad8 = mot_mb[1].sad + mot_mb[2].sad + mot_mb[3].sad + mot_mb[4].sad;
30842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
30942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
31042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /* choose between INTRA or INTER */
31142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    (*ChooseMode)(mode_mb, cur, width, ((sad8 < sad16) ? sad8 : sad16));
31242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
31342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else    /* INTRA update, use for prediction 3/23/01 */
31442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
31542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    mot_mb[0].x = mot_mb[0].y = 0;
31642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
31742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
31842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (*mode_mb == MODE_INTRA)
31942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
32042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    numIntra++ ;
32142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
32242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /* compute SAV for rate control and fast DCT, 11/28/00 */
32342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    (*ComputeMBSum)(cur, width, mot_mb);
32442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
32542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /* leave mot_mb[0] as it is for fast motion search */
32642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /* set the 4 MVs to zeros */
32742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    for (comp = 1; comp <= 4; comp++)
32842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
32942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb[comp].x = 0;
33042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb[comp].y = 0;
33142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
33242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
33342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
33442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fprintf(fp_debug, "\n");
33542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fclose(fp_debug);
33642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
33742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
33842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else /* *mode_mb = MODE_INTER;*/
33942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
34042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (video->encParams->HalfPel_Enabled)
34142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
34242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef _SAD_STAT
34342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        num_HP_MB++;
34442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
34542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        /* find half-pel resolution motion vector */
34642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        FindHalfPelMB(video, cur, mot_mb, best_cand[0],
34742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                      i << 4, j << 4, xh, yh, hp_guess);
34842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
34942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
35042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        fprintf(fp_debug, "(%d,%d), %d\n", mot_mb[0].x, mot_mb[0].y, mot_mb[0].sad);
35142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        fclose(fp_debug);
35242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
35342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        skip_halfpel_4mv = ((sad16 - mot_mb[0].sad) <= (MB_Nb >> 1) + 1);
35442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        sad16 = mot_mb[0].sad;
35542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
35642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_INTER4V
35742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (use_4mv && !skip_halfpel_4mv)
35842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
35942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            /* Also decide 1MV or 4MV !!!!!!!!*/
36042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            sad8 = FindHalfPelBlk(video, cur, mot_mb, sad16,
36142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                                  best_cand, mode_mb, i << 4, j << 4, xh, yh, hp_mem4MV);
36242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
36342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
36442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
36542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            fprintf(fp_debug, " (%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) \n",
36642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    mot_mb[1].x, mot_mb[1].y, mot_mb[1].sad,
36742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    mot_mb[2].x, mot_mb[2].y, mot_mb[2].sad,
36842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    mot_mb[3].x, mot_mb[3].y, mot_mb[3].sad,
36942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    mot_mb[4].x, mot_mb[4].y, mot_mb[4].sad);
37042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            fclose(fp_debug);
37142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
37242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
37342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif /* NO_INTER4V */
37442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
37542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    else    /* HalfPel_Enabled ==0  */
37642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
37742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_INTER4V
37842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        //if(sad16 < sad8-PREF_16_VEC)
37942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (sad16 - PREF_16_VEC > sad8)
38042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
38142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            *mode_mb = MODE_INTER4V;
38242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
38342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
38442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
38542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#if (ZERO_MV_PREF==2)   /* use mot_mb[7].sad as d0 computed in MBMotionSearch*/
38642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /******************************************************/
38742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (mot_mb[7].sad - PREF_NULL_VEC < sad16 && mot_mb[7].sad - PREF_NULL_VEC < sad8)
38842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
38942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb[0].sad = mot_mb[7].sad - PREF_NULL_VEC;
39042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb[0].x = mot_mb[0].y = 0;
39142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        *mode_mb = MODE_INTER;
39242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
39342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /******************************************************/
39442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
39542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (*mode_mb == MODE_INTER)
39642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
39742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (mot_mb[0].x == 0 && mot_mb[0].y == 0)   /* use zero vector */
39842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            mot_mb[0].sad += PREF_NULL_VEC; /* add back the bias */
39942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
40042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb[1].sad = mot_mb[2].sad = mot_mb[3].sad = mot_mb[4].sad = (mot_mb[0].sad + 2) >> 2;
40142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb[1].x = mot_mb[2].x = mot_mb[3].x = mot_mb[4].x = mot_mb[0].x;
40242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb[1].y = mot_mb[2].y = mot_mb[3].y = mot_mb[4].y = mot_mb[0].y;
40342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
40442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
40542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
40642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
40742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* find maximum magnitude */
40842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* compute average SAD for rate control, 11/28/00 */
40942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (*mode_mb == MODE_INTER)
41042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
41142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
41242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
41342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fprintf(fp_debug, "%d MODE_INTER\n", mbnum);
41442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fclose(fp_debug);
41542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
41642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    totalSAD += mot_mb[0].sad;
41742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (mot_mb[0].x > max_mag)
41842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        max_mag = mot_mb[0].x;
41942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (mot_mb[0].y > max_mag)
42042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        max_mag = mot_mb[0].y;
42142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (mot_mb[0].x < min_mag)
42242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        min_mag = mot_mb[0].x;
42342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (mot_mb[0].y < min_mag)
42442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        min_mag = mot_mb[0].y;
42542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
42642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else if (*mode_mb == MODE_INTER4V)
42742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
42842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
42942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
43042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fprintf(fp_debug, "%d MODE_INTER4V\n", mbnum);
43142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fclose(fp_debug);
43242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
43342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    totalSAD += sad8;
43442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    for (comp = 1; comp <= 4; comp++)
43542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
43642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (mot_mb[comp].x > max_mag)
43742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            max_mag = mot_mb[comp].x;
43842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (mot_mb[comp].y > max_mag)
43942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            max_mag = mot_mb[comp].y;
44042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (mot_mb[comp].x < min_mag)
44142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            min_mag = mot_mb[comp].x;
44242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (mot_mb[comp].y < min_mag)
44342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            min_mag = mot_mb[comp].y;
44442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
44542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
44642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else    /* MODE_INTRA */
44742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
44842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef PRINT_MV
44942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
45042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fprintf(fp_debug, "%d MODE_INTRA\n", mbnum);
45142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    fclose(fp_debug);
45242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
45342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    totalSAD += mot_mb[0].sad;
45442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
45542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mbnum += incr_i;
45642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                offset += (incr_i << 4);
45742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
45842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
45942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
46042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
46142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (incr_i > 1 && numLoop) /* scene change on and first loop */
46242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
46342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            //if(numIntra > ((totalMB>>3)<<1) + (totalMB>>3)) /* 75% of 50%MBs */
46442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (numIntra > (0.30*(totalMB / 2.0))) /* 15% of 50%MBs */
46542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
46642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /******** scene change detected *******************/
46742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                currVop->predictionType = I_VOP;
46842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                M4VENC_MEMSET(Mode, MODE_INTRA, sizeof(UChar)*totalMB); /* set this for MB level coding*/
46942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                currVop->quantizer = video->encParams->InitQuantIvop[video->currLayer];
47042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
47142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* compute the SAV for rate control & fast DCT */
47242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                totalSAD = 0;
47342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                offset = 0;
47442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mbnum = 0;
47542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cur = currFrame->yChan;
47642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
47742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                for (j = 0; j < mbheight; j++)
47842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
47942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    for (i = 0; i < mbwidth; i++)
48042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
48142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        video->mbnum = mbnum;
48242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mot_mb = mot[mbnum];
48342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
48442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
48542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        (*ComputeMBSum)(cur + (i << 4), width, mot_mb);
48642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        totalSAD += mot_mb[0].sad;
48742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
48842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        mbnum++;
48942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
49042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    cur += (width << 4);
49142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
49242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
49342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                video->sumMAD = (float)totalSAD / (float)NumPixelMB;
49442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                ResetIntraUpdate(intraArray, totalMB);
49542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* video->numVopsInGOP=0; 3/13/01 move it to vop.c*/
49642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
49742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                return ;
49842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
49942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
50042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        /******** no scene change, continue motion search **********************/
50142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        start_i = 0;
50242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        type_pred++; /* second pass */
50342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
50442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
50542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    video->sumMAD = (float)totalSAD / (float)NumPixelMB;    /* avg SAD */
50642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
50742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* find f_code , 10/27/2000 */
50842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    f_code_p = 1;
50942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    while ((max_mag >> (4 + f_code_p)) > 0)
51042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        f_code_p++;
51142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
51242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    f_code_n = 1;
51342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    min_mag *= -1;
51442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    while ((min_mag - 1) >> (4 + f_code_n) > 0)
51542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        f_code_n++;
51642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
51742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    currVop->fcodeForward = (f_code_p > f_code_n ? f_code_p : f_code_n);
51842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
51942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef HTFM
52042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /***** HYPOTHESIS TESTING ********/  /* 2/28/01 */
52142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (collect)
52242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
52342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        collect = 0;
52442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        UpdateHTFM(video, newvar, exp_lamda, &htfm_stat);
52542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
52642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /*********************************/
52742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
52842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
52942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
53042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
53142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
53242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
53342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef HTFM
53442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid InitHTFM(VideoEncData *video, HTFM_Stat *htfm_stat, double *newvar, Int *collect)
53542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
53642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i;
53742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx = video->currVop->width; //  padding
53842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx2 = lx << 1;
53942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx3 = lx2 + lx;
54042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int rx = video->currVop->pitch;
54142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int rx2 = rx << 1;
54242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int rx3 = rx2 + rx;
54342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
54442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int *offset, *offset2;
54542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
54642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* 4/11/01, collect data every 30 frames, doesn't have to be base layer */
54742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (((Int)video->numVopsInGOP) % 30 == 1)
54842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
54942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
55042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *collect = 1;
55142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
55242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        htfm_stat->countbreak = 0;
55342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        htfm_stat->abs_dif_mad_avg = 0;
55442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
55542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (i = 0; i < 16; i++)
55642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
55742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            newvar[i] = 0.0;
55842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
55942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//      video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM_Collect;
56042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_Macroblock = &SAD_MB_HTFM_Collect;
56142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[0] = NULL;
56242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFM_Collectxh;
56342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFM_Collectyh;
56442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFM_Collectxhyh;
56542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->sad_extra_info = (void*)(htfm_stat);
56642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset = htfm_stat->offsetArray;
56742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset2 = htfm_stat->offsetRef;
56842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
56942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
57042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
57142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//      video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM;
57242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_Macroblock = &SAD_MB_HTFM;
57342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[0] = NULL;
57442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFMxh;
57542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFMyh;
57642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFMxhyh;
57742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        video->sad_extra_info = (void*)(video->nrmlz_th);
57842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset = video->nrmlz_th + 16;
57942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset2 = video->nrmlz_th + 32;
58042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
58142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
58242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[0] = 0;
58342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[1] = lx2 + 2;
58442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[2] = 2;
58542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[3] = lx2;
58642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[4] = lx + 1;
58742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[5] = lx3 + 3;
58842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[6] = lx + 3;
58942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[7] = lx3 + 1;
59042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[8] = lx;
59142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[9] = lx3 + 2;
59242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[10] = lx3 ;
59342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[11] = lx + 2 ;
59442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[12] = 1;
59542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[13] = lx2 + 3;
59642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[14] = lx2 + 1;
59742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset[15] = 3;
59842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
59942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[0] = 0;
60042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[1] = rx2 + 2;
60142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[2] = 2;
60242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[3] = rx2;
60342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[4] = rx + 1;
60442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[5] = rx3 + 3;
60542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[6] = rx + 3;
60642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[7] = rx3 + 1;
60742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[8] = rx;
60842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[9] = rx3 + 2;
60942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[10] = rx3 ;
61042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[11] = rx + 2 ;
61142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[12] = 1;
61242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[13] = rx2 + 3;
61342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[14] = rx2 + 1;
61442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    offset2[15] = 3;
61542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
61642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
61742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
61842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
61942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid UpdateHTFM(VideoEncData *video, double *newvar, double *exp_lamda, HTFM_Stat *htfm_stat)
62042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
62142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (htfm_stat->countbreak == 0)
62242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        htfm_stat->countbreak = 1;
62342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
62442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    newvar[0] = (double)(htfm_stat->abs_dif_mad_avg) / (htfm_stat->countbreak * 16.);
62542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
62642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (newvar[0] < 0.001)
62742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
62842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        newvar[0] = 0.001; /* to prevent floating overflow */
62942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
63042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[0] =  1 / (newvar[0] * 1.4142136);
63142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[1] = exp_lamda[0] * 1.5825;
63242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[2] = exp_lamda[0] * 2.1750;
63342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[3] = exp_lamda[0] * 3.5065;
63442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[4] = exp_lamda[0] * 3.1436;
63542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[5] = exp_lamda[0] * 3.5315;
63642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[6] = exp_lamda[0] * 3.7449;
63742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[7] = exp_lamda[0] * 4.5854;
63842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[8] = exp_lamda[0] * 4.6191;
63942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[9] = exp_lamda[0] * 5.4041;
64042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[10] = exp_lamda[0] * 6.5974;
64142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[11] = exp_lamda[0] * 10.5341;
64242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[12] = exp_lamda[0] * 10.0719;
64342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[13] = exp_lamda[0] * 12.0516;
64442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    exp_lamda[14] = exp_lamda[0] * 15.4552;
64542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
64642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    CalcThreshold(HTFM_Pf, exp_lamda, video->nrmlz_th);
64742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
64842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
64942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
65042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
65142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid CalcThreshold(double pf, double exp_lamda[], Int nrmlz_th[])
65242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
65342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i;
65442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    double temp[15];
65542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    //  printf("\nLamda: ");
65642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
65742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* parametric PREMODELling */
65842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (i = 0; i < 15; i++)
65942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
66042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        //    printf("%g ",exp_lamda[i]);
66142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (pf < 0.5)
66242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            temp[i] = 1 / exp_lamda[i] * M4VENC_LOG(2 * pf);
66342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else
66442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            temp[i] = -1 / exp_lamda[i] * M4VENC_LOG(2 * (1 - pf));
66542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
66642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
66742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    nrmlz_th[15] = 0;
66842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (i = 0; i < 15; i++)        /* scale upto no.pixels */
66942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        nrmlz_th[i] = (Int)(temp[i] * ((i + 1) << 4) + 0.5);
67042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
67142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
67242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
67342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
67442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid    HTFMPrepareCurMB(VideoEncData *video, HTFM_Stat *htfm_stat, UChar *cur)
67542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
67642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void* tmp = (void*)(video->currYMB);
67742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    ULong *htfmMB = (ULong*)tmp;
67842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *ptr, byte;
67942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int *offset;
68042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i;
68142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    ULong word;
68242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int width = video->currVop->width;
68342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
68442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (((Int)video->numVopsInGOP) % 30 == 1)
68542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
68642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset = htfm_stat->offsetArray;
68742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
68842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
68942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
69042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        offset = video->nrmlz_th + 16;
69142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
69242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
69342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (i = 0; i < 16; i++)
69442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
69542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ptr = cur + offset[i];
69642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word = ptr[0];
69742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[4];
69842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 8);
69942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[8];
70042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 16);
70142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[12];
70242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 24);
70342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *htfmMB++ = word;
70442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
70542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word = *(ptr += (width << 2));
70642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[4];
70742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 8);
70842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[8];
70942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 16);
71042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[12];
71142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 24);
71242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *htfmMB++ = word;
71342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
71442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word = *(ptr += (width << 2));
71542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[4];
71642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 8);
71742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[8];
71842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 16);
71942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[12];
72042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 24);
72142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *htfmMB++ = word;
72242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
72342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word = *(ptr += (width << 2));
72442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[4];
72542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 8);
72642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[8];
72742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 16);
72842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        byte = ptr[12];
72942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        word |= (byte << 24);
73042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *htfmMB++ = word;
73142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
73242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
73342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
73442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
73542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
73642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
73742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
73842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
73942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid    PrepareCurMB(VideoEncData *video, UChar *cur)
74042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
74142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void* tmp = (void*)(video->currYMB);
74242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    ULong *currYMB = (ULong*)tmp;
74342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i;
74442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int width = video->currVop->width;
74542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
74642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    cur -= width;
74742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
74842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (i = 0; i < 16; i++)
74942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
75042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *currYMB++ = *((ULong*)(cur += width));
75142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *currYMB++ = *((ULong*)(cur + 4));
75242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *currYMB++ = *((ULong*)(cur + 8));
75342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *currYMB++ = *((ULong*)(cur + 12));
75442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
75542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
75642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
75742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
75842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
75942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
76042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*==================================================================
76142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   MBMotionSearch
76242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       09/06/2000
76342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Perform motion estimation for a macroblock.
76442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                Find 1MV and 4MVs in half-pels resolutions.
76542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                Using ST1 algorithm provided by Chalidabhongse and Kuo
76642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                CSVT March'98.
76742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
76842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong==================================================================*/
76942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
77042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid MBMotionSearch(VideoEncData *video, UChar *cur, UChar *best_cand[],
77142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    Int i0, Int j0, Int type_pred, Int FS_en, Int *hp_guess)
77242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
77342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vol *currVol = video->vol[video->currLayer];
77442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *ref, *cand, *ncand = NULL, *cur8;
77542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void *extra_info = video->sad_extra_info;
77642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbnum = video->mbnum;
77742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int width = video->currVop->width; /* 6/12/01, must be multiple of 16 */
77842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int height = video->currVop->height;
77942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    MOT **mot = video->mot;
78042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar use_4mv = video->encParams->MV8x8_Enabled;
78142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar h263_mode = video->encParams->H263_Enabled;
78242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int(*SAD_Macroblock)(UChar*, UChar*, Int, void*) = video->functionPointer->SAD_Macroblock;
78342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int(*SAD_Block)(UChar*, UChar*, Int, Int, void*) = video->functionPointer->SAD_Block;
78442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    VideoEncParams *encParams = video->encParams;
78542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int range = encParams->SearchRange;
78642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
78742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx = video->currVop->pitch; /* padding */
78842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int comp;
78942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i, j, imin, jmin, ilow, ihigh, jlow, jhigh, iorg, jorg;
79042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int d, dmin, dn[9];
79142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#if (ZERO_MV_PREF==1)   /* compute (0,0) MV at the end */
79242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int d0;
79342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
79442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int k;
79542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mvx[5], mvy[5], imin0, jmin0;
79642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int num_can, center_again;
79742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int last_loc, new_loc = 0;
79842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int step, max_step = range >> 1;
79942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int next;
80042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
80142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    ref = video->forwardRefVop->yChan; /* origin of actual frame */
80242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
80342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    cur = video->currYMB; /* use smaller memory space for current MB */
80442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
80542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /*  find limit of the search (adjusting search range)*/
80642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
80742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (!h263_mode)
80842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
80942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ilow = i0 - range;
81042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (ilow < -15)
81142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ilow = -15;
81242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ihigh = i0 + range - 1;
81342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (ihigh > width - 1)
81442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ihigh = width - 1;
81542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        jlow = j0 - range;
81642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (jlow < -15)
81742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jlow = -15;
81842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        jhigh = j0 + range - 1;
81942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (jhigh > height - 1)
82042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jhigh = height - 1;
82142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
82242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
82342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
82442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ilow = i0 - range;
82542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (ilow < 0)
82642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ilow = 0;
82742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ihigh = i0 + range - 1;
82842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (ihigh > width - 16)
82942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ihigh = width - 16;
83042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        jlow = j0 - range;
83142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (jlow < 0)
83242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jlow = 0;
83342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        jhigh = j0 + range - 1;
83442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (jhigh > height - 16)
83542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jhigh = height - 16;
83642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
83742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
83842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    imin = i0;
83942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    jmin = j0; /* needed for fullsearch */
84042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    ncand = ref + imin + jmin * lx;
84142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
84242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* for first row of MB, fullsearch can be used */
84342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (FS_en)
84442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
84542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *hp_guess = 0; /* no guess for fast half-pel */
84642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
84742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        dmin =  fullsearch(video, currVol, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh);
84842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
84942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ncand = ref + imin + jmin * lx;
85042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
85142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][0].sad = dmin;
85242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][0].x = (imin - i0) << 1;
85342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][0].y = (jmin - j0) << 1;
85442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        imin0 = imin << 1;  /* 16x16 MV in half-pel resolution */
85542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        jmin0 = jmin << 1;
85642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        best_cand[0] = ncand;
85742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
85842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
85942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {   /* 4/7/01, modified this testing for fullsearch the top row to only upto (0,3) MB */
86042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        /*            upto 30% complexity saving with the same complexity */
86142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (video->forwardRefVop->predictionType == I_VOP && j0 == 0 && i0 <= 64 && type_pred != 1)
86242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
86342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            *hp_guess = 0; /* no guess for fast half-pel */
86442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dmin =  fullsearch(video, currVol, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh);
86542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ncand = ref + imin + jmin * lx;
86642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
86742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else
86842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
86942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /************** initialize candidate **************************/
87042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* find initial motion vector */
87142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            CandidateSelection(mvx, mvy, &num_can, i0 >> 4, j0 >> 4, video, type_pred);
87242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
87342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dmin = 65535;
87442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
87542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* check if all are equal */
87642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (num_can == ALL_CAND_EQUAL)
87742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
87842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                i = i0 + mvx[0];
87942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                j = j0 + mvy[0];
88042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
88142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
88242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
88342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    cand = ref + i + j * lx;
88442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
88542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
88642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
88742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (d < dmin)
88842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
88942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        dmin = d;
89042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        imin = i;
89142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        jmin = j;
89242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        ncand = cand;
89342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
89442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
89542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
89642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else
89742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
89842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /************** evaluate unique candidates **********************/
89942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                for (k = 0; k < num_can; k++)
90042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
90142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    i = i0 + mvx[k];
90242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    j = j0 + mvy[k];
90342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
90442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
90542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
90642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        cand = ref + i + j * lx;
90742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
90842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
90942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (d < dmin)
91042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
91142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            dmin = d;
91242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            imin = i;
91342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            jmin = j;
91442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            ncand = cand;
91542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
91642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        else if ((d == dmin) && PV_ABS(mvx[k]) + PV_ABS(mvy[k]) < PV_ABS(i0 - imin) + PV_ABS(j0 - jmin))
91742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
91842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            dmin = d;
91942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            imin = i;
92042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            jmin = j;
92142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            ncand = cand;
92242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
92342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
92442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
92542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
92642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (num_can == 0 || dmin == 65535) /* no candidate selected */
92742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
92842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                ncand = ref + i0 + j0 * lx; /* use (0,0) MV as initial value */
92942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot[mbnum][7].sad = dmin = (*SAD_Macroblock)(ncand, cur, (65535 << 16) | lx, extra_info);
93042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#if (ZERO_MV_PREF==1)   /* compute (0,0) MV at the end */
93142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                d0 = dmin;
93242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
93342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                imin = i0;
93442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                jmin = j0;
93542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
93642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
93742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#if (ZERO_MV_PREF==0)  /*  COMPUTE ZERO VECTOR FIRST !!!!!*/
93842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dmin -= PREF_NULL_VEC;
93942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
94042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
94142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /******************* local refinement ***************************/
94242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            center_again = 0;
94342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            last_loc = new_loc = 0;
94442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            //          ncand = ref + jmin*lx + imin;  /* center of the search */
94542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            step = 0;
94642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[0] = dmin;
94742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            while (!center_again && step <= max_step)
94842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
94942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
95042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                MoveNeighborSAD(dn, last_loc);
95142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
95242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                center_again = 1;
95342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                i = imin;
95442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                j = jmin - 1;
95542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand = ref + i + j * lx;
95642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
95742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /*  starting from [0,-1] */
95842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* spiral check one step at a time*/
95942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                for (k = 2; k <= 8; k += 2)
96042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
96142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (!tab_exclude[last_loc][k]) /* exclude last step computation */
96242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {       /* not already computed */
96342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
96442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
96542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
96642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            dn[k] = d; /* keep it for half pel use */
96742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
96842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            if (d < dmin)
96942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            {
97042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                ncand = cand;
97142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                dmin = d;
97242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                imin = i;
97342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                jmin = j;
97442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                center_again = 0;
97542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                new_loc = k;
97642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            }
97742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            else if ((d == dmin) && PV_ABS(i0 - i) + PV_ABS(j0 - j) < PV_ABS(i0 - imin) + PV_ABS(j0 - jmin))
97842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            {
97942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                ncand = cand;
98042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                imin = i;
98142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                jmin = j;
98242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                center_again = 0;
98342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                new_loc = k;
98442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            }
98542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
98642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
98742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    if (k == 8)  /* end side search*/
98842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
98942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (!center_again)
99042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
99142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            k = -1; /* start diagonal search */
99242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            cand -= lx;
99342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            j--;
99442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
99542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
99642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    else
99742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
99842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        next = refine_next[k][0];
99942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        i += next;
100042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        cand += next;
100142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        next = refine_next[k][1];
100242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        j += next;
100342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        cand += lx * next;
100442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
100542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
100642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                last_loc = new_loc;
100742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                step ++;
100842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
100942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (!center_again)
101042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                MoveNeighborSAD(dn, last_loc);
101142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
101242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            *hp_guess = FindMin(dn);
101342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
101442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
101542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
101642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#if (ZERO_MV_PREF==1)   /* compute (0,0) MV at the end */
101742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (d0 - PREF_NULL_VEC < dmin)
101842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
101942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ncand = ref + i0 + j0 * lx;
102042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dmin = d0;
102142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            imin = i0;
102242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jmin = j0;
102342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
102442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
102542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][0].sad = dmin;
102642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][0].x = (imin - i0) << 1;
102742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][0].y = (jmin - j0) << 1;
102842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        imin0 = imin << 1;  /* 16x16 MV in half-pel resolution */
102942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        jmin0 = jmin << 1;
103042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        best_cand[0] = ncand;
103142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
103242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* imin and jmin is the best 1 MV */
103342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_INTER4V
103442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /*******************  Find 4 motion vectors ****************************/
103542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (use_4mv && !h263_mode)
103642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
103742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef _SAD_STAT
103842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        num_Blk += 4;
103942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
104042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        /* starting from the best 1MV */
104142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        //offset = imin + jmin*lx;
104242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        iorg = i0;
104342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        jorg = j0;
104442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
104542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (comp = 0; comp < 4; comp++)
104642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
104742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            i0 = iorg + ((comp & 1) << 3);
104842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            j0 = jorg + ((comp & 2) << 2);
104942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
105042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            imin = (imin0 >> 1) + ((comp & 1) << 3);    /* starting point from 16x16 MV */
105142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jmin = (jmin0 >> 1) + ((comp & 2) << 2);
105242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ncand = ref + imin + jmin * lx;
105342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
105442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            cur8 = cur + ((comp & 1) << 3) + (((comp & 2) << 2) << 4) ; /* 11/30/05, smaller cache */
105542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
105642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /*  find limit of the search (adjusting search range)*/
105742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ilow = i0 - range;
105842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            ihigh = i0 + range - 1 ;/* 4/9/01 */
105942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (ilow < -15)
106042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                ilow = -15;
106142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (ihigh > width - 1)
106242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                ihigh = width - 1;
106342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jlow = j0 - range;
106442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            jhigh = j0 + range - 1 ;/* 4/9/01 */
106542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jlow < -15)
106642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                jlow = -15;
106742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jhigh > height - 1)
106842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                jhigh = height - 1;
106942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
107042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            SAD_Block = video->functionPointer->SAD_Block;
107142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
107242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (FS_en)  /* fullsearch enable, center around 16x16 MV */
107342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
107442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                dmin =  fullsearchBlk(video, currVol, ncand, cur8, &imin, &jmin, ilow, ihigh, jlow, jhigh, range);
107542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                ncand = ref + imin + jmin * lx;
107642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
107742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot[mbnum][comp+1].sad = dmin;
107842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot[mbnum][comp+1].x = (imin - i0) << 1;
107942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot[mbnum][comp+1].y = (jmin - j0) << 1;
108042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                best_cand[comp+1] = ncand;
108142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
108242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else    /* no fullsearch, do local search */
108342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
108442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /* starting point from 16x16 */
108542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                dmin = (*SAD_Block)(ncand, cur8, 65536, lx, extra_info);
108642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
108742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                /******************* local refinement ***************************/
108842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                center_again = 0;
108942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                last_loc = 0;
109042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
109142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                while (!center_again)
109242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
109342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    center_again = 1;
109442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    i = imin;
109542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    j = jmin - 1;
109642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    cand = ref + i + j * lx;
109742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
109842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /*  starting from [0,-1] */
109942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    /* spiral check one step at a time*/
110042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    for (k = 2; k <= 8; k += 2)
110142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    {
110242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (!tab_exclude[last_loc][k]) /* exclude last step computation */
110342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {       /* not already computed */
110442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
110542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            {
110642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                d = (*SAD_Block)(cand, cur8, dmin, lx, extra_info);
110742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
110842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                if (d < dmin)
110942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                {
111042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    ncand = cand;
111142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    dmin = d;
111242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    imin = i;
111342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    jmin = j;
111442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    center_again = 0;
111542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    new_loc = k;
111642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                }
111742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                else if ((d == dmin) &&
111842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                         PV_ABS(i0 - i) + PV_ABS(j0 - j) < PV_ABS(i0 - imin) + PV_ABS(j0 - jmin))
111942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                {
112042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    ncand = cand;
112142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    imin = i;
112242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    jmin = j;
112342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    center_again = 0;
112442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                    new_loc = k;
112542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                }
112642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            }
112742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
112842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        if (k == 8)  /* end side search*/
112942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
113042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            if (!center_again)
113142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            {
113242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                k = -1; /* start diagonal search */
113342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                if (j <= height - 1 && j > 0)   cand -= lx;
113442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                                j--;
113542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            }
113642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
113742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        else
113842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        {
113942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            next = refine_next[k][0];
114042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            cand += next;
114142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            i += next;
114242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            next = refine_next[k][1];
114342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            cand += lx * next;
114442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            j += next;
114542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        }
114642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    }
114742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    last_loc = new_loc;
114842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
114942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot[mbnum][comp+1].sad = dmin;
115042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot[mbnum][comp+1].x = (imin - i0) << 1;
115142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mot[mbnum][comp+1].y = (jmin - j0) << 1;
115242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                best_cand[comp+1] = ncand;
115342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
115442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /********************************************/
115542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
115642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
115742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else
115842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif  /* NO_INTER4V */
115942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
116042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][1].sad = mot[mbnum][2].sad = mot[mbnum][3].sad = mot[mbnum][4].sad = (dmin + 2) >> 2;
116142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][1].x = mot[mbnum][2].x = mot[mbnum][3].x = mot[mbnum][4].x = mot[mbnum][0].x;
116242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        mot[mbnum][1].y = mot[mbnum][2].y = mot[mbnum][3].y = mot[mbnum][4].y = mot[mbnum][0].y;
116342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        best_cand[1] = best_cand[2] = best_cand[3] = best_cand[4] = ncand;
116442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
116542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
116642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
116742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
116842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
116942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
117042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*===============================================================================
117142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   fullsearch
117242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       09/16/2000
117342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Perform full-search motion estimation over the range of search
117442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                region in a spiral-outward manner.
117542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Input/Output:   VideoEncData, current Vol, previou Vop, pointer to the left corner of
117642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                current VOP, current coord (also output), boundaries.
117742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong===============================================================================*/
117842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
117942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongInt fullsearch(VideoEncData *video, Vol *currVol, UChar *prev, UChar *cur,
118042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong               Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh)
118142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
118242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int range = video->encParams->SearchRange;
118342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *cand;
118442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i, j, k, l;
118542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int d, dmin;
118642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i0 = *imin; /* current position */
118742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int j0 = *jmin;
118842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int(*SAD_Macroblock)(UChar*, UChar*, Int, void*) = video->functionPointer->SAD_Macroblock;
118942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void *extra_info = video->sad_extra_info;
119042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//  UChar h263_mode = video->encParams->H263_Enabled;
119142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx = video->currVop->pitch; /* with padding */
119242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
119342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int offset = i0 + j0 * lx;
119442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
119542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    OSCL_UNUSED_ARG(currVol);
119642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
119742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    cand = prev + offset;
119842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
119942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    dmin  = (*SAD_Macroblock)(cand, cur, (65535 << 16) | lx, (void*)extra_info) - PREF_NULL_VEC;
120042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
120142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* perform spiral search */
120242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (k = 1; k <= range; k++)
120342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
120442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
120542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        i = i0 - k;
120642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        j = j0 - k;
120742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
120842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        cand = prev + i + j * lx;
120942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
121042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (l = 0; l < 8*k; l++)
121142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
121242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* no need for boundary checking again */
121342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
121442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
121542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, (void*)extra_info);
121642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
121742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (d < dmin)
121842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
121942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    dmin = d;
122042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *imin = i;
122142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *jmin = j;
122242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
122342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else if ((d == dmin) && PV_ABS(i0 - i) + PV_ABS(j0 - j) < PV_ABS(i0 - *imin) + PV_ABS(j0 - *jmin))
122442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
122542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    dmin = d;
122642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *imin = i;
122742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *jmin = j;
122842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
122942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
123042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
123142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (l < (k << 1))
123242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
123342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                i++;
123442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand++;
123542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
123642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else if (l < (k << 2))
123742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
123842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                j++;
123942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand += lx;
124042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
124142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else if (l < ((k << 2) + (k << 1)))
124242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
124342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                i--;
124442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand--;
124542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
124642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else
124742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
124842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                j--;
124942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand -= lx;
125042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
125142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
125242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
125342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
125442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return dmin;
125542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
125642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
125742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifndef NO_INTER4V
125842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*===============================================================================
125942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   fullsearchBlk
126042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       01/9/2001
126142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Perform full-search motion estimation of an 8x8 block over the range
126242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                of search region in a spiral-outward manner centered at the 16x16 MV.
126342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Input/Output:   VideoEncData, MB coordinate, pointer to the initial MV on the
126442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                reference, pointer to coor of current block, search range.
126542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong===============================================================================*/
126642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongInt fullsearchBlk(VideoEncData *video, Vol *currVol, UChar *cent, UChar *cur,
126742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                  Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh, Int range)
126842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
126942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    UChar *cand, *ref;
127042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i, j, k, l, istart, jstart;
127142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int d, dmin;
127242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int lx = video->currVop->pitch; /* with padding */
127342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int(*SAD_Block)(UChar*, UChar*, Int, Int, void*) = video->functionPointer->SAD_Block;
127442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    void *extra_info = video->sad_extra_info;
127542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
127642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    OSCL_UNUSED_ARG(currVol);
127742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
127842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* starting point centered at 16x16 MV */
127942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    ref = cent;
128042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    istart = *imin;
128142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    jstart = *jmin;
128242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
128342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    dmin = (*SAD_Block)(ref, cur, 65536, lx, (void*)extra_info);
128442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
128542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    cand = ref;
128642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* perform spiral search */
128742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (k = 1; k <= range; k++)
128842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
128942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
129042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        i = istart - k;
129142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        j = jstart - k;
129242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        cand -= (lx + 1);  /* candidate region */
129342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
129442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        for (l = 0; l < 8*k; l++)
129542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
129642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* no need for boundary checking again */
129742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
129842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
129942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                d = (*SAD_Block)(cand, cur, dmin, lx, (void*)extra_info);
130042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
130142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (d < dmin)
130242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
130342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    dmin = d;
130442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *imin = i;
130542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *jmin = j;
130642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
130742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                else if ((d == dmin) &&
130842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                         PV_ABS(istart - i) + PV_ABS(jstart - j) < PV_ABS(istart - *imin) + PV_ABS(jstart - *jmin))
130942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
131042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    dmin = d;
131142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *imin = i;
131242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    *jmin = j;
131342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
131442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
131542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
131642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (l < (k << 1))
131742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
131842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                i++;
131942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand++;
132042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
132142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else if (l < (k << 2))
132242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
132342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                j++;
132442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand += lx;
132542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
132642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else if (l < ((k << 2) + (k << 1)))
132742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
132842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                i--;
132942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand--;
133042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
133142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else
133242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
133342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                j--;
133442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                cand -= lx;
133542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
133642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
133742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
133842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
133942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return dmin;
134042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
134142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif /* NO_INTER4V */
134242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
134342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*===============================================================================
134442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   CandidateSelection
134542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       09/16/2000
134642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Fill up the list of candidate using spatio-temporal correlation
134742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                among neighboring blocks.
134842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Input/Output:   type_pred = 0: first pass, 1: second pass, or no SCD
134942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Modified:    09/23/01, get rid of redundant candidates before passing back.
135042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong===============================================================================*/
135142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
135242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid CandidateSelection(Int *mvx, Int *mvy, Int *num_can, Int imb, Int jmb,
135342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                        VideoEncData *video, Int type_pred)
135442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
135542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    MOT **mot = video->mot;
135642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    MOT *pmot;
135742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbnum = video->mbnum;
135842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Vol *currVol = video->vol[video->currLayer];
135942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbwidth = currVol->nMBPerRow;
136042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int mbheight = currVol->nMBPerCol;
136142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int i, j, same, num1;
136242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
136342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    *num_can = 0;
136442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
136542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (video->forwardRefVop->predictionType == P_VOP)
136642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
136742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        /* Spatio-Temporal Candidate (five candidates) */
136842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (type_pred == 0) /* first pass */
136942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
137042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            pmot = &mot[mbnum][0]; /* same coordinate previous frame */
137142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mvx[(*num_can)] = (pmot->x) >> 1;
137242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mvy[(*num_can)++] = (pmot->y) >> 1;
137342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb >= (mbwidth >> 1) && imb > 0)  /*left neighbor previous frame */
137442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
137542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-1][0];
137642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
137742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
137842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
137942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else if (imb + 1 < mbwidth)   /*right neighbor previous frame */
138042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
138142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum+1][0];
138242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
138342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
138442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
138542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
138642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb < mbheight - 1)  /*bottom neighbor previous frame */
138742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
138842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum+mbwidth][0];
138942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
139042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
139142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
139242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            else if (jmb > 0)   /*upper neighbor previous frame */
139342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
139442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth][0];
139542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
139642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
139742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
139842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
139942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb > 0 && jmb > 0)  /* upper-left neighbor current frame*/
140042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
140142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth-1][0];
140242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
140342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
140442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
140542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb > 0 && imb < mbheight - 1)  /* upper right neighbor current frame*/
140642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
140742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth+1][0];
140842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
140942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
141042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
141142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
141242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else    /* second pass */
141342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            /* original ST1 algorithm */
141442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
141542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            pmot = &mot[mbnum][0]; /* same coordinate previous frame */
141642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mvx[(*num_can)] = (pmot->x) >> 1;
141742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mvy[(*num_can)++] = (pmot->y) >> 1;
141842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
141942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb > 0)  /*left neighbor current frame */
142042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
142142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-1][0];
142242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
142342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
142442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
142542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb > 0)  /*upper neighbor current frame */
142642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
142742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth][0];
142842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
142942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
143042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
143142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb < mbwidth - 1)  /*right neighbor previous frame */
143242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
143342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum+1][0];
143442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
143542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
143642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
143742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb < mbheight - 1)  /*bottom neighbor previous frame */
143842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
143942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum+mbwidth][0];
144042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
144142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
144242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
144342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
144442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
144542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    else  /* only Spatial Candidate (four candidates)*/
144642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
144742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (type_pred == 0) /*first pass*/
144842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
144942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb > 1)  /* neighbor two blocks away to the left */
145042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
145142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-2][0];
145242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
145342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
145442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
145542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb > 0 && jmb > 0)  /* upper-left neighbor */
145642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
145742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth-1][0];
145842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
145942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
146042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
146142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb > 0 && imb < mbheight - 1)  /* upper right neighbor */
146242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
146342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth+1][0];
146442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
146542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
146642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
146742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
146842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//#ifdef SCENE_CHANGE_DETECTION
146942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        /* second pass (ST2 algorithm)*/
147042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else if (type_pred == 1) /* 4/7/01 */
147142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
147242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb > 0)  /*left neighbor current frame */
147342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
147442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-1][0];
147542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
147642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
147742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
147842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb > 0)  /*upper neighbor current frame */
147942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
148042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth][0];
148142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
148242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
148342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
148442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb < mbwidth - 1)  /*right neighbor current frame */
148542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
148642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum+1][0];
148742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
148842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
148942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
149042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb < mbheight - 1)  /*bottom neighbor current frame */
149142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
149242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum+mbwidth][0];
149342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
149442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
149542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
149642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
149742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//#else
149842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        else /* original ST1 algorithm */
149942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
150042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (imb > 0)  /*left neighbor current frame */
150142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
150242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-1][0];
150342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
150442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
150542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
150642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (jmb > 0)  /*upper-left neighbor current frame */
150742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
150842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    pmot = &mot[mbnum-mbwidth-1][0];
150942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    mvx[(*num_can)] = (pmot->x) >> 1;
151042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    mvy[(*num_can)++] = (pmot->y) >> 1;
151142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
151242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
151342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
151442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (jmb > 0)  /*upper neighbor current frame */
151542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            {
151642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                pmot = &mot[mbnum-mbwidth][0];
151742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvx[(*num_can)] = (pmot->x) >> 1;
151842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
151942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
152042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                if (imb < mbheight - 1)  /*upper-right neighbor current frame */
152142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                {
152242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    pmot = &mot[mbnum-mbwidth+1][0];
152342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    mvx[(*num_can)] = (pmot->x) >> 1;
152442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                    mvy[(*num_can)++] = (pmot->y) >> 1;
152542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                }
152642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            }
152742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
152842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong//#endif
152942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
153042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
153142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* 3/23/01, remove redundant candidate (possible k-mean) */
153242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    num1 = *num_can;
153342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    *num_can = 1;
153442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (i = 1; i < num1; i++)
153542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
153642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        same = 0;
153742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        j = 0;
153842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        while (!same && j < *num_can)
153942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
154042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#if (CANDIDATE_DISTANCE==0)
154142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (mvx[i] == mvx[j] && mvy[i] == mvy[j])
154242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#else
154342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            // modified k-mean, 3/24/01, shouldn't be greater than 3
154442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            if (PV_ABS(mvx[i] - mvx[j]) + PV_ABS(mvy[i] - mvy[j]) < CANDIDATE_DISTANCE)
154542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
154642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                same = 1;
154742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            j++;
154842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
154942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (!same)
155042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
155142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mvx[*num_can] = mvx[i];
155242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            mvy[*num_can] = mvy[i];
155342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            (*num_can)++;
155442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
155542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
155642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
155742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#ifdef _SAD_STAT
155842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    num_cand += (*num_can);
155942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong#endif
156042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
156142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (num1 == 5 && *num_can == 1)
156242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        *num_can = ALL_CAND_EQUAL; /* all are equal */
156342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
156442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
156542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
156642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
156742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*===========================================================================
156842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   RasterIntraUpdate
156942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       2/26/01
157042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    To raster-scan assign INTRA-update .
157142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                N macroblocks are updated (also was programmable).
157242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong===========================================================================*/
157342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid RasterIntraUpdate(UChar *intraArray, UChar *Mode, Int totalMB, Int numRefresh)
157442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
157542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int indx, i;
157642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
157742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* find the last refresh MB */
157842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    indx = 0;
157942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    while (intraArray[indx] == 1 && indx < totalMB)
158042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        indx++;
158142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
158242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* add more  */
158342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (i = 0; i < numRefresh && indx < totalMB; i++)
158442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
158542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        Mode[indx] = MODE_INTRA;
158642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        intraArray[indx++] = 1;
158742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
158842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
158942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    /* if read the end of frame, reset and loop around */
159042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (indx >= totalMB - 1)
159142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
159242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        ResetIntraUpdate(intraArray, totalMB);
159342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        indx = 0;
159442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        while (i < numRefresh && indx < totalMB)
159542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
159642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            intraArray[indx] = 1;
159742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            Mode[indx++] = MODE_INTRA;
159842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            i++;
159942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
160042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
160142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
160242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
160342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
160442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
160542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*===========================================================================
160642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   ResetIntraUpdate
160742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       11/28/00
160842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Reset already intra updated flags to all zero
160942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong===========================================================================*/
161042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
161142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid ResetIntraUpdate(UChar *intraArray, Int totalMB)
161242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
161342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    M4VENC_MEMSET(intraArray, 0, sizeof(UChar)*totalMB);
161442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
161542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
161642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
161742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*===========================================================================
161842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   ResetIntraUpdateRegion
161942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       12/1/00
162042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Reset already intra updated flags in one region to all zero
162142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong===========================================================================*/
162242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid ResetIntraUpdateRegion(UChar *intraArray, Int start_i, Int rwidth,
162342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong                            Int start_j, Int rheight, Int mbwidth, Int mbheight)
162442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
162542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int indx, j;
162642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
162742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (start_i + rwidth >= mbwidth)
162842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        rwidth = mbwidth - start_i;
162942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    if (start_j + rheight >= mbheight)
163042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        rheight = mbheight - start_j;
163142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
163242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (j = start_j; j < start_j + rheight; j++)
163342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
163442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        indx = j * mbwidth;
163542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        M4VENC_MEMSET(intraArray + indx + start_i, 0, sizeof(UChar)*rwidth);
163642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
163742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
163842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
163942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
164042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
164142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/*************************************************************
164242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Function:   MoveNeighborSAD
164342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Date:       3/27/01
164442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Purpose:    Move neighboring SAD around when center has shifted
164542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong*************************************************************/
164642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
164742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dongvoid MoveNeighborSAD(Int dn[], Int new_loc)
164842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
164942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int tmp[9];
165042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[0] = dn[0];
165142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[1] = dn[1];
165242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[2] = dn[2];
165342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[3] = dn[3];
165442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[4] = dn[4];
165542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[5] = dn[5];
165642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[6] = dn[6];
165742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[7] = dn[7];
165842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    tmp[8] = dn[8];
165942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    dn[0] = dn[1] = dn[2] = dn[3] = dn[4] = dn[5] = dn[6] = dn[7] = dn[8] = 65536;
166042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
166142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    switch (new_loc)
166242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
166342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 0:
166442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
166542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 1:
166642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[4] = tmp[2];
166742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[5] = tmp[0];
166842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[6] = tmp[8];
166942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
167042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 2:
167142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[4] = tmp[3];
167242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[5] = tmp[4];
167342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[6] = tmp[0];
167442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[7] = tmp[8];
167542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[8] = tmp[1];
167642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
167742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 3:
167842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[6] = tmp[4];
167942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[7] = tmp[0];
168042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[8] = tmp[2];
168142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
168242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 4:
168342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[1] = tmp[2];
168442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[2] = tmp[3];
168542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[6] = tmp[5];
168642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[7] = tmp[6];
168742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[8] = tmp[0];
168842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
168942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 5:
169042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[1] = tmp[0];
169142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[2] = tmp[4];
169242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[8] = tmp[6];
169342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
169442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 6:
169542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[1] = tmp[8];
169642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[2] = tmp[0];
169742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[3] = tmp[4];
169842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[4] = tmp[5];
169942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[8] = tmp[7];
170042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
170142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 7:
170242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[2] = tmp[8];
170342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[3] = tmp[0];
170442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[4] = tmp[6];
170542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
170642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        case 8:
170742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[2] = tmp[1];
170842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[3] = tmp[2];
170942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[4] = tmp[0];
171042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[5] = tmp[6];
171142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dn[6] = tmp[7];
171242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            break;
171342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
171442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    dn[0] = tmp[new_loc];
171542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
171642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return ;
171742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
171842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
171942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong/* 3/28/01, find minimal of dn[9] */
172042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
172142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames DongInt FindMin(Int dn[])
172242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong{
172342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int min, i;
172442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    Int dmin;
172542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
172642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    dmin = dn[1];
172742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    min = 1;
172842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    for (i = 2; i < 9; i++)
172942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    {
173042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        if (dn[i] < dmin)
173142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        {
173242ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            dmin = dn[i];
173342ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong            min = i;
173442ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong        }
173542ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    }
173642ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
173742ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong    return min;
173842ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong}
173942ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
174042ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
174142ef0c715da879a9878b7bf4eb9c90b21e4ab8aeJames Dong
1742