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