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