159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ------------------------------------------------------------------
259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Copyright (C) 1998-2009 PacketVideo
359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Licensed under the Apache License, Version 2.0 (the "License");
559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * you may not use this file except in compliance with the License.
659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * You may obtain a copy of the License at
759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *      http://www.apache.org/licenses/LICENSE-2.0
959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
1059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Unless required by applicable law or agreed to in writing, software
1159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * express or implied.
1459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * See the License for the specific language governing permissions
1559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * and limitations under the License.
1659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * -------------------------------------------------------------------
1759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong */
1859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4def.h"
1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4enc_lib.h"
2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4lib_int.h"
2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h"
2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//#define PRINT_MV
2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define MIN_GOP 1   /* minimum size of GOP,  1/23/01, need to be tested */
2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define CANDIDATE_DISTANCE  0 /* distance candidate from one another to consider as a distinct one */
2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* shouldn't be more than 3 */
2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define ZERO_MV_PREF    0 /* 0: bias (0,0)MV before full-pel search, lowest complexity*/
3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 1: bias (0,0)MV after full-pel search, before half-pel, highest comp */
3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 2: bias (0,0)MV after half-pel, high comp, better PSNR */
3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define RASTER_REFRESH  /* instead of random INTRA refresh, do raster scan,  2/26/01 */
3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef RASTER_REFRESH
3659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define TARGET_REFRESH_PER_REGION 4 /* , no. MB per frame to be INTRA refreshed */
3759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define TARGET_REFRESH_PER_REGION 1 /* , no. MB per region to be INTRA refreshed */
3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define ALL_CAND_EQUAL  10  /*  any number greater than 5 will work */
4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define NumPixelMB  256     /*  number of pixels used in SAD calculation */
4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define DEF_8X8_WIN 3   /* search region for 8x8 MVs around the 16x16 MV */
4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define MB_Nb  256
4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define PREF_NULL_VEC 129   /* for zero vector bias */
4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define PREF_16_VEC 129     /* 1MV bias versus 4MVs*/
5059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define PREF_INTRA  512     /* bias for INTRA coding */
5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int tab_exclude[9][9] =  // [last_loc][curr_loc]
5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 0, 0, 0, 0, 0, 0, 0, 0},
5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 0, 0, 0, 1, 1, 1, 0, 0},
5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 0, 0, 0, 1, 1, 1, 1, 1},
5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 0, 0, 0, 0, 0, 1, 1, 1},
5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 1, 1, 0, 0, 0, 1, 1, 1},
5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 1, 1, 0, 0, 0, 0, 0, 1},
6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 1, 1, 1, 1, 0, 0, 0, 1},
6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 0, 1, 1, 1, 0, 0, 0, 0},
6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 0, 1, 1, 1, 1, 1, 0, 0}
6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}; //to decide whether to continue or compute
6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int refine_next[8][2] =    /* [curr_k][increment] */
6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 0}, {2, 0}, {1, 1}, {0, 2}, { -1, 1}, { -2, 0}, { -1, -1}, {0, -2}
6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef __cplusplus
7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dongextern "C"
7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void MBMotionSearch(VideoEncData *video, UChar *cur, UChar *best_cand[],
7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i0, Int j0, Int type_pred, Int fullsearch, Int *hp_guess);
7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int  fullsearch(VideoEncData *video, Vol *currVol, UChar *ref, UChar *cur,
7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh);
8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int fullsearchBlk(VideoEncData *video, Vol *currVol, UChar *cent, UChar *cur,
8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                      Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh, Int range);
8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void CandidateSelection(Int *mvx, Int *mvy, Int *num_can, Int imb, Int jmb,
8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            VideoEncData *video, Int type_pred);
8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void RasterIntraUpdate(UChar *intraArray, UChar *Mode, Int totalMB, Int numRefresh);
8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void ResetIntraUpdate(UChar *intraArray, Int totalMB);
8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void ResetIntraUpdateRegion(UChar *intraArray, Int start_i, Int rwidth,
8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                Int start_j, Int rheight, Int mbwidth, Int mbheight);
8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void MoveNeighborSAD(Int dn[], Int new_loc);
9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int FindMin(Int dn[]);
9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void PrepareCurMB(VideoEncData *video, UChar *cur);
9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef __cplusplus
9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/***************************************/
9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  2/28/01, for HYPOTHESIS TESTING */
9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef HTFM     /* defined in mp4def.h */
10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef __cplusplus
10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dongextern "C"
10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void CalcThreshold(double pf, double exp_lamda[], Int nrmlz_th[]);
10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void    HTFMPrepareCurMB(VideoEncData *video, HTFM_Stat *htfm_stat, UChar *cur);
10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef __cplusplus
10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define HTFM_Pf  0.25   /* 3/2/1, probability of false alarm, can be varied from 0 to 0.5 */
11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/***************************************/
11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _SAD_STAT
11659f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong num_MB = 0;
11759f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong num_HP_MB = 0;
11859f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong num_Blk = 0;
11959f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong num_HP_Blk = 0;
12059f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong num_cand = 0;
12159f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong num_better_hp = 0;
12259f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong i_dist_from_guess = 0;
12359f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong j_dist_from_guess = 0;
12459f566c4ec3dfc097ad8163523e522280b27e5c3James DongULong num_hp_not_zero = 0;
12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*==================================================================
13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   MotionEstimation
13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       10/3/2000
13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Go through all macroblock for motion search and
13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                determine scene change detection.
13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong====================================================================*/
13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid MotionEstimation(VideoEncData *video)
13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar use_4mv = video->encParams->MV8x8_Enabled;
13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *currVop = video->currVop;
14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncFrameIO *currFrame = video->input;
14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, j, comp;
14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbwidth = currVol->nMBPerRow;
14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbheight = currVol->nMBPerCol;
14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int totalMB = currVol->nTotalMB;
14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = currFrame->pitch;
14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *mode_mb, *Mode = video->headerInfo.Mode;
14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    MOT *mot_mb, **mot = video->mot;
14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *intraArray = video->intraArray;
15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int FS_en = video->encParams->FullSearch_Enabled;
15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*ComputeMBSum)(UChar *, Int, MOT *) = video->functionPointer->ComputeMBSum;
15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*ChooseMode)(UChar*, UChar*, Int, Int) = video->functionPointer->ChooseMode;
15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int numIntra, start_i, numLoop, incr_i;
15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbnum, offset;
15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *cur, *best_cand[5];
15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int sad8 = 0, sad16 = 0;
15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int totalSAD = 0;   /* average SAD for rate control */
15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int skip_halfpel_4mv;
16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int f_code_p, f_code_n, max_mag = 0, min_mag = 0;
16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int type_pred;
16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int xh[5] = {0, 0, 0, 0, 0};
16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int yh[5] = {0, 0, 0, 0, 0}; /* half-pel */
16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar hp_mem4MV[17*17*4];
16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef HTFM
16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***** HYPOTHESIS TESTING ********/  /* 2/28/01 */
16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int collect = 0;
16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    HTFM_Stat htfm_stat;
17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    double newvar[16];
17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    double exp_lamda[15];
17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*********************************/
17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int hp_guess = 0;
17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    FILE *fp_debug;
17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  FILE *fstat;
18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  static int frame_num = 0;
18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset = 0;
18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currVop->predictionType == I_VOP)
18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {   /* compute the SAV */
18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mbnum = 0;
18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur = currFrame->yChan;
18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (j = 0; j < mbheight; j++)
19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (i = 0; i < mbwidth; i++)
19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->mbnum = mbnum;
19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot_mb = mot[mbnum];
19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                (*ComputeMBSum)(cur + (i << 4), width, mot_mb);
19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                totalSAD += mot_mb[0].sad;
19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mbnum++;
20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            cur += (width << 4);
20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->sumMAD = (float)totalSAD / (float)NumPixelMB;
20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ResetIntraUpdate(intraArray, totalMB);
20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        return  ;
21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 09/20/05 */
21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->prevBaseVop->padded == 0 && !video->encParams->H263_Enabled)
21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        PaddingEdge(video->prevBaseVop);
21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->prevBaseVop->padded = 1;
21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Random INTRA update */
22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*  suggest to do it in CodeMB */
22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*  2/21/2001 */
22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //if(video->encParams->RC_Type == CBR_1 || video->encParams->RC_Type == CBR_2)
22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->currLayer == 0 && video->encParams->Refresh)
22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        RasterIntraUpdate(intraArray, Mode, totalMB, video->encParams->Refresh);
22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->sad_extra_info = NULL;
22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef HTFM
23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***** HYPOTHESIS TESTING ********/  /* 2/28/01 */
23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    InitHTFM(video, &htfm_stat, newvar, &collect);
23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*********************************/
23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if ((video->encParams->SceneChange_Det == 1) /*&& video->currLayer==0 */
23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            && ((video->encParams->LayerFrameRate[0] < 5.0) || (video->numVopsInGOP > MIN_GOP)))
23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* do not try to detect a new scene if low frame rate and too close to previous I-frame */
23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        incr_i = 2;
24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        numLoop = 2;
24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        start_i = 1;
24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        type_pred = 0; /* for initial candidate selection */
24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        incr_i = 1;
24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        numLoop = 1;
24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        start_i = 0;
25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        type_pred = 2;
25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* First pass, loop thru half the macroblock */
25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* determine scene change */
25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* Second pass, for the rest of macroblocks */
25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    numIntra = 0;
25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    while (numLoop--)
25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (j = 0; j < mbheight; j++)
26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (incr_i > 1)
26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                start_i = (start_i == 0 ? 1 : 0) ; /* toggle 0 and 1 */
26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            offset = width * (j << 4) + (start_i << 4);
26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mbnum = j * mbwidth + start_i;
26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (i = start_i; i < mbwidth; i += incr_i)
26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->mbnum = mbnum;
27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot_mb = mot[mbnum];
27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mode_mb = Mode + mbnum;
27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cur = currFrame->yChan + offset;
27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (*mode_mb != MODE_INTRA)
27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
27959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if defined(HTFM)
28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    HTFMPrepareCurMB(video, &htfm_stat, cur);
28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    PrepareCurMB(video, cur);
28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /************************************************************/
28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /******** full-pel 1MV and 4MVs search **********************/
28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _SAD_STAT
28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    num_MB++;
28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    MBMotionSearch(video, cur, best_cand, i << 4, j << 4, type_pred,
29159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                   FS_en, &hp_guess);
29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fprintf(fp_debug, "#%d (%d,%d,%d) : ", mbnum, mot_mb[0].x, mot_mb[0].y, mot_mb[0].sad);
29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fprintf(fp_debug, "(%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) : ==>\n",
29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            mot_mb[1].x, mot_mb[1].y, mot_mb[1].sad,
29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            mot_mb[2].x, mot_mb[2].y, mot_mb[2].sad,
29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            mot_mb[3].x, mot_mb[3].y, mot_mb[3].sad,
30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            mot_mb[4].x, mot_mb[4].y, mot_mb[4].sad);
30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fclose(fp_debug);
30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad16 = mot_mb[0].sad;
30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef NO_INTER4V
30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad8 = sad16;
30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad8 = mot_mb[1].sad + mot_mb[2].sad + mot_mb[3].sad + mot_mb[4].sad;
30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* choose between INTRA or INTER */
31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    (*ChooseMode)(mode_mb, cur, width, ((sad8 < sad16) ? sad8 : sad16));
31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else    /* INTRA update, use for prediction 3/23/01 */
31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    mot_mb[0].x = mot_mb[0].y = 0;
31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (*mode_mb == MODE_INTRA)
31959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    numIntra++ ;
32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* compute SAV for rate control and fast DCT, 11/28/00 */
32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    (*ComputeMBSum)(cur, width, mot_mb);
32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* leave mot_mb[0] as it is for fast motion search */
32659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* set the 4 MVs to zeros */
32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (comp = 1; comp <= 4; comp++)
32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb[comp].x = 0;
33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb[comp].y = 0;
33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fprintf(fp_debug, "\n");
33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fclose(fp_debug);
33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else /* *mode_mb = MODE_INTER;*/
33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (video->encParams->HalfPel_Enabled)
34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _SAD_STAT
34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        num_HP_MB++;
34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        /* find half-pel resolution motion vector */
34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        FindHalfPelMB(video, cur, mot_mb, best_cand[0],
34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                      i << 4, j << 4, xh, yh, hp_guess);
34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        fprintf(fp_debug, "(%d,%d), %d\n", mot_mb[0].x, mot_mb[0].y, mot_mb[0].sad);
35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        fclose(fp_debug);
35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        skip_halfpel_4mv = ((sad16 - mot_mb[0].sad) <= (MB_Nb >> 1) + 1);
35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        sad16 = mot_mb[0].sad;
35559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_INTER4V
35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (use_4mv && !skip_halfpel_4mv)
35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            /* Also decide 1MV or 4MV !!!!!!!!*/
36059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            sad8 = FindHalfPelBlk(video, cur, mot_mb, sad16,
36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                                  best_cand, mode_mb, i << 4, j << 4, xh, yh, hp_mem4MV);
36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            fprintf(fp_debug, " (%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) : (%d,%d,%d) \n",
36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    mot_mb[1].x, mot_mb[1].y, mot_mb[1].sad,
36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    mot_mb[2].x, mot_mb[2].y, mot_mb[2].sad,
36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    mot_mb[3].x, mot_mb[3].y, mot_mb[3].sad,
36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    mot_mb[4].x, mot_mb[4].y, mot_mb[4].sad);
37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            fclose(fp_debug);
37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* NO_INTER4V */
37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else    /* HalfPel_Enabled ==0  */
37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_INTER4V
37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        //if(sad16 < sad8-PREF_16_VEC)
37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (sad16 - PREF_16_VEC > sad8)
38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            *mode_mb = MODE_INTER4V;
38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
38359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (ZERO_MV_PREF==2)   /* use mot_mb[7].sad as d0 computed in MBMotionSearch*/
38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /******************************************************/
38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (mot_mb[7].sad - PREF_NULL_VEC < sad16 && mot_mb[7].sad - PREF_NULL_VEC < sad8)
38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb[0].sad = mot_mb[7].sad - PREF_NULL_VEC;
39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb[0].x = mot_mb[0].y = 0;
39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        *mode_mb = MODE_INTER;
39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /******************************************************/
39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (*mode_mb == MODE_INTER)
39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (mot_mb[0].x == 0 && mot_mb[0].y == 0)   /* use zero vector */
39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            mot_mb[0].sad += PREF_NULL_VEC; /* add back the bias */
39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
40059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb[1].sad = mot_mb[2].sad = mot_mb[3].sad = mot_mb[4].sad = (mot_mb[0].sad + 2) >> 2;
40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb[1].x = mot_mb[2].x = mot_mb[3].x = mot_mb[4].x = mot_mb[0].x;
40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb[1].y = mot_mb[2].y = mot_mb[3].y = mot_mb[4].y = mot_mb[0].y;
40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
40659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* find maximum magnitude */
40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* compute average SAD for rate control, 11/28/00 */
40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (*mode_mb == MODE_INTER)
41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fprintf(fp_debug, "%d MODE_INTER\n", mbnum);
41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fclose(fp_debug);
41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
41659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    totalSAD += mot_mb[0].sad;
41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (mot_mb[0].x > max_mag)
41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        max_mag = mot_mb[0].x;
41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (mot_mb[0].y > max_mag)
42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        max_mag = mot_mb[0].y;
42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (mot_mb[0].x < min_mag)
42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        min_mag = mot_mb[0].x;
42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (mot_mb[0].y < min_mag)
42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        min_mag = mot_mb[0].y;
42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else if (*mode_mb == MODE_INTER4V)
42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fprintf(fp_debug, "%d MODE_INTER4V\n", mbnum);
43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fclose(fp_debug);
43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    totalSAD += sad8;
43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (comp = 1; comp <= 4; comp++)
43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (mot_mb[comp].x > max_mag)
43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            max_mag = mot_mb[comp].x;
43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (mot_mb[comp].y > max_mag)
43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            max_mag = mot_mb[comp].y;
44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (mot_mb[comp].x < min_mag)
44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            min_mag = mot_mb[comp].x;
44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (mot_mb[comp].y < min_mag)
44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            min_mag = mot_mb[comp].y;
44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else    /* MODE_INTRA */
44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef PRINT_MV
44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fp_debug = fopen("c:\\bitstream\\mv1_debug.txt", "a");
45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fprintf(fp_debug, "%d MODE_INTRA\n", mbnum);
45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    fclose(fp_debug);
45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    totalSAD += mot_mb[0].sad;
45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mbnum += incr_i;
45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                offset += (incr_i << 4);
45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (incr_i > 1 && numLoop) /* scene change on and first loop */
46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            //if(numIntra > ((totalMB>>3)<<1) + (totalMB>>3)) /* 75% of 50%MBs */
46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (numIntra > (0.30*(totalMB / 2.0))) /* 15% of 50%MBs */
46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /******** scene change detected *******************/
46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                currVop->predictionType = I_VOP;
46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                M4VENC_MEMSET(Mode, MODE_INTRA, sizeof(UChar)*totalMB); /* set this for MB level coding*/
46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                currVop->quantizer = video->encParams->InitQuantIvop[video->currLayer];
47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* compute the SAV for rate control & fast DCT */
47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                totalSAD = 0;
47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                offset = 0;
47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mbnum = 0;
47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cur = currFrame->yChan;
47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (j = 0; j < mbheight; j++)
47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (i = 0; i < mbwidth; i++)
48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        video->mbnum = mbnum;
48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mot_mb = mot[mbnum];
48359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        (*ComputeMBSum)(cur + (i << 4), width, mot_mb);
48659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        totalSAD += mot_mb[0].sad;
48759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        mbnum++;
48959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
49059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    cur += (width << 4);
49159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
49259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
49359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                video->sumMAD = (float)totalSAD / (float)NumPixelMB;
49459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ResetIntraUpdate(intraArray, totalMB);
49559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* video->numVopsInGOP=0; 3/13/01 move it to vop.c*/
49659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
49759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                return ;
49859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
49959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
50059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /******** no scene change, continue motion search **********************/
50159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        start_i = 0;
50259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        type_pred++; /* second pass */
50359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
50459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
50559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->sumMAD = (float)totalSAD / (float)NumPixelMB;    /* avg SAD */
50659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
50759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* find f_code , 10/27/2000 */
50859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    f_code_p = 1;
50959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    while ((max_mag >> (4 + f_code_p)) > 0)
51059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        f_code_p++;
51159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    f_code_n = 1;
51359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    min_mag *= -1;
51459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    while ((min_mag - 1) >> (4 + f_code_n) > 0)
51559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        f_code_n++;
51659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    currVop->fcodeForward = (f_code_p > f_code_n ? f_code_p : f_code_n);
51859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef HTFM
52059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /***** HYPOTHESIS TESTING ********/  /* 2/28/01 */
52159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (collect)
52259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
52359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        collect = 0;
52459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        UpdateHTFM(video, newvar, exp_lamda, &htfm_stat);
52559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
52659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*********************************/
52759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
52859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
52959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
53059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
53159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
53259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
53359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef HTFM
53459f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid InitHTFM(VideoEncData *video, HTFM_Stat *htfm_stat, double *newvar, Int *collect)
53559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
53659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;
53759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = video->currVop->width; //  padding
53859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx2 = lx << 1;
53959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx3 = lx2 + lx;
54059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int rx = video->currVop->pitch;
54159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int rx2 = rx << 1;
54259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int rx3 = rx2 + rx;
54359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
54459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int *offset, *offset2;
54559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
54659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 4/11/01, collect data every 30 frames, doesn't have to be base layer */
54759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (((Int)video->numVopsInGOP) % 30 == 1)
54859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
54959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
55059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *collect = 1;
55159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
55259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        htfm_stat->countbreak = 0;
55359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        htfm_stat->abs_dif_mad_avg = 0;
55459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
55559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (i = 0; i < 16; i++)
55659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
55759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            newvar[i] = 0.0;
55859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
55959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//      video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM_Collect;
56059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_Macroblock = &SAD_MB_HTFM_Collect;
56159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[0] = NULL;
56259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFM_Collectxh;
56359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFM_Collectyh;
56459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFM_Collectxhyh;
56559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->sad_extra_info = (void*)(htfm_stat);
56659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset = htfm_stat->offsetArray;
56759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset2 = htfm_stat->offsetRef;
56859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
56959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
57059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
57159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//      video->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM;
57259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_Macroblock = &SAD_MB_HTFM;
57359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[0] = NULL;
57459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFMxh;
57559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFMyh;
57659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFMxhyh;
57759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->sad_extra_info = (void*)(video->nrmlz_th);
57859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset = video->nrmlz_th + 16;
57959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset2 = video->nrmlz_th + 32;
58059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
58159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
58259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[0] = 0;
58359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[1] = lx2 + 2;
58459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[2] = 2;
58559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[3] = lx2;
58659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[4] = lx + 1;
58759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[5] = lx3 + 3;
58859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[6] = lx + 3;
58959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[7] = lx3 + 1;
59059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[8] = lx;
59159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[9] = lx3 + 2;
59259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[10] = lx3 ;
59359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[11] = lx + 2 ;
59459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[12] = 1;
59559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[13] = lx2 + 3;
59659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[14] = lx2 + 1;
59759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset[15] = 3;
59859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
59959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[0] = 0;
60059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[1] = rx2 + 2;
60159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[2] = 2;
60259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[3] = rx2;
60359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[4] = rx + 1;
60459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[5] = rx3 + 3;
60559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[6] = rx + 3;
60659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[7] = rx3 + 1;
60759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[8] = rx;
60859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[9] = rx3 + 2;
60959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[10] = rx3 ;
61059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[11] = rx + 2 ;
61159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[12] = 1;
61259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[13] = rx2 + 3;
61359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[14] = rx2 + 1;
61459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    offset2[15] = 3;
61559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
61659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
61759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
61859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
61959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid UpdateHTFM(VideoEncData *video, double *newvar, double *exp_lamda, HTFM_Stat *htfm_stat)
62059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
62159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (htfm_stat->countbreak == 0)
62259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        htfm_stat->countbreak = 1;
62359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
62459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    newvar[0] = (double)(htfm_stat->abs_dif_mad_avg) / (htfm_stat->countbreak * 16.);
62559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
62659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (newvar[0] < 0.001)
62759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
62859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        newvar[0] = 0.001; /* to prevent floating overflow */
62959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
63059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[0] =  1 / (newvar[0] * 1.4142136);
63159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[1] = exp_lamda[0] * 1.5825;
63259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[2] = exp_lamda[0] * 2.1750;
63359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[3] = exp_lamda[0] * 3.5065;
63459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[4] = exp_lamda[0] * 3.1436;
63559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[5] = exp_lamda[0] * 3.5315;
63659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[6] = exp_lamda[0] * 3.7449;
63759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[7] = exp_lamda[0] * 4.5854;
63859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[8] = exp_lamda[0] * 4.6191;
63959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[9] = exp_lamda[0] * 5.4041;
64059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[10] = exp_lamda[0] * 6.5974;
64159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[11] = exp_lamda[0] * 10.5341;
64259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[12] = exp_lamda[0] * 10.0719;
64359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[13] = exp_lamda[0] * 12.0516;
64459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    exp_lamda[14] = exp_lamda[0] * 15.4552;
64559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
64659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    CalcThreshold(HTFM_Pf, exp_lamda, video->nrmlz_th);
64759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
64859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
64959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
65059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
65159f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid CalcThreshold(double pf, double exp_lamda[], Int nrmlz_th[])
65259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
65359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;
65459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    double temp[15];
65559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    //  printf("\nLamda: ");
65659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
65759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* parametric PREMODELling */
65859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < 15; i++)
65959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
66059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        //    printf("%g ",exp_lamda[i]);
66159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (pf < 0.5)
66259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            temp[i] = 1 / exp_lamda[i] * M4VENC_LOG(2 * pf);
66359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
66459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            temp[i] = -1 / exp_lamda[i] * M4VENC_LOG(2 * (1 - pf));
66559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
66659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
66759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    nrmlz_th[15] = 0;
66859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < 15; i++)        /* scale upto no.pixels */
66959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        nrmlz_th[i] = (Int)(temp[i] * ((i + 1) << 4) + 0.5);
67059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
67159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
67259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
67359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
67459f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid    HTFMPrepareCurMB(VideoEncData *video, HTFM_Stat *htfm_stat, UChar *cur)
67559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
67659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void* tmp = (void*)(video->currYMB);
67759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ULong *htfmMB = (ULong*)tmp;
67859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *ptr, byte;
67959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int *offset;
68059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;
68159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ULong word;
68259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = video->currVop->width;
68359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
68459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (((Int)video->numVopsInGOP) % 30 == 1)
68559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
68659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset = htfm_stat->offsetArray;
68759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
68859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
68959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
69059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        offset = video->nrmlz_th + 16;
69159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
69259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
69359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < 16; i++)
69459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
69559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ptr = cur + offset[i];
69659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word = ptr[0];
69759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[4];
69859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 8);
69959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[8];
70059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 16);
70159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[12];
70259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 24);
70359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *htfmMB++ = word;
70459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
70559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word = *(ptr += (width << 2));
70659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[4];
70759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 8);
70859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[8];
70959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 16);
71059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[12];
71159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 24);
71259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *htfmMB++ = word;
71359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
71459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word = *(ptr += (width << 2));
71559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[4];
71659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 8);
71759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[8];
71859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 16);
71959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[12];
72059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 24);
72159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *htfmMB++ = word;
72259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
72359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word = *(ptr += (width << 2));
72459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[4];
72559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 8);
72659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[8];
72759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 16);
72859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        byte = ptr[12];
72959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        word |= (byte << 24);
73059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *htfmMB++ = word;
73159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
73259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
73359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
73459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
73559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
73659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
73759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
73859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
73959f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid    PrepareCurMB(VideoEncData *video, UChar *cur)
74059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
74159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void* tmp = (void*)(video->currYMB);
74259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ULong *currYMB = (ULong*)tmp;
74359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i;
74459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = video->currVop->width;
74559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
74659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cur -= width;
74759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
74859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < 16; i++)
74959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
75059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *currYMB++ = *((ULong*)(cur += width));
75159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *currYMB++ = *((ULong*)(cur + 4));
75259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *currYMB++ = *((ULong*)(cur + 8));
75359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *currYMB++ = *((ULong*)(cur + 12));
75459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
75559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
75659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
75759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
75859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
75959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
76059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*==================================================================
76159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   MBMotionSearch
76259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       09/06/2000
76359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Perform motion estimation for a macroblock.
76459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                Find 1MV and 4MVs in half-pels resolutions.
76559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                Using ST1 algorithm provided by Chalidabhongse and Kuo
76659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                CSVT March'98.
76759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
76859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong==================================================================*/
76959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
77059f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid MBMotionSearch(VideoEncData *video, UChar *cur, UChar *best_cand[],
77159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    Int i0, Int j0, Int type_pred, Int FS_en, Int *hp_guess)
77259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
77359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
77459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *ref, *cand, *ncand = NULL, *cur8;
77559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void *extra_info = video->sad_extra_info;
77659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbnum = video->mbnum;
77759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = video->currVop->width; /* 6/12/01, must be multiple of 16 */
77859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int height = video->currVop->height;
77959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    MOT **mot = video->mot;
78059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar use_4mv = video->encParams->MV8x8_Enabled;
78159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar h263_mode = video->encParams->H263_Enabled;
78259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*SAD_Macroblock)(UChar*, UChar*, Int, void*) = video->functionPointer->SAD_Macroblock;
78359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*SAD_Block)(UChar*, UChar*, Int, Int, void*) = video->functionPointer->SAD_Block;
78459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncParams *encParams = video->encParams;
78559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int range = encParams->SearchRange;
78659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
78759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = video->currVop->pitch; /* padding */
78859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int comp;
78959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, j, imin, jmin, ilow, ihigh, jlow, jhigh, iorg, jorg;
79059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int d, dmin, dn[9];
79159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (ZERO_MV_PREF==1)   /* compute (0,0) MV at the end */
79259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int d0;
79359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
79459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int k;
79559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mvx[5], mvy[5], imin0, jmin0;
79659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int num_can, center_again;
79759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int last_loc, new_loc = 0;
79859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int step, max_step = range >> 1;
79959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int next;
80059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
80159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ref = video->forwardRefVop->yChan; /* origin of actual frame */
80259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
80359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cur = video->currYMB; /* use smaller memory space for current MB */
80459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
80559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*  find limit of the search (adjusting search range)*/
80659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
80759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!h263_mode)
80859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
80959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ilow = i0 - range;
81059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (ilow < -15)
81159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ilow = -15;
81259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ihigh = i0 + range - 1;
81359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (ihigh > width - 1)
81459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ihigh = width - 1;
81559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jlow = j0 - range;
81659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (jlow < -15)
81759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jlow = -15;
81859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jhigh = j0 + range - 1;
81959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (jhigh > height - 1)
82059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jhigh = height - 1;
82159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
82259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
82359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
82459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ilow = i0 - range;
82559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (ilow < 0)
82659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ilow = 0;
82759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ihigh = i0 + range - 1;
82859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (ihigh > width - 16)
82959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ihigh = width - 16;
83059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jlow = j0 - range;
83159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (jlow < 0)
83259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jlow = 0;
83359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jhigh = j0 + range - 1;
83459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (jhigh > height - 16)
83559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jhigh = height - 16;
83659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
83759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
83859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    imin = i0;
83959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    jmin = j0; /* needed for fullsearch */
84059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ncand = ref + imin + jmin * lx;
84159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* for first row of MB, fullsearch can be used */
84359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (FS_en)
84459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
84559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *hp_guess = 0; /* no guess for fast half-pel */
84659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        dmin =  fullsearch(video, currVol, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh);
84859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
84959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ncand = ref + imin + jmin * lx;
85059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
85159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][0].sad = dmin;
85259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][0].x = (imin - i0) << 1;
85359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][0].y = (jmin - j0) << 1;
85459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        imin0 = imin << 1;  /* 16x16 MV in half-pel resolution */
85559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jmin0 = jmin << 1;
85659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        best_cand[0] = ncand;
85759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
85859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
85959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {   /* 4/7/01, modified this testing for fullsearch the top row to only upto (0,3) MB */
86059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /*            upto 30% complexity saving with the same complexity */
86159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (video->forwardRefVop->predictionType == I_VOP && j0 == 0 && i0 <= 64 && type_pred != 1)
86259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
86359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *hp_guess = 0; /* no guess for fast half-pel */
86459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dmin =  fullsearch(video, currVol, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh);
86559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ncand = ref + imin + jmin * lx;
86659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
86759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
86859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
86959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /************** initialize candidate **************************/
87059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* find initial motion vector */
87159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CandidateSelection(mvx, mvy, &num_can, i0 >> 4, j0 >> 4, video, type_pred);
87259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
87359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dmin = 65535;
87459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
87559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* check if all are equal */
87659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (num_can == ALL_CAND_EQUAL)
87759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
87859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                i = i0 + mvx[0];
87959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                j = j0 + mvy[0];
88059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
88159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
88259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
88359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    cand = ref + i + j * lx;
88459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
88559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
88659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
88759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (d < dmin)
88859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
88959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        dmin = d;
89059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        imin = i;
89159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        jmin = j;
89259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        ncand = cand;
89359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
89459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
89559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
89659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
89759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
89859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /************** evaluate unique candidates **********************/
89959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (k = 0; k < num_can; k++)
90059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
90159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    i = i0 + mvx[k];
90259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    j = j0 + mvy[k];
90359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
90459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
90559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
90659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        cand = ref + i + j * lx;
90759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
90859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
90959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (d < dmin)
91059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
91159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            dmin = d;
91259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            imin = i;
91359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            jmin = j;
91459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            ncand = cand;
91559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
91659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        else if ((d == dmin) && PV_ABS(mvx[k]) + PV_ABS(mvy[k]) < PV_ABS(i0 - imin) + PV_ABS(j0 - jmin))
91759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
91859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            dmin = d;
91959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            imin = i;
92059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            jmin = j;
92159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            ncand = cand;
92259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
92359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
92459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
92559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
92659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (num_can == 0 || dmin == 65535) /* no candidate selected */
92759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
92859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncand = ref + i0 + j0 * lx; /* use (0,0) MV as initial value */
92959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[mbnum][7].sad = dmin = (*SAD_Macroblock)(ncand, cur, (65535 << 16) | lx, extra_info);
93059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (ZERO_MV_PREF==1)   /* compute (0,0) MV at the end */
93159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                d0 = dmin;
93259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
93359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                imin = i0;
93459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                jmin = j0;
93559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
93659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
93759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (ZERO_MV_PREF==0)  /*  COMPUTE ZERO VECTOR FIRST !!!!!*/
93859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dmin -= PREF_NULL_VEC;
93959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
94059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
94159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /******************* local refinement ***************************/
94259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            center_again = 0;
94359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            last_loc = new_loc = 0;
94459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            //          ncand = ref + jmin*lx + imin;  /* center of the search */
94559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            step = 0;
94659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[0] = dmin;
94759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            while (!center_again && step <= max_step)
94859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
94959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
95059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                MoveNeighborSAD(dn, last_loc);
95159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
95259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                center_again = 1;
95359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                i = imin;
95459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                j = jmin - 1;
95559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand = ref + i + j * lx;
95659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
95759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /*  starting from [0,-1] */
95859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* spiral check one step at a time*/
95959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                for (k = 2; k <= 8; k += 2)
96059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
96159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (!tab_exclude[last_loc][k]) /* exclude last step computation */
96259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {       /* not already computed */
96359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
96459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
96559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
96659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            dn[k] = d; /* keep it for half pel use */
96759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
96859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            if (d < dmin)
96959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            {
97059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                ncand = cand;
97159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                dmin = d;
97259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                imin = i;
97359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                jmin = j;
97459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                center_again = 0;
97559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                new_loc = k;
97659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            }
97759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            else if ((d == dmin) && PV_ABS(i0 - i) + PV_ABS(j0 - j) < PV_ABS(i0 - imin) + PV_ABS(j0 - jmin))
97859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            {
97959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                ncand = cand;
98059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                imin = i;
98159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                jmin = j;
98259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                center_again = 0;
98359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                new_loc = k;
98459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            }
98559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
98659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
98759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (k == 8)  /* end side search*/
98859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
98959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (!center_again)
99059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
99159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            k = -1; /* start diagonal search */
99259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            cand -= lx;
99359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            j--;
99459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
99559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
99659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else
99759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
99859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        next = refine_next[k][0];
99959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        i += next;
100059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        cand += next;
100159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        next = refine_next[k][1];
100259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        j += next;
100359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        cand += lx * next;
100459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
100559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
100659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                last_loc = new_loc;
100759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                step ++;
100859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
100959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (!center_again)
101059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                MoveNeighborSAD(dn, last_loc);
101159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
101259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *hp_guess = FindMin(dn);
101359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
101459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
101559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
101659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (ZERO_MV_PREF==1)   /* compute (0,0) MV at the end */
101759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (d0 - PREF_NULL_VEC < dmin)
101859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
101959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ncand = ref + i0 + j0 * lx;
102059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dmin = d0;
102159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            imin = i0;
102259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jmin = j0;
102359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
102459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
102559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][0].sad = dmin;
102659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][0].x = (imin - i0) << 1;
102759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][0].y = (jmin - j0) << 1;
102859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        imin0 = imin << 1;  /* 16x16 MV in half-pel resolution */
102959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jmin0 = jmin << 1;
103059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        best_cand[0] = ncand;
103159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
103259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* imin and jmin is the best 1 MV */
103359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_INTER4V
103459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*******************  Find 4 motion vectors ****************************/
103559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (use_4mv && !h263_mode)
103659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
103759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _SAD_STAT
103859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        num_Blk += 4;
103959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
104059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* starting from the best 1MV */
104159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        //offset = imin + jmin*lx;
104259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        iorg = i0;
104359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jorg = j0;
104459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
104559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (comp = 0; comp < 4; comp++)
104659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
104759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            i0 = iorg + ((comp & 1) << 3);
104859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            j0 = jorg + ((comp & 2) << 2);
104959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
105059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            imin = (imin0 >> 1) + ((comp & 1) << 3);    /* starting point from 16x16 MV */
105159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jmin = (jmin0 >> 1) + ((comp & 2) << 2);
105259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ncand = ref + imin + jmin * lx;
105359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
105459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            cur8 = cur + ((comp & 1) << 3) + (((comp & 2) << 2) << 4) ; /* 11/30/05, smaller cache */
105559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
105659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /*  find limit of the search (adjusting search range)*/
105759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ilow = i0 - range;
105859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ihigh = i0 + range - 1 ;/* 4/9/01 */
105959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (ilow < -15)
106059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ilow = -15;
106159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (ihigh > width - 1)
106259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ihigh = width - 1;
106359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jlow = j0 - range;
106459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            jhigh = j0 + range - 1 ;/* 4/9/01 */
106559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jlow < -15)
106659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                jlow = -15;
106759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jhigh > height - 1)
106859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                jhigh = height - 1;
106959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
107059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            SAD_Block = video->functionPointer->SAD_Block;
107159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
107259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (FS_en)  /* fullsearch enable, center around 16x16 MV */
107359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
107459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dmin =  fullsearchBlk(video, currVol, ncand, cur8, &imin, &jmin, ilow, ihigh, jlow, jhigh, range);
107559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncand = ref + imin + jmin * lx;
107659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
107759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[mbnum][comp+1].sad = dmin;
107859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[mbnum][comp+1].x = (imin - i0) << 1;
107959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[mbnum][comp+1].y = (jmin - j0) << 1;
108059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                best_cand[comp+1] = ncand;
108159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
108259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else    /* no fullsearch, do local search */
108359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
108459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /* starting point from 16x16 */
108559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dmin = (*SAD_Block)(ncand, cur8, 65536, lx, extra_info);
108659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
108759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                /******************* local refinement ***************************/
108859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                center_again = 0;
108959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                last_loc = 0;
109059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
109159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                while (!center_again)
109259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
109359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    center_again = 1;
109459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    i = imin;
109559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    j = jmin - 1;
109659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    cand = ref + i + j * lx;
109759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
109859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /*  starting from [0,-1] */
109959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    /* spiral check one step at a time*/
110059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    for (k = 2; k <= 8; k += 2)
110159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
110259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (!tab_exclude[last_loc][k]) /* exclude last step computation */
110359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {       /* not already computed */
110459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
110559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            {
110659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                d = (*SAD_Block)(cand, cur8, dmin, lx, extra_info);
110759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
110859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                if (d < dmin)
110959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                {
111059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    ncand = cand;
111159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    dmin = d;
111259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    imin = i;
111359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    jmin = j;
111459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    center_again = 0;
111559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    new_loc = k;
111659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                }
111759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                else if ((d == dmin) &&
111859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                         PV_ABS(i0 - i) + PV_ABS(j0 - j) < PV_ABS(i0 - imin) + PV_ABS(j0 - jmin))
111959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                {
112059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    ncand = cand;
112159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    imin = i;
112259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    jmin = j;
112359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    center_again = 0;
112459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                    new_loc = k;
112559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                }
112659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            }
112759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
112859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        if (k == 8)  /* end side search*/
112959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
113059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            if (!center_again)
113159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            {
113259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                k = -1; /* start diagonal search */
113359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                if (j <= height - 1 && j > 0)   cand -= lx;
113459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                j--;
113559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            }
113659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
113759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        else
113859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        {
113959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            next = refine_next[k][0];
114059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            cand += next;
114159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            i += next;
114259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            next = refine_next[k][1];
114359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            cand += lx * next;
114459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            j += next;
114559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        }
114659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
114759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    last_loc = new_loc;
114859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
114959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[mbnum][comp+1].sad = dmin;
115059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[mbnum][comp+1].x = (imin - i0) << 1;
115159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[mbnum][comp+1].y = (jmin - j0) << 1;
115259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                best_cand[comp+1] = ncand;
115359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
115459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /********************************************/
115559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
115659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
115759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
115859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif  /* NO_INTER4V */
115959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
116059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][1].sad = mot[mbnum][2].sad = mot[mbnum][3].sad = mot[mbnum][4].sad = (dmin + 2) >> 2;
116159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][1].x = mot[mbnum][2].x = mot[mbnum][3].x = mot[mbnum][4].x = mot[mbnum][0].x;
116259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[mbnum][1].y = mot[mbnum][2].y = mot[mbnum][3].y = mot[mbnum][4].y = mot[mbnum][0].y;
116359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        best_cand[1] = best_cand[2] = best_cand[3] = best_cand[4] = ncand;
116459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
116559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
116659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
116759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
116859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
116959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
117059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*===============================================================================
117159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   fullsearch
117259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       09/16/2000
117359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Perform full-search motion estimation over the range of search
117459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                region in a spiral-outward manner.
117559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Input/Output:   VideoEncData, current Vol, previou Vop, pointer to the left corner of
117659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                current VOP, current coord (also output), boundaries.
117759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong===============================================================================*/
117859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
117959f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt fullsearch(VideoEncData *video, Vol *currVol, UChar *prev, UChar *cur,
118059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong               Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh)
118159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
118259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int range = video->encParams->SearchRange;
118359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *cand;
118459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, j, k, l;
118559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int d, dmin;
118659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i0 = *imin; /* current position */
118759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int j0 = *jmin;
118859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*SAD_Macroblock)(UChar*, UChar*, Int, void*) = video->functionPointer->SAD_Macroblock;
118959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void *extra_info = video->sad_extra_info;
119059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  UChar h263_mode = video->encParams->H263_Enabled;
119159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = video->currVop->pitch; /* with padding */
119259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
119359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offset = i0 + j0 * lx;
119459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
119559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    OSCL_UNUSED_ARG(currVol);
119659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
119759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cand = prev + offset;
119859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
119959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dmin  = (*SAD_Macroblock)(cand, cur, (65535 << 16) | lx, (void*)extra_info) - PREF_NULL_VEC;
120059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
120159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* perform spiral search */
120259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (k = 1; k <= range; k++)
120359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
120459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
120559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        i = i0 - k;
120659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        j = j0 - k;
120759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
120859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cand = prev + i + j * lx;
120959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
121059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (l = 0; l < 8*k; l++)
121159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
121259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* no need for boundary checking again */
121359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
121459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
121559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, (void*)extra_info);
121659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
121759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (d < dmin)
121859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
121959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    dmin = d;
122059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *imin = i;
122159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *jmin = j;
122259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
122359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else if ((d == dmin) && PV_ABS(i0 - i) + PV_ABS(j0 - j) < PV_ABS(i0 - *imin) + PV_ABS(j0 - *jmin))
122459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
122559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    dmin = d;
122659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *imin = i;
122759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *jmin = j;
122859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
122959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
123059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
123159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (l < (k << 1))
123259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
123359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                i++;
123459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand++;
123559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
123659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (l < (k << 2))
123759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
123859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                j++;
123959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand += lx;
124059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
124159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (l < ((k << 2) + (k << 1)))
124259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
124359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                i--;
124459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand--;
124559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
124659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
124759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
124859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                j--;
124959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand -= lx;
125059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
125159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
125259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
125359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
125459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return dmin;
125559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
125659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
125759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_INTER4V
125859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*===============================================================================
125959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   fullsearchBlk
126059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       01/9/2001
126159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Perform full-search motion estimation of an 8x8 block over the range
126259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                of search region in a spiral-outward manner centered at the 16x16 MV.
126359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Input/Output:   VideoEncData, MB coordinate, pointer to the initial MV on the
126459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                reference, pointer to coor of current block, search range.
126559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong===============================================================================*/
126659f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt fullsearchBlk(VideoEncData *video, Vol *currVol, UChar *cent, UChar *cur,
126759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                  Int *imin, Int *jmin, Int ilow, Int ihigh, Int jlow, Int jhigh, Int range)
126859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
126959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *cand, *ref;
127059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, j, k, l, istart, jstart;
127159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int d, dmin;
127259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = video->currVop->pitch; /* with padding */
127359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*SAD_Block)(UChar*, UChar*, Int, Int, void*) = video->functionPointer->SAD_Block;
127459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void *extra_info = video->sad_extra_info;
127559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
127659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    OSCL_UNUSED_ARG(currVol);
127759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
127859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* starting point centered at 16x16 MV */
127959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ref = cent;
128059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    istart = *imin;
128159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    jstart = *jmin;
128259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
128359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dmin = (*SAD_Block)(ref, cur, 65536, lx, (void*)extra_info);
128459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
128559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cand = ref;
128659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* perform spiral search */
128759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (k = 1; k <= range; k++)
128859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
128959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
129059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        i = istart - k;
129159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        j = jstart - k;
129259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cand -= (lx + 1);  /* candidate region */
129359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
129459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (l = 0; l < 8*k; l++)
129559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
129659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* no need for boundary checking again */
129759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
129859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
129959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                d = (*SAD_Block)(cand, cur, dmin, lx, (void*)extra_info);
130059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
130159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (d < dmin)
130259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
130359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    dmin = d;
130459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *imin = i;
130559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *jmin = j;
130659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
130759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else if ((d == dmin) &&
130859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                         PV_ABS(istart - i) + PV_ABS(jstart - j) < PV_ABS(istart - *imin) + PV_ABS(jstart - *jmin))
130959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
131059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    dmin = d;
131159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *imin = i;
131259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    *jmin = j;
131359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
131459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
131559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
131659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (l < (k << 1))
131759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
131859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                i++;
131959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand++;
132059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
132159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (l < (k << 2))
132259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
132359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                j++;
132459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand += lx;
132559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
132659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (l < ((k << 2) + (k << 1)))
132759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
132859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                i--;
132959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand--;
133059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
133159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
133259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
133359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                j--;
133459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                cand -= lx;
133559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
133659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
133759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
133859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
133959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return dmin;
134059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
134159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* NO_INTER4V */
134259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
134359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*===============================================================================
134459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   CandidateSelection
134559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       09/16/2000
134659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Fill up the list of candidate using spatio-temporal correlation
134759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                among neighboring blocks.
134859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Input/Output:   type_pred = 0: first pass, 1: second pass, or no SCD
134959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Modified:    09/23/01, get rid of redundant candidates before passing back.
135059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong===============================================================================*/
135159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
135259f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid CandidateSelection(Int *mvx, Int *mvy, Int *num_can, Int imb, Int jmb,
135359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        VideoEncData *video, Int type_pred)
135459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
135559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    MOT **mot = video->mot;
135659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    MOT *pmot;
135759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbnum = video->mbnum;
135859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
135959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbwidth = currVol->nMBPerRow;
136059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int mbheight = currVol->nMBPerCol;
136159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, j, same, num1;
136259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
136359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *num_can = 0;
136459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
136559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (video->forwardRefVop->predictionType == P_VOP)
136659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
136759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* Spatio-Temporal Candidate (five candidates) */
136859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (type_pred == 0) /* first pass */
136959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
137059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pmot = &mot[mbnum][0]; /* same coordinate previous frame */
137159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mvx[(*num_can)] = (pmot->x) >> 1;
137259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mvy[(*num_can)++] = (pmot->y) >> 1;
137359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb >= (mbwidth >> 1) && imb > 0)  /*left neighbor previous frame */
137459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
137559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-1][0];
137659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
137759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
137859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
137959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (imb + 1 < mbwidth)   /*right neighbor previous frame */
138059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
138159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum+1][0];
138259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
138359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
138459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
138559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
138659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb < mbheight - 1)  /*bottom neighbor previous frame */
138759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
138859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum+mbwidth][0];
138959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
139059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
139159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
139259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (jmb > 0)   /*upper neighbor previous frame */
139359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
139459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth][0];
139559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
139659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
139759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
139859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
139959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb > 0 && jmb > 0)  /* upper-left neighbor current frame*/
140059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
140159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth-1][0];
140259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
140359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
140459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
140559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb > 0 && imb < mbheight - 1)  /* upper right neighbor current frame*/
140659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
140759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth+1][0];
140859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
140959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
141059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
141159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
141259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else    /* second pass */
141359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            /* original ST1 algorithm */
141459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
141559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pmot = &mot[mbnum][0]; /* same coordinate previous frame */
141659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mvx[(*num_can)] = (pmot->x) >> 1;
141759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mvy[(*num_can)++] = (pmot->y) >> 1;
141859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
141959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb > 0)  /*left neighbor current frame */
142059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
142159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-1][0];
142259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
142359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
142459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
142559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb > 0)  /*upper neighbor current frame */
142659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
142759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth][0];
142859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
142959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
143059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
143159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb < mbwidth - 1)  /*right neighbor previous frame */
143259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
143359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum+1][0];
143459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
143559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
143659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
143759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb < mbheight - 1)  /*bottom neighbor previous frame */
143859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
143959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum+mbwidth][0];
144059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
144159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
144259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
144359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
144459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
144559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else  /* only Spatial Candidate (four candidates)*/
144659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
144759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (type_pred == 0) /*first pass*/
144859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
144959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb > 1)  /* neighbor two blocks away to the left */
145059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
145159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-2][0];
145259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
145359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
145459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
145559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb > 0 && jmb > 0)  /* upper-left neighbor */
145659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
145759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth-1][0];
145859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
145959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
146059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
146159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb > 0 && imb < mbheight - 1)  /* upper right neighbor */
146259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
146359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth+1][0];
146459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
146559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
146659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
146759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
146859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//#ifdef SCENE_CHANGE_DETECTION
146959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* second pass (ST2 algorithm)*/
147059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (type_pred == 1) /* 4/7/01 */
147159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
147259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb > 0)  /*left neighbor current frame */
147359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
147459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-1][0];
147559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
147659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
147759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
147859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb > 0)  /*upper neighbor current frame */
147959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
148059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth][0];
148159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
148259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
148359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
148459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb < mbwidth - 1)  /*right neighbor current frame */
148559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
148659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum+1][0];
148759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
148859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
148959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
149059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb < mbheight - 1)  /*bottom neighbor current frame */
149159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
149259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum+mbwidth][0];
149359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
149459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
149559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
149659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
149759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//#else
149859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else /* original ST1 algorithm */
149959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
150059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (imb > 0)  /*left neighbor current frame */
150159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
150259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-1][0];
150359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
150459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
150559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
150659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (jmb > 0)  /*upper-left neighbor current frame */
150759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
150859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    pmot = &mot[mbnum-mbwidth-1][0];
150959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    mvx[(*num_can)] = (pmot->x) >> 1;
151059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    mvy[(*num_can)++] = (pmot->y) >> 1;
151159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
151259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
151359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
151459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (jmb > 0)  /*upper neighbor current frame */
151559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
151659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                pmot = &mot[mbnum-mbwidth][0];
151759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvx[(*num_can)] = (pmot->x) >> 1;
151859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mvy[(*num_can)++] = (pmot->y) >> 1;
151959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
152059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (imb < mbheight - 1)  /*upper-right neighbor current frame */
152159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
152259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    pmot = &mot[mbnum-mbwidth+1][0];
152359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    mvx[(*num_can)] = (pmot->x) >> 1;
152459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    mvy[(*num_can)++] = (pmot->y) >> 1;
152559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
152659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
152759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
152859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//#endif
152959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
153059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
153159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* 3/23/01, remove redundant candidate (possible k-mean) */
153259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    num1 = *num_can;
153359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *num_can = 1;
153459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 1; i < num1; i++)
153559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
153659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        same = 0;
153759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        j = 0;
153859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        while (!same && j < *num_can)
153959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
154059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#if (CANDIDATE_DISTANCE==0)
154159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (mvx[i] == mvx[j] && mvy[i] == mvy[j])
154259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#else
154359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            // modified k-mean, 3/24/01, shouldn't be greater than 3
154459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (PV_ABS(mvx[i] - mvx[j]) + PV_ABS(mvy[i] - mvy[j]) < CANDIDATE_DISTANCE)
154559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
154659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                same = 1;
154759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            j++;
154859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
154959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!same)
155059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
155159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mvx[*num_can] = mvx[i];
155259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            mvy[*num_can] = mvy[i];
155359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            (*num_can)++;
155459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
155559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
155659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
155759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _SAD_STAT
155859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    num_cand += (*num_can);
155959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
156059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
156159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (num1 == 5 && *num_can == 1)
156259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        *num_can = ALL_CAND_EQUAL; /* all are equal */
156359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
156459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
156559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
156659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
156759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*===========================================================================
156859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   RasterIntraUpdate
156959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       2/26/01
157059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    To raster-scan assign INTRA-update .
157159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                N macroblocks are updated (also was programmable).
157259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong===========================================================================*/
157359f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid RasterIntraUpdate(UChar *intraArray, UChar *Mode, Int totalMB, Int numRefresh)
157459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
157559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int indx, i;
157659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
157759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* find the last refresh MB */
157859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    indx = 0;
157959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    while (intraArray[indx] == 1 && indx < totalMB)
158059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        indx++;
158159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
158259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* add more  */
158359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 0; i < numRefresh && indx < totalMB; i++)
158459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
158559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        Mode[indx] = MODE_INTRA;
158659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        intraArray[indx++] = 1;
158759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
158859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
158959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* if read the end of frame, reset and loop around */
159059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (indx >= totalMB - 1)
159159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
159259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ResetIntraUpdate(intraArray, totalMB);
159359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        indx = 0;
159459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        while (i < numRefresh && indx < totalMB)
159559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
159659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            intraArray[indx] = 1;
159759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            Mode[indx++] = MODE_INTRA;
159859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            i++;
159959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
160059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
160159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
160259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
160359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
160459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
160559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*===========================================================================
160659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   ResetIntraUpdate
160759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       11/28/00
160859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Reset already intra updated flags to all zero
160959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong===========================================================================*/
161059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
161159f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid ResetIntraUpdate(UChar *intraArray, Int totalMB)
161259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
161359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    M4VENC_MEMSET(intraArray, 0, sizeof(UChar)*totalMB);
161459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
161559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
161659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
161759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*===========================================================================
161859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   ResetIntraUpdateRegion
161959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       12/1/00
162059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Reset already intra updated flags in one region to all zero
162159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong===========================================================================*/
162259f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid ResetIntraUpdateRegion(UChar *intraArray, Int start_i, Int rwidth,
162359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                            Int start_j, Int rheight, Int mbwidth, Int mbheight)
162459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
162559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int indx, j;
162659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
162759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (start_i + rwidth >= mbwidth)
162859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        rwidth = mbwidth - start_i;
162959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (start_j + rheight >= mbheight)
163059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        rheight = mbheight - start_j;
163159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
163259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (j = start_j; j < start_j + rheight; j++)
163359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
163459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        indx = j * mbwidth;
163559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        M4VENC_MEMSET(intraArray + indx + start_i, 0, sizeof(UChar)*rwidth);
163659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
163759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
163859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
163959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
164059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
164159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*************************************************************
164259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   MoveNeighborSAD
164359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       3/27/01
164459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Move neighboring SAD around when center has shifted
164559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong*************************************************************/
164659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
164759f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid MoveNeighborSAD(Int dn[], Int new_loc)
164859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
164959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int tmp[9];
165059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[0] = dn[0];
165159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[1] = dn[1];
165259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[2] = dn[2];
165359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[3] = dn[3];
165459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[4] = dn[4];
165559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[5] = dn[5];
165659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[6] = dn[6];
165759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[7] = dn[7];
165859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    tmp[8] = dn[8];
165959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dn[0] = dn[1] = dn[2] = dn[3] = dn[4] = dn[5] = dn[6] = dn[7] = dn[8] = 65536;
166059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
166159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    switch (new_loc)
166259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
166359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 0:
166459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
166559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 1:
166659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[4] = tmp[2];
166759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[5] = tmp[0];
166859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[6] = tmp[8];
166959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
167059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 2:
167159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[4] = tmp[3];
167259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[5] = tmp[4];
167359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[6] = tmp[0];
167459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[7] = tmp[8];
167559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[8] = tmp[1];
167659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
167759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 3:
167859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[6] = tmp[4];
167959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[7] = tmp[0];
168059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[8] = tmp[2];
168159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
168259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 4:
168359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[1] = tmp[2];
168459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[2] = tmp[3];
168559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[6] = tmp[5];
168659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[7] = tmp[6];
168759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[8] = tmp[0];
168859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
168959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 5:
169059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[1] = tmp[0];
169159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[2] = tmp[4];
169259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[8] = tmp[6];
169359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
169459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 6:
169559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[1] = tmp[8];
169659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[2] = tmp[0];
169759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[3] = tmp[4];
169859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[4] = tmp[5];
169959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[8] = tmp[7];
170059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
170159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 7:
170259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[2] = tmp[8];
170359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[3] = tmp[0];
170459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[4] = tmp[6];
170559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
170659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        case 8:
170759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[2] = tmp[1];
170859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[3] = tmp[2];
170959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[4] = tmp[0];
171059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[5] = tmp[6];
171159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dn[6] = tmp[7];
171259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            break;
171359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
171459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dn[0] = tmp[new_loc];
171559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
171659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
171759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
171859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
171959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* 3/28/01, find minimal of dn[9] */
172059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
172159f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt FindMin(Int dn[])
172259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
172359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int min, i;
172459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int dmin;
172559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
172659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dmin = dn[1];
172759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    min = 1;
172859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (i = 2; i < 9; i++)
172959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
173059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (dn[i] < dmin)
173159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
173259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dmin = dn[i];
173359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            min = i;
173459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
173559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
173659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
173759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return min;
173859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
173959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
174059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
174159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
1742