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/* 3/29/01 fast half-pel search based on neighboring guess */
2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* value ranging from 0 to 4, high complexity (more accurate) to
2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong   low complexity (less accurate) */
2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define HP_DISTANCE_TH      2  /* half-pel distance threshold */
2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#define PREF_16_VEC 129     /* 1MV bias versus 4MVs*/
2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef __cplusplus
3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dongextern "C"
3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void GenerateSearchRegion(UChar *searchPadding, UChar *ref, Int width, Int height,
3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ilow, Int ihigh, Int jlow, Int jhigh);
3659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
3759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void InterpDiag(UChar *prev, Int lx, UChar *pred_block);
3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void InterpHorz(UChar *prev, Int lx, UChar *pred_block);
3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void InterpVert(UChar *prev, Int lx, UChar *pred_block);
4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef __cplusplus
4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongconst static Int distance_tab[9][9] =   /* [hp_guess][k] */
4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {0, 1, 1, 1, 1, 1, 1, 1, 1},
4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 0, 1, 2, 3, 4, 3, 2, 1},
4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 0, 0, 0, 1, 2, 3, 2, 1},
5059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 2, 1, 0, 1, 2, 3, 4, 3},
5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 2, 1, 0, 0, 0, 1, 2, 3},
5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 4, 3, 2, 1, 0, 1, 2, 3},
5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 2, 3, 2, 1, 0, 0, 0, 1},
5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 2, 3, 4, 3, 2, 1, 0, 1},
5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {1, 0, 1, 2, 3, 2, 1, 0, 0}
5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong};
5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*=====================================================================
6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   FindHalfPelMB
6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       10/7/2000
6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Find half pel resolution MV surrounding the full-pel MV
6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong=====================================================================*/
6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dongvoid FindHalfPelMB(VideoEncData *video, UChar *cur, MOT *mot, UChar *ncand,
6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                   Int xpos, Int ypos, Int *xhmin, Int *yhmin, Int hp_guess)
6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  hp_mem = ULong *vertArray; /* 20x17 */
6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//           ULong *horzArray; /* 20x16 */
7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//           ULong *diagArray; /* 20x17 */
7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int dmin, d;
7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int xh, yh;
7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int k, kmin = 0;
7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int imin, jmin, ilow, jlow;
7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int h263_mode = video->encParams->H263_Enabled; /*  3/29/01 */
7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int in_range[9] = {0, 1, 1, 1, 1, 1, 1, 1, 1}; /*  3/29/01 */
7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int range = video->encParams->SearchRange;
7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = video->currVop->pitch;
8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = video->currVop->width; /*  padding */
8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int height = video->vol[video->currLayer]->height;
8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(**SAD_MB_HalfPel)(UChar*, UChar*, Int, void*) =
8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        video->functionPointer->SAD_MB_HalfPel;
8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void *extra_info = video->sad_extra_info;
8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int next_hp_pos[9][2] = {{0, 0}, {2, 0}, {1, 1}, {0, 2}, { -1, 1}, { -2, 0}, { -1, -1}, {0, -2}, {0, -1}};
8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int next_ncand[9] = {0, 1 , lx, lx, 0, -1, -1, -lx, -lx};
8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cur = video->currYMB;
9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /**************** check range ***************************/
9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*  3/29/01 */
9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    imin = xpos + (mot[0].x >> 1);
9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    jmin = ypos + (mot[0].y >> 1);
9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ilow = xpos - range;
9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    jlow = ypos - range;
9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (!h263_mode)
9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (imin <= -15 || imin == ilow)
10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[1] = in_range[7] = in_range[8] = 0;
10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (imin >= width - 1)
10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[3] = in_range[4] = in_range[5] = 0;
10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (jmin <= -15 || jmin == jlow)
10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[1] = in_range[2] = in_range[3] = 0;
10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (jmin >= height - 1)
10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[5] = in_range[6] = in_range[7] = 0;
10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (imin <= 0 || imin == ilow)
11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[1] = in_range[7] = in_range[8] = 0;
11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (imin >= width - 16)
11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[3] = in_range[4] = in_range[5] = 0;
11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (jmin <= 0 || jmin == jlow)
11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[1] = in_range[2] = in_range[3] = 0;
11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (jmin >= height - 16)
11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[5] = in_range[6] = in_range[7] = 0;
11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
12059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    xhmin[0] = 0;
12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    yhmin[0] = 0;
12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dmin = mot[0].sad;
12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    xh = 0;
12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    yh = -1;
12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    ncand -= lx; /* initial position */
12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (k = 2; k <= 8; k += 2)
13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (distance_tab[hp_guess][k] < HP_DISTANCE_TH)
13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (in_range[k])
13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                d = (*(SAD_MB_HalfPel[((yh&1)<<1)+(xh&1)]))(ncand, cur, (dmin << 16) | lx, extra_info);
13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (d < dmin)
13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    dmin = d;
14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    xhmin[0] = xh;
14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    yhmin[0] = yh;
14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    kmin = k;
14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else if (d == dmin &&
14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                         PV_ABS(mot[0].x + xh) + PV_ABS(mot[0].y + yh) < PV_ABS(mot[0].x + xhmin[0]) + PV_ABS(mot[0].y + yhmin[0]))
14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    xhmin[0] = xh;
14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    yhmin[0] = yh;
14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    kmin = k;
15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        xh += next_hp_pos[k][0];
15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        yh += next_hp_pos[k][1];
15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ncand += next_ncand[k];
15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (k == 8)
15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (xhmin[0] != 0 || yhmin[0] != 0)
16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                k = -1;
16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                hp_guess = kmin;
16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    mot[0].sad = dmin;
16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    mot[0].x += xhmin[0];
17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    mot[0].y += yhmin[0];
17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return ;
17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_INTER4V
17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*=====================================================================
17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Function:   FindHalfPelBlk
17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Date:       10/7/2000
17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Purpose:    Find half pel resolution MV surrounding the full-pel MV
18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                And decide between 1MV or 4MV mode
18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong=====================================================================*/
18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong///// THIS FUNCTION IS NOT WORKING!!! NEED TO BE RIVISITED
18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
18459f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt FindHalfPelBlk(VideoEncData *video, UChar *cur, MOT *mot, Int sad16, UChar *ncand8[],
18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                   UChar *mode, Int xpos, Int ypos, Int *xhmin, Int *yhmin, UChar *hp_mem)
18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int k, comp;
18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int xh, yh;//, xhmin, yhmin;
18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int imin, jmin, ilow, jlow;
19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int height;
19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *cand, *cur8;
19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *hmem;//[17*17]; /* half-pel memory */
19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int d, dmin, sad8;
19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = video->currVop->pitch;
19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = video->currVop->width; /* , padding */
19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*SAD_Blk_HalfPel)(UChar*, UChar*, Int, Int, Int, Int, Int, void*) = video->functionPointer->SAD_Blk_HalfPel;
19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void *extra_info = video->sad_extra_info;
19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int in_range[8]; /*  3/29/01 */
19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int range = video->encParams->SearchRange;
20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int swidth;
20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int next_hp_pos[8][2] = {{1, 0}, {1, 0}, {0, 1}, {0, 1}, { -1, 0}, { -1, 0}, {0, -1}, {0, -1}};
20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    height = video->vol[video->currLayer]->height;
20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    hmem = hp_mem;
20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    sad8 = 0;
20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (comp = 0; comp < 4; comp++)
20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifdef _SAD_STAT
21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        num_HP_Blk++;
21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**************** check range ***************************/
21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /*  3/29/01 */
21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        M4VENC_MEMSET(in_range, 1, sizeof(Int) << 3);
21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        imin = xpos + ((comp & 1) << 3) + (mot[comp+1].x >> 1);
21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jmin = ypos + ((comp & 2) << 2) + (mot[comp+1].y >> 1);
21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ilow = xpos + ((comp & 1) << 3) - range;
21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        jlow = ypos + ((comp & 2) << 2) - range;
21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (imin <= -15 || imin == ilow)
22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[0] = in_range[6] = in_range[7] = 0;
22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (imin >= width - 1)
22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[2] = in_range[3] = in_range[4] = 0;
22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (jmin <= -15 || jmin == jlow)
22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[0] = in_range[1] = in_range[2] = 0;
22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (jmin >= height - 1)
22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            in_range[4] = in_range[5] = in_range[6] = 0;
22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /**************** half-pel search ***********************/
23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur8 = cur + ((comp & 1) << 3) + ((comp & 2) << 2) * width ;
23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /* generate half-pel search region */
23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            cand = ncand8[comp+1];
23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            swidth = lx;
23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        xhmin[comp+1] = 0;
24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        yhmin[comp+1] = 0;
24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        dmin = mot[comp+1].sad;
24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        xh = -1;
24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        yh = -1;
24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        for (k = 0; k < 8; k++)
24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (in_range[k])
24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                d = (*SAD_Blk_HalfPel)(cand, cur8, dmin, lx, swidth, xh, yh, extra_info);
25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (d < dmin)
25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    dmin = d;
25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    xhmin[comp+1] = xh;
25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    yhmin[comp+1] = yh;
25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            xh += next_hp_pos[k][0];
25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            yh += next_hp_pos[k][1];
26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        /********************************************/
26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[comp+1].x += xhmin[comp+1];
26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[comp+1].y += yhmin[comp+1];
26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mot[comp+1].sad = dmin;
26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sad8 += dmin;
26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (sad8 >= sad16 - PREF_16_VEC)
26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            *mode = MODE_INTER;
27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            for (k = 1; k <= 4; k++)
27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[k].sad = (mot[0].sad + 2) >> 2;
27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[k].x = mot[0].x;
27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                mot[k].y = mot[0].y;
27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            return sad8;
27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
27959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        hmem += (10 * 10);
28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    *mode = MODE_INTER4V;
28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return sad8;
28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif /* NO_INTER4V */
28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
288