129a84457aed4c45bc900998b5e11c03023264208James Dong/* ------------------------------------------------------------------
229a84457aed4c45bc900998b5e11c03023264208James Dong * Copyright (C) 1998-2009 PacketVideo
329a84457aed4c45bc900998b5e11c03023264208James Dong *
429a84457aed4c45bc900998b5e11c03023264208James Dong * Licensed under the Apache License, Version 2.0 (the "License");
529a84457aed4c45bc900998b5e11c03023264208James Dong * you may not use this file except in compliance with the License.
629a84457aed4c45bc900998b5e11c03023264208James Dong * You may obtain a copy of the License at
729a84457aed4c45bc900998b5e11c03023264208James Dong *
829a84457aed4c45bc900998b5e11c03023264208James Dong *      http://www.apache.org/licenses/LICENSE-2.0
929a84457aed4c45bc900998b5e11c03023264208James Dong *
1029a84457aed4c45bc900998b5e11c03023264208James Dong * Unless required by applicable law or agreed to in writing, software
1129a84457aed4c45bc900998b5e11c03023264208James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1229a84457aed4c45bc900998b5e11c03023264208James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1329a84457aed4c45bc900998b5e11c03023264208James Dong * express or implied.
1429a84457aed4c45bc900998b5e11c03023264208James Dong * See the License for the specific language governing permissions
1529a84457aed4c45bc900998b5e11c03023264208James Dong * and limitations under the License.
1629a84457aed4c45bc900998b5e11c03023264208James Dong * -------------------------------------------------------------------
1729a84457aed4c45bc900998b5e11c03023264208James Dong */
1829a84457aed4c45bc900998b5e11c03023264208James Dong#include "avcenc_lib.h"
1929a84457aed4c45bc900998b5e11c03023264208James Dong
2029a84457aed4c45bc900998b5e11c03023264208James Dong#define MIN_GOP     1   /* minimum size of GOP, 1/23/01, need to be tested */
2129a84457aed4c45bc900998b5e11c03023264208James Dong
2229a84457aed4c45bc900998b5e11c03023264208James Dong#define DEFAULT_REF_IDX     0  /* always from the first frame in the reflist */
2329a84457aed4c45bc900998b5e11c03023264208James Dong
2429a84457aed4c45bc900998b5e11c03023264208James Dong#define ALL_CAND_EQUAL  10  /*  any number greater than 5 will work */
2529a84457aed4c45bc900998b5e11c03023264208James Dong
2629a84457aed4c45bc900998b5e11c03023264208James Dong
2729a84457aed4c45bc900998b5e11c03023264208James Dong/* from TMN 3.2 */
2829a84457aed4c45bc900998b5e11c03023264208James Dong#define PREF_NULL_VEC 129   /* zero vector bias */
2929a84457aed4c45bc900998b5e11c03023264208James Dong#define PREF_16_VEC 129     /* 1MV bias versus 4MVs*/
3029a84457aed4c45bc900998b5e11c03023264208James Dong#define PREF_INTRA  3024//512       /* bias for INTRA coding */
3129a84457aed4c45bc900998b5e11c03023264208James Dong
3229a84457aed4c45bc900998b5e11c03023264208James Dongconst static int tab_exclude[9][9] =  // [last_loc][curr_loc]
3329a84457aed4c45bc900998b5e11c03023264208James Dong{
3429a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 0, 0, 0, 0, 0, 0, 0, 0},
3529a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 0, 0, 0, 1, 1, 1, 0, 0},
3629a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 0, 0, 0, 1, 1, 1, 1, 1},
3729a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 0, 0, 0, 0, 0, 1, 1, 1},
3829a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 1, 1, 0, 0, 0, 1, 1, 1},
3929a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 1, 1, 0, 0, 0, 0, 0, 1},
4029a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 1, 1, 1, 1, 0, 0, 0, 1},
4129a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 0, 1, 1, 1, 0, 0, 0, 0},
4229a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 0, 1, 1, 1, 1, 1, 0, 0}
4329a84457aed4c45bc900998b5e11c03023264208James Dong}; //to decide whether to continue or compute
4429a84457aed4c45bc900998b5e11c03023264208James Dong
4529a84457aed4c45bc900998b5e11c03023264208James Dongconst static int refine_next[8][2] =    /* [curr_k][increment] */
4629a84457aed4c45bc900998b5e11c03023264208James Dong{
4729a84457aed4c45bc900998b5e11c03023264208James Dong    {0, 0}, {2, 0}, {1, 1}, {0, 2}, { -1, 1}, { -2, 0}, { -1, -1}, {0, -2}
4829a84457aed4c45bc900998b5e11c03023264208James Dong};
4929a84457aed4c45bc900998b5e11c03023264208James Dong
5029a84457aed4c45bc900998b5e11c03023264208James Dong#ifdef _SAD_STAT
5129a84457aed4c45bc900998b5e11c03023264208James Donguint32 num_MB = 0;
5229a84457aed4c45bc900998b5e11c03023264208James Donguint32 num_cand = 0;
5329a84457aed4c45bc900998b5e11c03023264208James Dong#endif
5429a84457aed4c45bc900998b5e11c03023264208James Dong
5529a84457aed4c45bc900998b5e11c03023264208James Dong/************************************************************************/
5629a84457aed4c45bc900998b5e11c03023264208James Dong#define TH_INTER_2  100  /* temporary for now */
5729a84457aed4c45bc900998b5e11c03023264208James Dong
5829a84457aed4c45bc900998b5e11c03023264208James Dong//#define FIXED_INTERPRED_MODE  AVC_P16
5929a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_REF_IDX   0
6029a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_MVX 0
6129a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_MVY 0
6229a84457aed4c45bc900998b5e11c03023264208James Dong
6329a84457aed4c45bc900998b5e11c03023264208James Dong// only use when AVC_P8 or AVC_P8ref0
6429a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_SUBMB_MODE    AVC_4x4
6529a84457aed4c45bc900998b5e11c03023264208James Dong/*************************************************************************/
6629a84457aed4c45bc900998b5e11c03023264208James Dong
6729a84457aed4c45bc900998b5e11c03023264208James Dong/* Initialize arrays necessary for motion search */
6829a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status InitMotionSearchModule(AVCHandle *avcHandle)
6929a84457aed4c45bc900998b5e11c03023264208James Dong{
7029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject;
7129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCRateControl *rateCtrl = encvid->rateCtrl;
7229a84457aed4c45bc900998b5e11c03023264208James Dong    int search_range = rateCtrl->mvRange;
7329a84457aed4c45bc900998b5e11c03023264208James Dong    int number_of_subpel_positions = 4 * (2 * search_range + 3);
7429a84457aed4c45bc900998b5e11c03023264208James Dong    int max_mv_bits, max_mvd;
7529a84457aed4c45bc900998b5e11c03023264208James Dong    int temp_bits = 0;
7629a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *mvbits;
7729a84457aed4c45bc900998b5e11c03023264208James Dong    int bits, imax, imin, i;
7829a84457aed4c45bc900998b5e11c03023264208James Dong    uint8* subpel_pred = (uint8*) encvid->subpel_pred; // all 16 sub-pel positions
7929a84457aed4c45bc900998b5e11c03023264208James Dong
8029a84457aed4c45bc900998b5e11c03023264208James Dong
8129a84457aed4c45bc900998b5e11c03023264208James Dong    while (number_of_subpel_positions > 0)
8229a84457aed4c45bc900998b5e11c03023264208James Dong    {
8329a84457aed4c45bc900998b5e11c03023264208James Dong        temp_bits++;
8429a84457aed4c45bc900998b5e11c03023264208James Dong        number_of_subpel_positions >>= 1;
8529a84457aed4c45bc900998b5e11c03023264208James Dong    }
8629a84457aed4c45bc900998b5e11c03023264208James Dong
8729a84457aed4c45bc900998b5e11c03023264208James Dong    max_mv_bits = 3 + 2 * temp_bits;
8829a84457aed4c45bc900998b5e11c03023264208James Dong    max_mvd  = (1 << (max_mv_bits >> 1)) - 1;
8929a84457aed4c45bc900998b5e11c03023264208James Dong
9029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->mvbits_array = (uint8*) avcHandle->CBAVC_Malloc(encvid->avcHandle->userData,
9129a84457aed4c45bc900998b5e11c03023264208James Dong                           sizeof(uint8) * (2 * max_mvd + 1), DEFAULT_ATTR);
9229a84457aed4c45bc900998b5e11c03023264208James Dong
9329a84457aed4c45bc900998b5e11c03023264208James Dong    if (encvid->mvbits_array == NULL)
9429a84457aed4c45bc900998b5e11c03023264208James Dong    {
9529a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_MEMORY_FAIL;
9629a84457aed4c45bc900998b5e11c03023264208James Dong    }
9729a84457aed4c45bc900998b5e11c03023264208James Dong
9829a84457aed4c45bc900998b5e11c03023264208James Dong    mvbits = encvid->mvbits  = encvid->mvbits_array + max_mvd;
9929a84457aed4c45bc900998b5e11c03023264208James Dong
10029a84457aed4c45bc900998b5e11c03023264208James Dong    mvbits[0] = 1;
10129a84457aed4c45bc900998b5e11c03023264208James Dong    for (bits = 3; bits <= max_mv_bits; bits += 2)
10229a84457aed4c45bc900998b5e11c03023264208James Dong    {
10329a84457aed4c45bc900998b5e11c03023264208James Dong        imax = 1    << (bits >> 1);
10429a84457aed4c45bc900998b5e11c03023264208James Dong        imin = imax >> 1;
10529a84457aed4c45bc900998b5e11c03023264208James Dong
10629a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = imin; i < imax; i++)   mvbits[-i] = mvbits[i] = bits;
10729a84457aed4c45bc900998b5e11c03023264208James Dong    }
10829a84457aed4c45bc900998b5e11c03023264208James Dong
10929a84457aed4c45bc900998b5e11c03023264208James Dong    /* initialize half-pel search */
11029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[0] = subpel_pred + REF_CENTER;
11129a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[1] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1 ;
11229a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[2] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1;
11329a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[3] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25;
11429a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[4] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25;
11529a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[5] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 25;
11629a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[6] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
11729a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[7] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
11829a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->hpel_cand[8] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE;
11929a84457aed4c45bc900998b5e11c03023264208James Dong
12029a84457aed4c45bc900998b5e11c03023264208James Dong    /* For quarter-pel interpolation around best half-pel result */
12129a84457aed4c45bc900998b5e11c03023264208James Dong
12229a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[0][0] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE;
12329a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[0][1] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1;
12429a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[0][2] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
12529a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[0][3] = subpel_pred + REF_CENTER;
12629a84457aed4c45bc900998b5e11c03023264208James Dong
12729a84457aed4c45bc900998b5e11c03023264208James Dong
12829a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[1][0] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE;
12929a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[1][1] = subpel_pred + REF_CENTER - 24;
13029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[1][2] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE;
13129a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[1][3] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1;
13229a84457aed4c45bc900998b5e11c03023264208James Dong
13329a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[2][0] = subpel_pred + REF_CENTER - 24;
13429a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[2][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1;
13529a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[2][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1;
13629a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[2][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1;
13729a84457aed4c45bc900998b5e11c03023264208James Dong
13829a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[3][0] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1;
13929a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[3][1] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1;
14029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[3][2] = subpel_pred + REF_CENTER;
14129a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[3][3] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25;
14229a84457aed4c45bc900998b5e11c03023264208James Dong
14329a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[4][0] = subpel_pred + REF_CENTER;
14429a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[4][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25;
14529a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[4][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 25;
14629a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[4][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25;
14729a84457aed4c45bc900998b5e11c03023264208James Dong
14829a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[5][0] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
14929a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[5][1] = subpel_pred + REF_CENTER;
15029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[5][2] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
15129a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[5][3] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 25;
15229a84457aed4c45bc900998b5e11c03023264208James Dong
15329a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[6][0] = subpel_pred + REF_CENTER - 1;
15429a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[6][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
15529a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[6][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 24;
15629a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[6][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
15729a84457aed4c45bc900998b5e11c03023264208James Dong
15829a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[7][0] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE;
15929a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[7][1] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE;
16029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[7][2] = subpel_pred + REF_CENTER - 1;
16129a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[7][3] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24;
16229a84457aed4c45bc900998b5e11c03023264208James Dong
16329a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[8][0] = subpel_pred + REF_CENTER - 25;
16429a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[8][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE;
16529a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[8][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE;
16629a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->bilin_base[8][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE;
16729a84457aed4c45bc900998b5e11c03023264208James Dong
16829a84457aed4c45bc900998b5e11c03023264208James Dong
16929a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
17029a84457aed4c45bc900998b5e11c03023264208James Dong}
17129a84457aed4c45bc900998b5e11c03023264208James Dong
17229a84457aed4c45bc900998b5e11c03023264208James Dong/* Clean-up memory */
17329a84457aed4c45bc900998b5e11c03023264208James Dongvoid CleanMotionSearchModule(AVCHandle *avcHandle)
17429a84457aed4c45bc900998b5e11c03023264208James Dong{
17529a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject;
17629a84457aed4c45bc900998b5e11c03023264208James Dong
17729a84457aed4c45bc900998b5e11c03023264208James Dong    if (encvid->mvbits_array)
17829a84457aed4c45bc900998b5e11c03023264208James Dong    {
17923da4cf305b9bfff07954711a8a2d9ec040865afMartin Storsjo        avcHandle->CBAVC_Free(avcHandle->userData, encvid->mvbits_array);
18029a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->mvbits = NULL;
18129a84457aed4c45bc900998b5e11c03023264208James Dong    }
18229a84457aed4c45bc900998b5e11c03023264208James Dong
18329a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
18429a84457aed4c45bc900998b5e11c03023264208James Dong}
18529a84457aed4c45bc900998b5e11c03023264208James Dong
18629a84457aed4c45bc900998b5e11c03023264208James Dong
18729a84457aed4c45bc900998b5e11c03023264208James Dongbool IntraDecisionABE(int *min_cost, uint8 *cur, int pitch, bool ave)
18829a84457aed4c45bc900998b5e11c03023264208James Dong{
18929a84457aed4c45bc900998b5e11c03023264208James Dong    int j;
19029a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *out;
19129a84457aed4c45bc900998b5e11c03023264208James Dong    int temp, SBE;
19229a84457aed4c45bc900998b5e11c03023264208James Dong    OsclFloat ABE;
19329a84457aed4c45bc900998b5e11c03023264208James Dong    bool intra = true;
19429a84457aed4c45bc900998b5e11c03023264208James Dong
19529a84457aed4c45bc900998b5e11c03023264208James Dong    SBE = 0;
19629a84457aed4c45bc900998b5e11c03023264208James Dong    /* top neighbor */
19729a84457aed4c45bc900998b5e11c03023264208James Dong    out = cur - pitch;
19829a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 0; j < 16; j++)
19929a84457aed4c45bc900998b5e11c03023264208James Dong    {
20029a84457aed4c45bc900998b5e11c03023264208James Dong        temp = out[j] - cur[j];
20129a84457aed4c45bc900998b5e11c03023264208James Dong        SBE += ((temp >= 0) ? temp : -temp);
20229a84457aed4c45bc900998b5e11c03023264208James Dong    }
20329a84457aed4c45bc900998b5e11c03023264208James Dong
20429a84457aed4c45bc900998b5e11c03023264208James Dong    /* left neighbor */
20529a84457aed4c45bc900998b5e11c03023264208James Dong    out = cur - 1;
20629a84457aed4c45bc900998b5e11c03023264208James Dong    out -= pitch;
20729a84457aed4c45bc900998b5e11c03023264208James Dong    cur -= pitch;
20829a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 0; j < 16; j++)
20929a84457aed4c45bc900998b5e11c03023264208James Dong    {
21029a84457aed4c45bc900998b5e11c03023264208James Dong        temp = *(out += pitch) - *(cur += pitch);
21129a84457aed4c45bc900998b5e11c03023264208James Dong        SBE += ((temp >= 0) ? temp : -temp);
21229a84457aed4c45bc900998b5e11c03023264208James Dong    }
21329a84457aed4c45bc900998b5e11c03023264208James Dong
21429a84457aed4c45bc900998b5e11c03023264208James Dong    /* compare mincost/384 and SBE/64 */
21529a84457aed4c45bc900998b5e11c03023264208James Dong    ABE = SBE / 32.0; //ABE = SBE/64.0; //
21629a84457aed4c45bc900998b5e11c03023264208James Dong    if (ABE >= *min_cost / 256.0) //if( ABE*0.8 >= min_cost/384.0) //
21729a84457aed4c45bc900998b5e11c03023264208James Dong    {
21829a84457aed4c45bc900998b5e11c03023264208James Dong        intra = false; // no possibility of intra, just use inter
21929a84457aed4c45bc900998b5e11c03023264208James Dong    }
22029a84457aed4c45bc900998b5e11c03023264208James Dong    else
22129a84457aed4c45bc900998b5e11c03023264208James Dong    {
22229a84457aed4c45bc900998b5e11c03023264208James Dong        if (ave == true)
22329a84457aed4c45bc900998b5e11c03023264208James Dong        {
22429a84457aed4c45bc900998b5e11c03023264208James Dong            *min_cost = (*min_cost + (int)(SBE * 8)) >> 1; // possibility of intra, averaging the cost
22529a84457aed4c45bc900998b5e11c03023264208James Dong        }
22629a84457aed4c45bc900998b5e11c03023264208James Dong        else
22729a84457aed4c45bc900998b5e11c03023264208James Dong        {
22829a84457aed4c45bc900998b5e11c03023264208James Dong            *min_cost = (int)(SBE * 8);
22929a84457aed4c45bc900998b5e11c03023264208James Dong        }
23029a84457aed4c45bc900998b5e11c03023264208James Dong    }
23129a84457aed4c45bc900998b5e11c03023264208James Dong
23229a84457aed4c45bc900998b5e11c03023264208James Dong    return intra;
23329a84457aed4c45bc900998b5e11c03023264208James Dong}
23429a84457aed4c45bc900998b5e11c03023264208James Dong
23529a84457aed4c45bc900998b5e11c03023264208James Dong/******* main function for macroblock prediction for the entire frame ***/
23629a84457aed4c45bc900998b5e11c03023264208James Dong/* if turns out to be IDR frame, set video->nal_unit_type to AVC_NALTYPE_IDR */
23729a84457aed4c45bc900998b5e11c03023264208James Dongvoid AVCMotionEstimation(AVCEncObject *encvid)
23829a84457aed4c45bc900998b5e11c03023264208James Dong{
23929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
24029a84457aed4c45bc900998b5e11c03023264208James Dong    int slice_type = video->slice_type;
24129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCFrameIO *currInput = encvid->currInput;
24229a84457aed4c45bc900998b5e11c03023264208James Dong    AVCPictureData *refPic = video->RefPicList0[0];
24329a84457aed4c45bc900998b5e11c03023264208James Dong    int i, j, k;
24429a84457aed4c45bc900998b5e11c03023264208James Dong    int mbwidth = video->PicWidthInMbs;
24529a84457aed4c45bc900998b5e11c03023264208James Dong    int mbheight = video->PicHeightInMbs;
24629a84457aed4c45bc900998b5e11c03023264208James Dong    int totalMB = video->PicSizeInMbs;
24729a84457aed4c45bc900998b5e11c03023264208James Dong    int pitch = currInput->pitch;
24829a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMacroblock *currMB, *mblock = video->mblock;
24929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMV *mot_mb_16x16, *mot16x16 = encvid->mot16x16;
25029a84457aed4c45bc900998b5e11c03023264208James Dong    // AVCMV *mot_mb_16x8, *mot_mb_8x16, *mot_mb_8x8, etc;
25129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCRateControl *rateCtrl = encvid->rateCtrl;
25229a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *intraSearch = encvid->intraSearch;
25329a84457aed4c45bc900998b5e11c03023264208James Dong    uint FS_en = encvid->fullsearch_enable;
25429a84457aed4c45bc900998b5e11c03023264208James Dong
25529a84457aed4c45bc900998b5e11c03023264208James Dong    int NumIntraSearch, start_i, numLoop, incr_i;
25629a84457aed4c45bc900998b5e11c03023264208James Dong    int mbnum, offset;
25729a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *cur, *best_cand[5];
25829a84457aed4c45bc900998b5e11c03023264208James Dong    int totalSAD = 0;   /* average SAD for rate control */
25929a84457aed4c45bc900998b5e11c03023264208James Dong    int type_pred;
26029a84457aed4c45bc900998b5e11c03023264208James Dong    int abe_cost;
26129a84457aed4c45bc900998b5e11c03023264208James Dong
26229a84457aed4c45bc900998b5e11c03023264208James Dong#ifdef HTFM
26329a84457aed4c45bc900998b5e11c03023264208James Dong    /***** HYPOTHESIS TESTING ********/  /* 2/28/01 */
26429a84457aed4c45bc900998b5e11c03023264208James Dong    int collect = 0;
26529a84457aed4c45bc900998b5e11c03023264208James Dong    HTFM_Stat htfm_stat;
26629a84457aed4c45bc900998b5e11c03023264208James Dong    double newvar[16];
26729a84457aed4c45bc900998b5e11c03023264208James Dong    double exp_lamda[15];
26829a84457aed4c45bc900998b5e11c03023264208James Dong    /*********************************/
26929a84457aed4c45bc900998b5e11c03023264208James Dong#endif
27029a84457aed4c45bc900998b5e11c03023264208James Dong    int hp_guess = 0;
27129a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 mv_uint32;
27229a84457aed4c45bc900998b5e11c03023264208James Dong
27329a84457aed4c45bc900998b5e11c03023264208James Dong    offset = 0;
27429a84457aed4c45bc900998b5e11c03023264208James Dong
27529a84457aed4c45bc900998b5e11c03023264208James Dong    if (slice_type == AVC_I_SLICE)
27629a84457aed4c45bc900998b5e11c03023264208James Dong    {
27729a84457aed4c45bc900998b5e11c03023264208James Dong        /* cannot do I16 prediction here because it needs full decoding. */
27829a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < totalMB; i++)
27929a84457aed4c45bc900998b5e11c03023264208James Dong        {
28029a84457aed4c45bc900998b5e11c03023264208James Dong            encvid->min_cost[i] = 0x7FFFFFFF;  /* max value for int */
28129a84457aed4c45bc900998b5e11c03023264208James Dong        }
28229a84457aed4c45bc900998b5e11c03023264208James Dong
28329a84457aed4c45bc900998b5e11c03023264208James Dong        memset(intraSearch, 1, sizeof(uint8)*totalMB);
28429a84457aed4c45bc900998b5e11c03023264208James Dong
28529a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->firstIntraRefreshMBIndx = 0; /* reset this */
28629a84457aed4c45bc900998b5e11c03023264208James Dong
28729a84457aed4c45bc900998b5e11c03023264208James Dong        return ;
28829a84457aed4c45bc900998b5e11c03023264208James Dong    }
28929a84457aed4c45bc900998b5e11c03023264208James Dong    else   // P_SLICE
29029a84457aed4c45bc900998b5e11c03023264208James Dong    {
29129a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < totalMB; i++)
29229a84457aed4c45bc900998b5e11c03023264208James Dong        {
29329a84457aed4c45bc900998b5e11c03023264208James Dong            mblock[i].mb_intra = 0;
29429a84457aed4c45bc900998b5e11c03023264208James Dong        }
29529a84457aed4c45bc900998b5e11c03023264208James Dong        memset(intraSearch, 1, sizeof(uint8)*totalMB);
29629a84457aed4c45bc900998b5e11c03023264208James Dong    }
29729a84457aed4c45bc900998b5e11c03023264208James Dong
29829a84457aed4c45bc900998b5e11c03023264208James Dong    if (refPic->padded == 0)
29929a84457aed4c45bc900998b5e11c03023264208James Dong    {
30029a84457aed4c45bc900998b5e11c03023264208James Dong        AVCPaddingEdge(refPic);
30129a84457aed4c45bc900998b5e11c03023264208James Dong        refPic->padded = 1;
30229a84457aed4c45bc900998b5e11c03023264208James Dong    }
30329a84457aed4c45bc900998b5e11c03023264208James Dong    /* Random INTRA update */
30429a84457aed4c45bc900998b5e11c03023264208James Dong    if (rateCtrl->intraMBRate)
30529a84457aed4c45bc900998b5e11c03023264208James Dong    {
30629a84457aed4c45bc900998b5e11c03023264208James Dong        AVCRasterIntraUpdate(encvid, mblock, totalMB, rateCtrl->intraMBRate);
30729a84457aed4c45bc900998b5e11c03023264208James Dong    }
30829a84457aed4c45bc900998b5e11c03023264208James Dong
30929a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->sad_extra_info = NULL;
31029a84457aed4c45bc900998b5e11c03023264208James Dong#ifdef HTFM
31129a84457aed4c45bc900998b5e11c03023264208James Dong    /***** HYPOTHESIS TESTING ********/
31229a84457aed4c45bc900998b5e11c03023264208James Dong    InitHTFM(video, &htfm_stat, newvar, &collect);
31329a84457aed4c45bc900998b5e11c03023264208James Dong    /*********************************/
31429a84457aed4c45bc900998b5e11c03023264208James Dong#endif
31529a84457aed4c45bc900998b5e11c03023264208James Dong
31629a84457aed4c45bc900998b5e11c03023264208James Dong    if ((rateCtrl->scdEnable == 1)
31729a84457aed4c45bc900998b5e11c03023264208James Dong            && ((rateCtrl->frame_rate < 5.0) || (video->sliceHdr->frame_num > MIN_GOP)))
31829a84457aed4c45bc900998b5e11c03023264208James Dong        /* do not try to detect a new scene if low frame rate and too close to previous I-frame */
31929a84457aed4c45bc900998b5e11c03023264208James Dong    {
32029a84457aed4c45bc900998b5e11c03023264208James Dong        incr_i = 2;
32129a84457aed4c45bc900998b5e11c03023264208James Dong        numLoop = 2;
32229a84457aed4c45bc900998b5e11c03023264208James Dong        start_i = 1;
32329a84457aed4c45bc900998b5e11c03023264208James Dong        type_pred = 0; /* for initial candidate selection */
32429a84457aed4c45bc900998b5e11c03023264208James Dong    }
32529a84457aed4c45bc900998b5e11c03023264208James Dong    else
32629a84457aed4c45bc900998b5e11c03023264208James Dong    {
32729a84457aed4c45bc900998b5e11c03023264208James Dong        incr_i = 1;
32829a84457aed4c45bc900998b5e11c03023264208James Dong        numLoop = 1;
32929a84457aed4c45bc900998b5e11c03023264208James Dong        start_i = 0;
33029a84457aed4c45bc900998b5e11c03023264208James Dong        type_pred = 2;
33129a84457aed4c45bc900998b5e11c03023264208James Dong    }
33229a84457aed4c45bc900998b5e11c03023264208James Dong
33329a84457aed4c45bc900998b5e11c03023264208James Dong    /* First pass, loop thru half the macroblock */
33429a84457aed4c45bc900998b5e11c03023264208James Dong    /* determine scene change */
33529a84457aed4c45bc900998b5e11c03023264208James Dong    /* Second pass, for the rest of macroblocks */
33629a84457aed4c45bc900998b5e11c03023264208James Dong    NumIntraSearch = 0; // to be intra searched in the encoding loop.
33729a84457aed4c45bc900998b5e11c03023264208James Dong    while (numLoop--)
33829a84457aed4c45bc900998b5e11c03023264208James Dong    {
33929a84457aed4c45bc900998b5e11c03023264208James Dong        for (j = 0; j < mbheight; j++)
34029a84457aed4c45bc900998b5e11c03023264208James Dong        {
34129a84457aed4c45bc900998b5e11c03023264208James Dong            if (incr_i > 1)
34229a84457aed4c45bc900998b5e11c03023264208James Dong                start_i = (start_i == 0 ? 1 : 0) ; /* toggle 0 and 1 */
34329a84457aed4c45bc900998b5e11c03023264208James Dong
34429a84457aed4c45bc900998b5e11c03023264208James Dong            offset = pitch * (j << 4) + (start_i << 4);
34529a84457aed4c45bc900998b5e11c03023264208James Dong
34629a84457aed4c45bc900998b5e11c03023264208James Dong            mbnum = j * mbwidth + start_i;
34729a84457aed4c45bc900998b5e11c03023264208James Dong
34829a84457aed4c45bc900998b5e11c03023264208James Dong            for (i = start_i; i < mbwidth; i += incr_i)
34929a84457aed4c45bc900998b5e11c03023264208James Dong            {
35029a84457aed4c45bc900998b5e11c03023264208James Dong                video->mbNum = mbnum;
35129a84457aed4c45bc900998b5e11c03023264208James Dong                video->currMB = currMB = mblock + mbnum;
35229a84457aed4c45bc900998b5e11c03023264208James Dong                mot_mb_16x16 = mot16x16 + mbnum;
35329a84457aed4c45bc900998b5e11c03023264208James Dong
35429a84457aed4c45bc900998b5e11c03023264208James Dong                cur = currInput->YCbCr[0] + offset;
35529a84457aed4c45bc900998b5e11c03023264208James Dong
35629a84457aed4c45bc900998b5e11c03023264208James Dong                if (currMB->mb_intra == 0) /* for INTER mode */
35729a84457aed4c45bc900998b5e11c03023264208James Dong                {
35829a84457aed4c45bc900998b5e11c03023264208James Dong#if defined(HTFM)
35929a84457aed4c45bc900998b5e11c03023264208James Dong                    HTFMPrepareCurMB_AVC(encvid, &htfm_stat, cur, pitch);
36029a84457aed4c45bc900998b5e11c03023264208James Dong#else
36129a84457aed4c45bc900998b5e11c03023264208James Dong                    AVCPrepareCurMB(encvid, cur, pitch);
36229a84457aed4c45bc900998b5e11c03023264208James Dong#endif
36329a84457aed4c45bc900998b5e11c03023264208James Dong                    /************************************************************/
36429a84457aed4c45bc900998b5e11c03023264208James Dong                    /******** full-pel 1MV search **********************/
36529a84457aed4c45bc900998b5e11c03023264208James Dong
36629a84457aed4c45bc900998b5e11c03023264208James Dong                    AVCMBMotionSearch(encvid, cur, best_cand, i << 4, j << 4, type_pred,
36729a84457aed4c45bc900998b5e11c03023264208James Dong                                      FS_en, &hp_guess);
36829a84457aed4c45bc900998b5e11c03023264208James Dong
36929a84457aed4c45bc900998b5e11c03023264208James Dong                    abe_cost = encvid->min_cost[mbnum] = mot_mb_16x16->sad;
37029a84457aed4c45bc900998b5e11c03023264208James Dong
37129a84457aed4c45bc900998b5e11c03023264208James Dong                    /* set mbMode and MVs */
37229a84457aed4c45bc900998b5e11c03023264208James Dong                    currMB->mbMode = AVC_P16;
37329a84457aed4c45bc900998b5e11c03023264208James Dong                    currMB->MBPartPredMode[0][0] = AVC_Pred_L0;
37429a84457aed4c45bc900998b5e11c03023264208James Dong                    mv_uint32 = ((mot_mb_16x16->y) << 16) | ((mot_mb_16x16->x) & 0xffff);
37529a84457aed4c45bc900998b5e11c03023264208James Dong                    for (k = 0; k < 32; k += 2)
37629a84457aed4c45bc900998b5e11c03023264208James Dong                    {
37729a84457aed4c45bc900998b5e11c03023264208James Dong                        currMB->mvL0[k>>1] = mv_uint32;
37829a84457aed4c45bc900998b5e11c03023264208James Dong                    }
37929a84457aed4c45bc900998b5e11c03023264208James Dong
38029a84457aed4c45bc900998b5e11c03023264208James Dong                    /* make a decision whether it should be tested for intra or not */
38129a84457aed4c45bc900998b5e11c03023264208James Dong                    if (i != mbwidth - 1 && j != mbheight - 1 && i != 0 && j != 0)
38229a84457aed4c45bc900998b5e11c03023264208James Dong                    {
38329a84457aed4c45bc900998b5e11c03023264208James Dong                        if (false == IntraDecisionABE(&abe_cost, cur, pitch, true))
38429a84457aed4c45bc900998b5e11c03023264208James Dong                        {
38529a84457aed4c45bc900998b5e11c03023264208James Dong                            intraSearch[mbnum] = 0;
38629a84457aed4c45bc900998b5e11c03023264208James Dong                        }
38729a84457aed4c45bc900998b5e11c03023264208James Dong                        else
38829a84457aed4c45bc900998b5e11c03023264208James Dong                        {
38929a84457aed4c45bc900998b5e11c03023264208James Dong                            NumIntraSearch++;
39029a84457aed4c45bc900998b5e11c03023264208James Dong                            rateCtrl->MADofMB[mbnum] = abe_cost;
39129a84457aed4c45bc900998b5e11c03023264208James Dong                        }
39229a84457aed4c45bc900998b5e11c03023264208James Dong                    }
39329a84457aed4c45bc900998b5e11c03023264208James Dong                    else // boundary MBs, always do intra search
39429a84457aed4c45bc900998b5e11c03023264208James Dong                    {
39529a84457aed4c45bc900998b5e11c03023264208James Dong                        NumIntraSearch++;
39629a84457aed4c45bc900998b5e11c03023264208James Dong                    }
39729a84457aed4c45bc900998b5e11c03023264208James Dong
39829a84457aed4c45bc900998b5e11c03023264208James Dong                    totalSAD += (int) rateCtrl->MADofMB[mbnum];//mot_mb_16x16->sad;
39929a84457aed4c45bc900998b5e11c03023264208James Dong                }
40029a84457aed4c45bc900998b5e11c03023264208James Dong                else    /* INTRA update, use for prediction */
40129a84457aed4c45bc900998b5e11c03023264208James Dong                {
40229a84457aed4c45bc900998b5e11c03023264208James Dong                    mot_mb_16x16[0].x = mot_mb_16x16[0].y = 0;
40329a84457aed4c45bc900998b5e11c03023264208James Dong
40429a84457aed4c45bc900998b5e11c03023264208James Dong                    /* reset all other MVs to zero */
40529a84457aed4c45bc900998b5e11c03023264208James Dong                    /* mot_mb_16x8, mot_mb_8x16, mot_mb_8x8, etc. */
40629a84457aed4c45bc900998b5e11c03023264208James Dong                    abe_cost = encvid->min_cost[mbnum] = 0x7FFFFFFF;  /* max value for int */
40729a84457aed4c45bc900998b5e11c03023264208James Dong
40829a84457aed4c45bc900998b5e11c03023264208James Dong                    if (i != mbwidth - 1 && j != mbheight - 1 && i != 0 && j != 0)
40929a84457aed4c45bc900998b5e11c03023264208James Dong                    {
41029a84457aed4c45bc900998b5e11c03023264208James Dong                        IntraDecisionABE(&abe_cost, cur, pitch, false);
41129a84457aed4c45bc900998b5e11c03023264208James Dong
41229a84457aed4c45bc900998b5e11c03023264208James Dong                        rateCtrl->MADofMB[mbnum] = abe_cost;
41329a84457aed4c45bc900998b5e11c03023264208James Dong                        totalSAD += abe_cost;
41429a84457aed4c45bc900998b5e11c03023264208James Dong                    }
41529a84457aed4c45bc900998b5e11c03023264208James Dong
41629a84457aed4c45bc900998b5e11c03023264208James Dong                    NumIntraSearch++ ;
41729a84457aed4c45bc900998b5e11c03023264208James Dong                    /* cannot do I16 prediction here because it needs full decoding. */
41829a84457aed4c45bc900998b5e11c03023264208James Dong                    // intraSearch[mbnum] = 1;
41929a84457aed4c45bc900998b5e11c03023264208James Dong
42029a84457aed4c45bc900998b5e11c03023264208James Dong                }
42129a84457aed4c45bc900998b5e11c03023264208James Dong
42229a84457aed4c45bc900998b5e11c03023264208James Dong                mbnum += incr_i;
42329a84457aed4c45bc900998b5e11c03023264208James Dong                offset += (incr_i << 4);
42429a84457aed4c45bc900998b5e11c03023264208James Dong
42529a84457aed4c45bc900998b5e11c03023264208James Dong            } /* for i */
42629a84457aed4c45bc900998b5e11c03023264208James Dong        } /* for j */
42729a84457aed4c45bc900998b5e11c03023264208James Dong
42829a84457aed4c45bc900998b5e11c03023264208James Dong        /* since we cannot do intra/inter decision here, the SCD has to be
42929a84457aed4c45bc900998b5e11c03023264208James Dong        based on other criteria such as motion vectors coherency or the SAD */
43029a84457aed4c45bc900998b5e11c03023264208James Dong        if (incr_i > 1 && numLoop) /* scene change on and first loop */
43129a84457aed4c45bc900998b5e11c03023264208James Dong        {
43229a84457aed4c45bc900998b5e11c03023264208James Dong            //if(NumIntraSearch > ((totalMB>>3)<<1) + (totalMB>>3)) /* 75% of 50%MBs */
43329a84457aed4c45bc900998b5e11c03023264208James Dong            if (NumIntraSearch*99 > (48*totalMB)) /* 20% of 50%MBs */
43429a84457aed4c45bc900998b5e11c03023264208James Dong                /* need to do more investigation about this threshold since the NumIntraSearch
43529a84457aed4c45bc900998b5e11c03023264208James Dong                only show potential intra MBs, not the actual one */
43629a84457aed4c45bc900998b5e11c03023264208James Dong            {
43729a84457aed4c45bc900998b5e11c03023264208James Dong                /* we can choose to just encode I_SLICE without IDR */
43829a84457aed4c45bc900998b5e11c03023264208James Dong                //video->nal_unit_type = AVC_NALTYPE_IDR;
43929a84457aed4c45bc900998b5e11c03023264208James Dong                video->nal_unit_type = AVC_NALTYPE_SLICE;
44029a84457aed4c45bc900998b5e11c03023264208James Dong                video->sliceHdr->slice_type = AVC_I_ALL_SLICE;
44129a84457aed4c45bc900998b5e11c03023264208James Dong                video->slice_type = AVC_I_SLICE;
44229a84457aed4c45bc900998b5e11c03023264208James Dong                memset(intraSearch, 1, sizeof(uint8)*totalMB);
44329a84457aed4c45bc900998b5e11c03023264208James Dong                i = totalMB;
44429a84457aed4c45bc900998b5e11c03023264208James Dong                while (i--)
44529a84457aed4c45bc900998b5e11c03023264208James Dong                {
44629a84457aed4c45bc900998b5e11c03023264208James Dong                    mblock[i].mb_intra = 1;
44729a84457aed4c45bc900998b5e11c03023264208James Dong                    encvid->min_cost[i] = 0x7FFFFFFF;  /* max value for int */
44829a84457aed4c45bc900998b5e11c03023264208James Dong                }
44929a84457aed4c45bc900998b5e11c03023264208James Dong
45029a84457aed4c45bc900998b5e11c03023264208James Dong                rateCtrl->totalSAD = totalSAD * 2;  /* SAD */
45129a84457aed4c45bc900998b5e11c03023264208James Dong
45229a84457aed4c45bc900998b5e11c03023264208James Dong                return ;
45329a84457aed4c45bc900998b5e11c03023264208James Dong            }
45429a84457aed4c45bc900998b5e11c03023264208James Dong        }
45529a84457aed4c45bc900998b5e11c03023264208James Dong        /******** no scene change, continue motion search **********************/
45629a84457aed4c45bc900998b5e11c03023264208James Dong        start_i = 0;
45729a84457aed4c45bc900998b5e11c03023264208James Dong        type_pred++; /* second pass */
45829a84457aed4c45bc900998b5e11c03023264208James Dong    }
45929a84457aed4c45bc900998b5e11c03023264208James Dong
46029a84457aed4c45bc900998b5e11c03023264208James Dong    rateCtrl->totalSAD = totalSAD;  /* SAD */
46129a84457aed4c45bc900998b5e11c03023264208James Dong
46229a84457aed4c45bc900998b5e11c03023264208James Dong#ifdef HTFM
46329a84457aed4c45bc900998b5e11c03023264208James Dong    /***** HYPOTHESIS TESTING ********/
46429a84457aed4c45bc900998b5e11c03023264208James Dong    if (collect)
46529a84457aed4c45bc900998b5e11c03023264208James Dong    {
46629a84457aed4c45bc900998b5e11c03023264208James Dong        collect = 0;
46729a84457aed4c45bc900998b5e11c03023264208James Dong        UpdateHTFM(encvid, newvar, exp_lamda, &htfm_stat);
46829a84457aed4c45bc900998b5e11c03023264208James Dong    }
46929a84457aed4c45bc900998b5e11c03023264208James Dong    /*********************************/
47029a84457aed4c45bc900998b5e11c03023264208James Dong#endif
47129a84457aed4c45bc900998b5e11c03023264208James Dong
47229a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
47329a84457aed4c45bc900998b5e11c03023264208James Dong}
47429a84457aed4c45bc900998b5e11c03023264208James Dong
47529a84457aed4c45bc900998b5e11c03023264208James Dong/*=====================================================================
47629a84457aed4c45bc900998b5e11c03023264208James Dong    Function:   PaddingEdge
47729a84457aed4c45bc900998b5e11c03023264208James Dong    Date:       09/16/2000
47829a84457aed4c45bc900998b5e11c03023264208James Dong    Purpose:    Pad edge of a Vop
47929a84457aed4c45bc900998b5e11c03023264208James Dong=====================================================================*/
48029a84457aed4c45bc900998b5e11c03023264208James Dong
48129a84457aed4c45bc900998b5e11c03023264208James Dongvoid  AVCPaddingEdge(AVCPictureData *refPic)
48229a84457aed4c45bc900998b5e11c03023264208James Dong{
48329a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *src, *dst;
48429a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
48529a84457aed4c45bc900998b5e11c03023264208James Dong    int pitch, width, height;
48629a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 temp1, temp2;
48729a84457aed4c45bc900998b5e11c03023264208James Dong
48829a84457aed4c45bc900998b5e11c03023264208James Dong    width = refPic->width;
48929a84457aed4c45bc900998b5e11c03023264208James Dong    height = refPic->height;
49029a84457aed4c45bc900998b5e11c03023264208James Dong    pitch = refPic->pitch;
49129a84457aed4c45bc900998b5e11c03023264208James Dong
49229a84457aed4c45bc900998b5e11c03023264208James Dong    /* pad top */
49329a84457aed4c45bc900998b5e11c03023264208James Dong    src = refPic->Sl;
49429a84457aed4c45bc900998b5e11c03023264208James Dong
49529a84457aed4c45bc900998b5e11c03023264208James Dong    temp1 = *src; /* top-left corner */
49629a84457aed4c45bc900998b5e11c03023264208James Dong    temp2 = src[width-1]; /* top-right corner */
49729a84457aed4c45bc900998b5e11c03023264208James Dong    temp1 |= (temp1 << 8);
49829a84457aed4c45bc900998b5e11c03023264208James Dong    temp1 |= (temp1 << 16);
49929a84457aed4c45bc900998b5e11c03023264208James Dong    temp2 |= (temp2 << 8);
50029a84457aed4c45bc900998b5e11c03023264208James Dong    temp2 |= (temp2 << 16);
50129a84457aed4c45bc900998b5e11c03023264208James Dong
50229a84457aed4c45bc900998b5e11c03023264208James Dong    dst = src - (pitch << 4);
50329a84457aed4c45bc900998b5e11c03023264208James Dong
50429a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst - 16)) = temp1;
50529a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst - 12)) = temp1;
50629a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst - 8)) = temp1;
50729a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst - 4)) = temp1;
50829a84457aed4c45bc900998b5e11c03023264208James Dong
50929a84457aed4c45bc900998b5e11c03023264208James Dong    memcpy(dst, src, width);
51029a84457aed4c45bc900998b5e11c03023264208James Dong
51129a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst += width)) = temp2;
51229a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst + 4)) = temp2;
51329a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst + 8)) = temp2;
51429a84457aed4c45bc900998b5e11c03023264208James Dong    *((uint32*)(dst + 12)) = temp2;
51529a84457aed4c45bc900998b5e11c03023264208James Dong
51629a84457aed4c45bc900998b5e11c03023264208James Dong    dst = dst - width - 16;
51729a84457aed4c45bc900998b5e11c03023264208James Dong
51829a84457aed4c45bc900998b5e11c03023264208James Dong    i = 15;
51929a84457aed4c45bc900998b5e11c03023264208James Dong    while (i--)
52029a84457aed4c45bc900998b5e11c03023264208James Dong    {
52129a84457aed4c45bc900998b5e11c03023264208James Dong        memcpy(dst + pitch, dst, pitch);
52229a84457aed4c45bc900998b5e11c03023264208James Dong        dst += pitch;
52329a84457aed4c45bc900998b5e11c03023264208James Dong    }
52429a84457aed4c45bc900998b5e11c03023264208James Dong
52529a84457aed4c45bc900998b5e11c03023264208James Dong    /* pad sides */
52629a84457aed4c45bc900998b5e11c03023264208James Dong    dst += (pitch + 16);
52729a84457aed4c45bc900998b5e11c03023264208James Dong    src = dst;
52829a84457aed4c45bc900998b5e11c03023264208James Dong    i = height;
52929a84457aed4c45bc900998b5e11c03023264208James Dong    while (i--)
53029a84457aed4c45bc900998b5e11c03023264208James Dong    {
53129a84457aed4c45bc900998b5e11c03023264208James Dong        temp1 = *src;
53229a84457aed4c45bc900998b5e11c03023264208James Dong        temp2 = src[width-1];
53329a84457aed4c45bc900998b5e11c03023264208James Dong        temp1 |= (temp1 << 8);
53429a84457aed4c45bc900998b5e11c03023264208James Dong        temp1 |= (temp1 << 16);
53529a84457aed4c45bc900998b5e11c03023264208James Dong        temp2 |= (temp2 << 8);
53629a84457aed4c45bc900998b5e11c03023264208James Dong        temp2 |= (temp2 << 16);
53729a84457aed4c45bc900998b5e11c03023264208James Dong
53829a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst - 16)) = temp1;
53929a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst - 12)) = temp1;
54029a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst - 8)) = temp1;
54129a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst - 4)) = temp1;
54229a84457aed4c45bc900998b5e11c03023264208James Dong
54329a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst += width)) = temp2;
54429a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst + 4)) = temp2;
54529a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst + 8)) = temp2;
54629a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(dst + 12)) = temp2;
54729a84457aed4c45bc900998b5e11c03023264208James Dong
54829a84457aed4c45bc900998b5e11c03023264208James Dong        src += pitch;
54929a84457aed4c45bc900998b5e11c03023264208James Dong        dst = src;
55029a84457aed4c45bc900998b5e11c03023264208James Dong    }
55129a84457aed4c45bc900998b5e11c03023264208James Dong
55229a84457aed4c45bc900998b5e11c03023264208James Dong    /* pad bottom */
55329a84457aed4c45bc900998b5e11c03023264208James Dong    dst -= 16;
55429a84457aed4c45bc900998b5e11c03023264208James Dong    i = 16;
55529a84457aed4c45bc900998b5e11c03023264208James Dong    while (i--)
55629a84457aed4c45bc900998b5e11c03023264208James Dong    {
55729a84457aed4c45bc900998b5e11c03023264208James Dong        memcpy(dst, dst - pitch, pitch);
55829a84457aed4c45bc900998b5e11c03023264208James Dong        dst += pitch;
55929a84457aed4c45bc900998b5e11c03023264208James Dong    }
56029a84457aed4c45bc900998b5e11c03023264208James Dong
56129a84457aed4c45bc900998b5e11c03023264208James Dong
56229a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
56329a84457aed4c45bc900998b5e11c03023264208James Dong}
56429a84457aed4c45bc900998b5e11c03023264208James Dong
56529a84457aed4c45bc900998b5e11c03023264208James Dong/*===========================================================================
56629a84457aed4c45bc900998b5e11c03023264208James Dong    Function:   AVCRasterIntraUpdate
56729a84457aed4c45bc900998b5e11c03023264208James Dong    Date:       2/26/01
56829a84457aed4c45bc900998b5e11c03023264208James Dong    Purpose:    To raster-scan assign INTRA-update .
56929a84457aed4c45bc900998b5e11c03023264208James Dong                N macroblocks are updated (also was programmable).
57029a84457aed4c45bc900998b5e11c03023264208James Dong===========================================================================*/
57129a84457aed4c45bc900998b5e11c03023264208James Dongvoid AVCRasterIntraUpdate(AVCEncObject *encvid, AVCMacroblock *mblock, int totalMB, int numRefresh)
57229a84457aed4c45bc900998b5e11c03023264208James Dong{
57329a84457aed4c45bc900998b5e11c03023264208James Dong    int indx, i;
57429a84457aed4c45bc900998b5e11c03023264208James Dong
57529a84457aed4c45bc900998b5e11c03023264208James Dong    indx = encvid->firstIntraRefreshMBIndx;
57629a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 0; i < numRefresh && indx < totalMB; i++)
57729a84457aed4c45bc900998b5e11c03023264208James Dong    {
57829a84457aed4c45bc900998b5e11c03023264208James Dong        (mblock + indx)->mb_intra = 1;
57929a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->intraSearch[indx++] = 1;
58029a84457aed4c45bc900998b5e11c03023264208James Dong    }
58129a84457aed4c45bc900998b5e11c03023264208James Dong
58229a84457aed4c45bc900998b5e11c03023264208James Dong    /* if read the end of frame, reset and loop around */
58329a84457aed4c45bc900998b5e11c03023264208James Dong    if (indx >= totalMB - 1)
58429a84457aed4c45bc900998b5e11c03023264208James Dong    {
58529a84457aed4c45bc900998b5e11c03023264208James Dong        indx = 0;
58629a84457aed4c45bc900998b5e11c03023264208James Dong        while (i < numRefresh && indx < totalMB)
58729a84457aed4c45bc900998b5e11c03023264208James Dong        {
58829a84457aed4c45bc900998b5e11c03023264208James Dong            (mblock + indx)->mb_intra = 1;
58929a84457aed4c45bc900998b5e11c03023264208James Dong            encvid->intraSearch[indx++] = 1;
59029a84457aed4c45bc900998b5e11c03023264208James Dong            i++;
59129a84457aed4c45bc900998b5e11c03023264208James Dong        }
59229a84457aed4c45bc900998b5e11c03023264208James Dong    }
59329a84457aed4c45bc900998b5e11c03023264208James Dong
59429a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->firstIntraRefreshMBIndx = indx; /* update with a new value */
59529a84457aed4c45bc900998b5e11c03023264208James Dong
59629a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
59729a84457aed4c45bc900998b5e11c03023264208James Dong}
59829a84457aed4c45bc900998b5e11c03023264208James Dong
59929a84457aed4c45bc900998b5e11c03023264208James Dong
60029a84457aed4c45bc900998b5e11c03023264208James Dong#ifdef HTFM
60129a84457aed4c45bc900998b5e11c03023264208James Dongvoid InitHTFM(VideoEncData *encvid, HTFM_Stat *htfm_stat, double *newvar, int *collect)
60229a84457aed4c45bc900998b5e11c03023264208James Dong{
60329a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
60429a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
60529a84457aed4c45bc900998b5e11c03023264208James Dong    int lx = video->currPic->width; // padding
60629a84457aed4c45bc900998b5e11c03023264208James Dong    int lx2 = lx << 1;
60729a84457aed4c45bc900998b5e11c03023264208James Dong    int lx3 = lx2 + lx;
60829a84457aed4c45bc900998b5e11c03023264208James Dong    int rx = video->currPic->pitch;
60929a84457aed4c45bc900998b5e11c03023264208James Dong    int rx2 = rx << 1;
61029a84457aed4c45bc900998b5e11c03023264208James Dong    int rx3 = rx2 + rx;
61129a84457aed4c45bc900998b5e11c03023264208James Dong
61229a84457aed4c45bc900998b5e11c03023264208James Dong    int *offset, *offset2;
61329a84457aed4c45bc900998b5e11c03023264208James Dong
61429a84457aed4c45bc900998b5e11c03023264208James Dong    /* 4/11/01, collect data every 30 frames, doesn't have to be base layer */
61529a84457aed4c45bc900998b5e11c03023264208James Dong    if (((int)video->sliceHdr->frame_num) % 30 == 1)
61629a84457aed4c45bc900998b5e11c03023264208James Dong    {
61729a84457aed4c45bc900998b5e11c03023264208James Dong
61829a84457aed4c45bc900998b5e11c03023264208James Dong        *collect = 1;
61929a84457aed4c45bc900998b5e11c03023264208James Dong
62029a84457aed4c45bc900998b5e11c03023264208James Dong        htfm_stat->countbreak = 0;
62129a84457aed4c45bc900998b5e11c03023264208James Dong        htfm_stat->abs_dif_mad_avg = 0;
62229a84457aed4c45bc900998b5e11c03023264208James Dong
62329a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 16; i++)
62429a84457aed4c45bc900998b5e11c03023264208James Dong        {
62529a84457aed4c45bc900998b5e11c03023264208James Dong            newvar[i] = 0.0;
62629a84457aed4c45bc900998b5e11c03023264208James Dong        }
62729a84457aed4c45bc900998b5e11c03023264208James Dong//      encvid->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM_Collect;
62829a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_Macroblock = &SAD_MB_HTFM_Collect;
62929a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[0] = NULL;
63029a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFM_Collectxh;
63129a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFM_Collectyh;
63229a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFM_Collectxhyh;
63329a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->sad_extra_info = (void*)(htfm_stat);
63429a84457aed4c45bc900998b5e11c03023264208James Dong        offset = htfm_stat->offsetArray;
63529a84457aed4c45bc900998b5e11c03023264208James Dong        offset2 = htfm_stat->offsetRef;
63629a84457aed4c45bc900998b5e11c03023264208James Dong    }
63729a84457aed4c45bc900998b5e11c03023264208James Dong    else
63829a84457aed4c45bc900998b5e11c03023264208James Dong    {
63929a84457aed4c45bc900998b5e11c03023264208James Dong//      encvid->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM;
64029a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_Macroblock = &SAD_MB_HTFM;
64129a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[0] = NULL;
64229a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFMxh;
64329a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFMyh;
64429a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFMxhyh;
64529a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->sad_extra_info = (void*)(encvid->nrmlz_th);
64629a84457aed4c45bc900998b5e11c03023264208James Dong        offset = encvid->nrmlz_th + 16;
64729a84457aed4c45bc900998b5e11c03023264208James Dong        offset2 = encvid->nrmlz_th + 32;
64829a84457aed4c45bc900998b5e11c03023264208James Dong    }
64929a84457aed4c45bc900998b5e11c03023264208James Dong
65029a84457aed4c45bc900998b5e11c03023264208James Dong    offset[0] = 0;
65129a84457aed4c45bc900998b5e11c03023264208James Dong    offset[1] = lx2 + 2;
65229a84457aed4c45bc900998b5e11c03023264208James Dong    offset[2] = 2;
65329a84457aed4c45bc900998b5e11c03023264208James Dong    offset[3] = lx2;
65429a84457aed4c45bc900998b5e11c03023264208James Dong    offset[4] = lx + 1;
65529a84457aed4c45bc900998b5e11c03023264208James Dong    offset[5] = lx3 + 3;
65629a84457aed4c45bc900998b5e11c03023264208James Dong    offset[6] = lx + 3;
65729a84457aed4c45bc900998b5e11c03023264208James Dong    offset[7] = lx3 + 1;
65829a84457aed4c45bc900998b5e11c03023264208James Dong    offset[8] = lx;
65929a84457aed4c45bc900998b5e11c03023264208James Dong    offset[9] = lx3 + 2;
66029a84457aed4c45bc900998b5e11c03023264208James Dong    offset[10] = lx3 ;
66129a84457aed4c45bc900998b5e11c03023264208James Dong    offset[11] = lx + 2 ;
66229a84457aed4c45bc900998b5e11c03023264208James Dong    offset[12] = 1;
66329a84457aed4c45bc900998b5e11c03023264208James Dong    offset[13] = lx2 + 3;
66429a84457aed4c45bc900998b5e11c03023264208James Dong    offset[14] = lx2 + 1;
66529a84457aed4c45bc900998b5e11c03023264208James Dong    offset[15] = 3;
66629a84457aed4c45bc900998b5e11c03023264208James Dong
66729a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[0] = 0;
66829a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[1] = rx2 + 2;
66929a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[2] = 2;
67029a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[3] = rx2;
67129a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[4] = rx + 1;
67229a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[5] = rx3 + 3;
67329a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[6] = rx + 3;
67429a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[7] = rx3 + 1;
67529a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[8] = rx;
67629a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[9] = rx3 + 2;
67729a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[10] = rx3 ;
67829a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[11] = rx + 2 ;
67929a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[12] = 1;
68029a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[13] = rx2 + 3;
68129a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[14] = rx2 + 1;
68229a84457aed4c45bc900998b5e11c03023264208James Dong    offset2[15] = 3;
68329a84457aed4c45bc900998b5e11c03023264208James Dong
68429a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
68529a84457aed4c45bc900998b5e11c03023264208James Dong}
68629a84457aed4c45bc900998b5e11c03023264208James Dong
68729a84457aed4c45bc900998b5e11c03023264208James Dongvoid UpdateHTFM(AVCEncObject *encvid, double *newvar, double *exp_lamda, HTFM_Stat *htfm_stat)
68829a84457aed4c45bc900998b5e11c03023264208James Dong{
68929a84457aed4c45bc900998b5e11c03023264208James Dong    if (htfm_stat->countbreak == 0)
69029a84457aed4c45bc900998b5e11c03023264208James Dong        htfm_stat->countbreak = 1;
69129a84457aed4c45bc900998b5e11c03023264208James Dong
69229a84457aed4c45bc900998b5e11c03023264208James Dong    newvar[0] = (double)(htfm_stat->abs_dif_mad_avg) / (htfm_stat->countbreak * 16.);
69329a84457aed4c45bc900998b5e11c03023264208James Dong
69429a84457aed4c45bc900998b5e11c03023264208James Dong    if (newvar[0] < 0.001)
69529a84457aed4c45bc900998b5e11c03023264208James Dong    {
69629a84457aed4c45bc900998b5e11c03023264208James Dong        newvar[0] = 0.001; /* to prevent floating overflow */
69729a84457aed4c45bc900998b5e11c03023264208James Dong    }
69829a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[0] =  1 / (newvar[0] * 1.4142136);
69929a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[1] = exp_lamda[0] * 1.5825;
70029a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[2] = exp_lamda[0] * 2.1750;
70129a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[3] = exp_lamda[0] * 3.5065;
70229a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[4] = exp_lamda[0] * 3.1436;
70329a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[5] = exp_lamda[0] * 3.5315;
70429a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[6] = exp_lamda[0] * 3.7449;
70529a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[7] = exp_lamda[0] * 4.5854;
70629a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[8] = exp_lamda[0] * 4.6191;
70729a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[9] = exp_lamda[0] * 5.4041;
70829a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[10] = exp_lamda[0] * 6.5974;
70929a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[11] = exp_lamda[0] * 10.5341;
71029a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[12] = exp_lamda[0] * 10.0719;
71129a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[13] = exp_lamda[0] * 12.0516;
71229a84457aed4c45bc900998b5e11c03023264208James Dong    exp_lamda[14] = exp_lamda[0] * 15.4552;
71329a84457aed4c45bc900998b5e11c03023264208James Dong
71429a84457aed4c45bc900998b5e11c03023264208James Dong    CalcThreshold(HTFM_Pf, exp_lamda, encvid->nrmlz_th);
71529a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
71629a84457aed4c45bc900998b5e11c03023264208James Dong}
71729a84457aed4c45bc900998b5e11c03023264208James Dong
71829a84457aed4c45bc900998b5e11c03023264208James Dong
71929a84457aed4c45bc900998b5e11c03023264208James Dongvoid CalcThreshold(double pf, double exp_lamda[], int nrmlz_th[])
72029a84457aed4c45bc900998b5e11c03023264208James Dong{
72129a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
72229a84457aed4c45bc900998b5e11c03023264208James Dong    double temp[15];
72329a84457aed4c45bc900998b5e11c03023264208James Dong    //  printf("\nLamda: ");
72429a84457aed4c45bc900998b5e11c03023264208James Dong
72529a84457aed4c45bc900998b5e11c03023264208James Dong    /* parametric PREMODELling */
72629a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 0; i < 15; i++)
72729a84457aed4c45bc900998b5e11c03023264208James Dong    {
72829a84457aed4c45bc900998b5e11c03023264208James Dong        //    printf("%g ",exp_lamda[i]);
72929a84457aed4c45bc900998b5e11c03023264208James Dong        if (pf < 0.5)
73029a84457aed4c45bc900998b5e11c03023264208James Dong            temp[i] = 1 / exp_lamda[i] * M4VENC_LOG(2 * pf);
73129a84457aed4c45bc900998b5e11c03023264208James Dong        else
73229a84457aed4c45bc900998b5e11c03023264208James Dong            temp[i] = -1 / exp_lamda[i] * M4VENC_LOG(2 * (1 - pf));
73329a84457aed4c45bc900998b5e11c03023264208James Dong    }
73429a84457aed4c45bc900998b5e11c03023264208James Dong
73529a84457aed4c45bc900998b5e11c03023264208James Dong    nrmlz_th[15] = 0;
73629a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 0; i < 15; i++)        /* scale upto no.pixels */
73729a84457aed4c45bc900998b5e11c03023264208James Dong        nrmlz_th[i] = (int)(temp[i] * ((i + 1) << 4) + 0.5);
73829a84457aed4c45bc900998b5e11c03023264208James Dong
73929a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
74029a84457aed4c45bc900998b5e11c03023264208James Dong}
74129a84457aed4c45bc900998b5e11c03023264208James Dong
74229a84457aed4c45bc900998b5e11c03023264208James Dongvoid    HTFMPrepareCurMB_AVC(AVCEncObject *encvid, HTFM_Stat *htfm_stat, uint8 *cur, int pitch)
74329a84457aed4c45bc900998b5e11c03023264208James Dong{
74429a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
74529a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 *htfmMB = (uint32*)(encvid->currYMB);
74629a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *ptr, byte;
74729a84457aed4c45bc900998b5e11c03023264208James Dong    int *offset;
74829a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
74929a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 word;
75029a84457aed4c45bc900998b5e11c03023264208James Dong
75129a84457aed4c45bc900998b5e11c03023264208James Dong    if (((int)video->sliceHdr->frame_num) % 30 == 1)
75229a84457aed4c45bc900998b5e11c03023264208James Dong    {
75329a84457aed4c45bc900998b5e11c03023264208James Dong        offset = htfm_stat->offsetArray;
75429a84457aed4c45bc900998b5e11c03023264208James Dong    }
75529a84457aed4c45bc900998b5e11c03023264208James Dong    else
75629a84457aed4c45bc900998b5e11c03023264208James Dong    {
75729a84457aed4c45bc900998b5e11c03023264208James Dong        offset = encvid->nrmlz_th + 16;
75829a84457aed4c45bc900998b5e11c03023264208James Dong    }
75929a84457aed4c45bc900998b5e11c03023264208James Dong
76029a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 0; i < 16; i++)
76129a84457aed4c45bc900998b5e11c03023264208James Dong    {
76229a84457aed4c45bc900998b5e11c03023264208James Dong        ptr = cur + offset[i];
76329a84457aed4c45bc900998b5e11c03023264208James Dong        word = ptr[0];
76429a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[4];
76529a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 8);
76629a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[8];
76729a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 16);
76829a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[12];
76929a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 24);
77029a84457aed4c45bc900998b5e11c03023264208James Dong        *htfmMB++ = word;
77129a84457aed4c45bc900998b5e11c03023264208James Dong
77229a84457aed4c45bc900998b5e11c03023264208James Dong        word = *(ptr += (pitch << 2));
77329a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[4];
77429a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 8);
77529a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[8];
77629a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 16);
77729a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[12];
77829a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 24);
77929a84457aed4c45bc900998b5e11c03023264208James Dong        *htfmMB++ = word;
78029a84457aed4c45bc900998b5e11c03023264208James Dong
78129a84457aed4c45bc900998b5e11c03023264208James Dong        word = *(ptr += (pitch << 2));
78229a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[4];
78329a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 8);
78429a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[8];
78529a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 16);
78629a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[12];
78729a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 24);
78829a84457aed4c45bc900998b5e11c03023264208James Dong        *htfmMB++ = word;
78929a84457aed4c45bc900998b5e11c03023264208James Dong
79029a84457aed4c45bc900998b5e11c03023264208James Dong        word = *(ptr += (pitch << 2));
79129a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[4];
79229a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 8);
79329a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[8];
79429a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 16);
79529a84457aed4c45bc900998b5e11c03023264208James Dong        byte = ptr[12];
79629a84457aed4c45bc900998b5e11c03023264208James Dong        word |= (byte << 24);
79729a84457aed4c45bc900998b5e11c03023264208James Dong        *htfmMB++ = word;
79829a84457aed4c45bc900998b5e11c03023264208James Dong    }
79929a84457aed4c45bc900998b5e11c03023264208James Dong
80029a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
80129a84457aed4c45bc900998b5e11c03023264208James Dong}
80229a84457aed4c45bc900998b5e11c03023264208James Dong
80329a84457aed4c45bc900998b5e11c03023264208James Dong
80429a84457aed4c45bc900998b5e11c03023264208James Dong#endif // HTFM
80529a84457aed4c45bc900998b5e11c03023264208James Dong
80629a84457aed4c45bc900998b5e11c03023264208James Dongvoid    AVCPrepareCurMB(AVCEncObject *encvid, uint8 *cur, int pitch)
80729a84457aed4c45bc900998b5e11c03023264208James Dong{
80829a84457aed4c45bc900998b5e11c03023264208James Dong    void* tmp = (void*)(encvid->currYMB);
80929a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 *currYMB = (uint32*) tmp;
81029a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
81129a84457aed4c45bc900998b5e11c03023264208James Dong
81229a84457aed4c45bc900998b5e11c03023264208James Dong    cur -= pitch;
81329a84457aed4c45bc900998b5e11c03023264208James Dong
81429a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 0; i < 16; i++)
81529a84457aed4c45bc900998b5e11c03023264208James Dong    {
81629a84457aed4c45bc900998b5e11c03023264208James Dong        *currYMB++ = *((uint32*)(cur += pitch));
81729a84457aed4c45bc900998b5e11c03023264208James Dong        *currYMB++ = *((uint32*)(cur + 4));
81829a84457aed4c45bc900998b5e11c03023264208James Dong        *currYMB++ = *((uint32*)(cur + 8));
81929a84457aed4c45bc900998b5e11c03023264208James Dong        *currYMB++ = *((uint32*)(cur + 12));
82029a84457aed4c45bc900998b5e11c03023264208James Dong    }
82129a84457aed4c45bc900998b5e11c03023264208James Dong
82229a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
82329a84457aed4c45bc900998b5e11c03023264208James Dong}
82429a84457aed4c45bc900998b5e11c03023264208James Dong
82529a84457aed4c45bc900998b5e11c03023264208James Dong#ifdef FIXED_INTERPRED_MODE
82629a84457aed4c45bc900998b5e11c03023264208James Dong
82729a84457aed4c45bc900998b5e11c03023264208James Dong/* due to the complexity of the predicted motion vector, we may not decide to skip
82829a84457aed4c45bc900998b5e11c03023264208James Donga macroblock here just yet. */
82929a84457aed4c45bc900998b5e11c03023264208James Dong/* We will find the best motion vector and the best intra prediction mode for each block. */
83029a84457aed4c45bc900998b5e11c03023264208James Dong/* output are
83129a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->NumMbPart,  currMB->MbPartWidth, currMB->MbPartHeight,
83229a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->NumSubMbPart[], currMB->SubMbPartWidth[], currMB->SubMbPartHeight,
83329a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->MBPartPredMode[][] (L0 or L1 or BiPred)
83429a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->RefIdx[], currMB->ref_idx_L0[],
83529a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->mvL0[], currMB->mvL1[]
83629a84457aed4c45bc900998b5e11c03023264208James Dong    */
83729a84457aed4c45bc900998b5e11c03023264208James Dong
83829a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status AVCMBMotionSearch(AVCEncObject *encvid, AVCMacroblock *currMB, int mbNum,
83929a84457aed4c45bc900998b5e11c03023264208James Dong                                int num_pass)
84029a84457aed4c45bc900998b5e11c03023264208James Dong{
84129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
84229a84457aed4c45bc900998b5e11c03023264208James Dong    int mbPartIdx, subMbPartIdx;
84329a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *mv;
84429a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
84529a84457aed4c45bc900998b5e11c03023264208James Dong    int SubMbPartHeight, SubMbPartWidth, NumSubMbPart;
84629a84457aed4c45bc900998b5e11c03023264208James Dong
84729a84457aed4c45bc900998b5e11c03023264208James Dong    /* assign value to currMB->MBPartPredMode[][x],subMbMode[],NumSubMbPart[],SubMbPartWidth[],SubMbPartHeight[] */
84829a84457aed4c45bc900998b5e11c03023264208James Dong
84929a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->mbMode = FIXED_INTERPRED_MODE;
85029a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->mb_intra = 0;
85129a84457aed4c45bc900998b5e11c03023264208James Dong
85229a84457aed4c45bc900998b5e11c03023264208James Dong    if (currMB->mbMode == AVC_P16)
85329a84457aed4c45bc900998b5e11c03023264208James Dong    {
85429a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->NumMbPart = 1;
85529a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartWidth = 16;
85629a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartHeight = 16;
85729a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->SubMbPartHeight[0] = 16;
85829a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->SubMbPartWidth[0] = 16;
85929a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->NumSubMbPart[0] =  1;
86029a84457aed4c45bc900998b5e11c03023264208James Dong    }
86129a84457aed4c45bc900998b5e11c03023264208James Dong    else if (currMB->mbMode == AVC_P16x8)
86229a84457aed4c45bc900998b5e11c03023264208James Dong    {
86329a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->NumMbPart = 2;
86429a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartWidth = 16;
86529a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartHeight = 8;
86629a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 2; i++)
86729a84457aed4c45bc900998b5e11c03023264208James Dong        {
86829a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->SubMbPartWidth[i] = 16;
86929a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->SubMbPartHeight[i] = 8;
87029a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->NumSubMbPart[i] = 1;
87129a84457aed4c45bc900998b5e11c03023264208James Dong        }
87229a84457aed4c45bc900998b5e11c03023264208James Dong    }
87329a84457aed4c45bc900998b5e11c03023264208James Dong    else if (currMB->mbMode == AVC_P8x16)
87429a84457aed4c45bc900998b5e11c03023264208James Dong    {
87529a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->NumMbPart = 2;
87629a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartWidth = 8;
87729a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartHeight = 16;
87829a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 2; i++)
87929a84457aed4c45bc900998b5e11c03023264208James Dong        {
88029a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->SubMbPartWidth[i] = 8;
88129a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->SubMbPartHeight[i] = 16;
88229a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->NumSubMbPart[i] = 1;
88329a84457aed4c45bc900998b5e11c03023264208James Dong        }
88429a84457aed4c45bc900998b5e11c03023264208James Dong    }
88529a84457aed4c45bc900998b5e11c03023264208James Dong    else if (currMB->mbMode == AVC_P8 || currMB->mbMode == AVC_P8ref0)
88629a84457aed4c45bc900998b5e11c03023264208James Dong    {
88729a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->NumMbPart = 4;
88829a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartWidth = 8;
88929a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MbPartHeight = 8;
89029a84457aed4c45bc900998b5e11c03023264208James Dong        if (FIXED_SUBMB_MODE == AVC_8x8)
89129a84457aed4c45bc900998b5e11c03023264208James Dong        {
89229a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartHeight = 8;
89329a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartWidth = 8;
89429a84457aed4c45bc900998b5e11c03023264208James Dong            NumSubMbPart = 1;
89529a84457aed4c45bc900998b5e11c03023264208James Dong        }
89629a84457aed4c45bc900998b5e11c03023264208James Dong        else if (FIXED_SUBMB_MODE == AVC_8x4)
89729a84457aed4c45bc900998b5e11c03023264208James Dong        {
89829a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartHeight = 4;
89929a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartWidth = 8;
90029a84457aed4c45bc900998b5e11c03023264208James Dong            NumSubMbPart = 2;
90129a84457aed4c45bc900998b5e11c03023264208James Dong        }
90229a84457aed4c45bc900998b5e11c03023264208James Dong        else if (FIXED_SUBMB_MODE == AVC_4x8)
90329a84457aed4c45bc900998b5e11c03023264208James Dong        {
90429a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartHeight = 8;
90529a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartWidth = 4;
90629a84457aed4c45bc900998b5e11c03023264208James Dong            NumSubMbPart = 2;
90729a84457aed4c45bc900998b5e11c03023264208James Dong        }
90829a84457aed4c45bc900998b5e11c03023264208James Dong        else if (FIXED_SUBMB_MODE == AVC_4x4)
90929a84457aed4c45bc900998b5e11c03023264208James Dong        {
91029a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartHeight = 4;
91129a84457aed4c45bc900998b5e11c03023264208James Dong            SubMbPartWidth = 4;
91229a84457aed4c45bc900998b5e11c03023264208James Dong            NumSubMbPart = 4;
91329a84457aed4c45bc900998b5e11c03023264208James Dong        }
91429a84457aed4c45bc900998b5e11c03023264208James Dong
91529a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 4; i++)
91629a84457aed4c45bc900998b5e11c03023264208James Dong        {
91729a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->subMbMode[i] = FIXED_SUBMB_MODE;
91829a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->SubMbPartHeight[i] = SubMbPartHeight;
91929a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->SubMbPartWidth[i] = SubMbPartWidth;
92029a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->NumSubMbPart[i] = NumSubMbPart;
92129a84457aed4c45bc900998b5e11c03023264208James Dong        }
92229a84457aed4c45bc900998b5e11c03023264208James Dong    }
92329a84457aed4c45bc900998b5e11c03023264208James Dong    else /* it's probably intra mode */
92429a84457aed4c45bc900998b5e11c03023264208James Dong    {
92529a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_SUCCESS;
92629a84457aed4c45bc900998b5e11c03023264208James Dong    }
92729a84457aed4c45bc900998b5e11c03023264208James Dong
92829a84457aed4c45bc900998b5e11c03023264208James Dong    for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
92929a84457aed4c45bc900998b5e11c03023264208James Dong    {
93029a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->MBPartPredMode[mbPartIdx][0]  = AVC_Pred_L0;
93129a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->ref_idx_L0[mbPartIdx] = FIXED_REF_IDX;
93229a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->RefIdx[mbPartIdx] = video->RefPicList0[FIXED_REF_IDX]->RefIdx;
93329a84457aed4c45bc900998b5e11c03023264208James Dong
93429a84457aed4c45bc900998b5e11c03023264208James Dong        for (subMbPartIdx = 0; subMbPartIdx < 4; subMbPartIdx++)
93529a84457aed4c45bc900998b5e11c03023264208James Dong        {
93629a84457aed4c45bc900998b5e11c03023264208James Dong            mv = (int16*)(currMB->mvL0 + (mbPartIdx << 2) + subMbPartIdx);
93729a84457aed4c45bc900998b5e11c03023264208James Dong
93829a84457aed4c45bc900998b5e11c03023264208James Dong            *mv++ = FIXED_MVX;
93929a84457aed4c45bc900998b5e11c03023264208James Dong            *mv = FIXED_MVY;
94029a84457aed4c45bc900998b5e11c03023264208James Dong        }
94129a84457aed4c45bc900998b5e11c03023264208James Dong    }
94229a84457aed4c45bc900998b5e11c03023264208James Dong
94329a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->min_cost = 0;
94429a84457aed4c45bc900998b5e11c03023264208James Dong
94529a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
94629a84457aed4c45bc900998b5e11c03023264208James Dong}
94729a84457aed4c45bc900998b5e11c03023264208James Dong
94829a84457aed4c45bc900998b5e11c03023264208James Dong#else /* perform the search */
94929a84457aed4c45bc900998b5e11c03023264208James Dong
95029a84457aed4c45bc900998b5e11c03023264208James Dong/* This option #1 search is very similar to PV's MPEG4 motion search algorithm.
95129a84457aed4c45bc900998b5e11c03023264208James Dong  The search is done in hierarchical manner from 16x16 MB down to smaller and smaller
95229a84457aed4c45bc900998b5e11c03023264208James Dong  partition. At each level, a decision can be made to stop the search if the expected
95329a84457aed4c45bc900998b5e11c03023264208James Dong  prediction gain is not worth the computation. The decision can also be made at the finest
95429a84457aed4c45bc900998b5e11c03023264208James Dong  level for more fullsearch-like behavior with the price of heavier computation. */
95529a84457aed4c45bc900998b5e11c03023264208James Dongvoid AVCMBMotionSearch(AVCEncObject *encvid, uint8 *cur, uint8 *best_cand[],
95629a84457aed4c45bc900998b5e11c03023264208James Dong                       int i0, int j0, int type_pred, int FS_en, int *hp_guess)
95729a84457aed4c45bc900998b5e11c03023264208James Dong{
95829a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
95929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCPictureData *currPic = video->currPic;
96029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSeqParamSet *currSPS = video->currSeqParams;
96129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCRateControl *rateCtrl = encvid->rateCtrl;
96229a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMacroblock *currMB = video->currMB;
96329a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *ref, *cand, *ncand;
96429a84457aed4c45bc900998b5e11c03023264208James Dong    void *extra_info = encvid->sad_extra_info;
96529a84457aed4c45bc900998b5e11c03023264208James Dong    int mbnum = video->mbNum;
96629a84457aed4c45bc900998b5e11c03023264208James Dong    int width = currPic->width; /* 6/12/01, must be multiple of 16 */
96729a84457aed4c45bc900998b5e11c03023264208James Dong    int height = currPic->height;
96829a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMV *mot16x16 = encvid->mot16x16;
96929a84457aed4c45bc900998b5e11c03023264208James Dong    int (*SAD_Macroblock)(uint8*, uint8*, int, void*) = encvid->functionPointer->SAD_Macroblock;
97029a84457aed4c45bc900998b5e11c03023264208James Dong
97129a84457aed4c45bc900998b5e11c03023264208James Dong    int range = rateCtrl->mvRange;
97229a84457aed4c45bc900998b5e11c03023264208James Dong
97329a84457aed4c45bc900998b5e11c03023264208James Dong    int lx = currPic->pitch; /*  padding */
97429a84457aed4c45bc900998b5e11c03023264208James Dong    int i, j, imin, jmin, ilow, ihigh, jlow, jhigh;
97529a84457aed4c45bc900998b5e11c03023264208James Dong    int d, dmin, dn[9];
97629a84457aed4c45bc900998b5e11c03023264208James Dong    int k;
97729a84457aed4c45bc900998b5e11c03023264208James Dong    int mvx[5], mvy[5];
97829a84457aed4c45bc900998b5e11c03023264208James Dong    int num_can, center_again;
97929a84457aed4c45bc900998b5e11c03023264208James Dong    int last_loc, new_loc = 0;
98029a84457aed4c45bc900998b5e11c03023264208James Dong    int step, max_step = range >> 1;
98129a84457aed4c45bc900998b5e11c03023264208James Dong    int next;
98229a84457aed4c45bc900998b5e11c03023264208James Dong
98329a84457aed4c45bc900998b5e11c03023264208James Dong    int cmvx, cmvy; /* estimated predicted MV */
98429a84457aed4c45bc900998b5e11c03023264208James Dong    int lev_idx;
98529a84457aed4c45bc900998b5e11c03023264208James Dong    int lambda_motion = encvid->lambda_motion;
98629a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *mvbits = encvid->mvbits;
98729a84457aed4c45bc900998b5e11c03023264208James Dong    int mvshift = 2;
98829a84457aed4c45bc900998b5e11c03023264208James Dong    int mvcost;
98929a84457aed4c45bc900998b5e11c03023264208James Dong
99029a84457aed4c45bc900998b5e11c03023264208James Dong    int min_sad = 65535;
99129a84457aed4c45bc900998b5e11c03023264208James Dong
99229a84457aed4c45bc900998b5e11c03023264208James Dong    ref = video->RefPicList0[DEFAULT_REF_IDX]->Sl; /* origin of actual frame */
99329a84457aed4c45bc900998b5e11c03023264208James Dong
99429a84457aed4c45bc900998b5e11c03023264208James Dong    /* have to initialize these params, necessary for interprediction part */
99529a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->NumMbPart = 1;
99629a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->SubMbPartHeight[0] = 16;
99729a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->SubMbPartWidth[0] = 16;
99829a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->NumSubMbPart[0] = 1;
99929a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->ref_idx_L0[0] = currMB->ref_idx_L0[1] =
100029a84457aed4c45bc900998b5e11c03023264208James Dong                                currMB->ref_idx_L0[2] = currMB->ref_idx_L0[3] = DEFAULT_REF_IDX;
100129a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->ref_idx_L1[0] = currMB->ref_idx_L1[1] =
100229a84457aed4c45bc900998b5e11c03023264208James Dong                                currMB->ref_idx_L1[2] = currMB->ref_idx_L1[3] = DEFAULT_REF_IDX;
100329a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->RefIdx[0] = currMB->RefIdx[1] =
100429a84457aed4c45bc900998b5e11c03023264208James Dong                            currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[DEFAULT_REF_IDX]->RefIdx;
100529a84457aed4c45bc900998b5e11c03023264208James Dong
100629a84457aed4c45bc900998b5e11c03023264208James Dong    cur = encvid->currYMB; /* use smaller memory space for current MB */
100729a84457aed4c45bc900998b5e11c03023264208James Dong
100829a84457aed4c45bc900998b5e11c03023264208James Dong    /*  find limit of the search (adjusting search range)*/
100929a84457aed4c45bc900998b5e11c03023264208James Dong    lev_idx = mapLev2Idx[currSPS->level_idc];
101029a84457aed4c45bc900998b5e11c03023264208James Dong
101129a84457aed4c45bc900998b5e11c03023264208James Dong    /* we can make this part dynamic based on previous statistics */
101229a84457aed4c45bc900998b5e11c03023264208James Dong    ilow = i0 - range;
101329a84457aed4c45bc900998b5e11c03023264208James Dong    if (i0 - ilow > 2047) /* clip to conform with the standard */
101429a84457aed4c45bc900998b5e11c03023264208James Dong    {
101529a84457aed4c45bc900998b5e11c03023264208James Dong        ilow = i0 - 2047;
101629a84457aed4c45bc900998b5e11c03023264208James Dong    }
101729a84457aed4c45bc900998b5e11c03023264208James Dong    if (ilow < -13)  // change it from -15 to -13 because of 6-tap filter needs extra 2 lines.
101829a84457aed4c45bc900998b5e11c03023264208James Dong    {
101929a84457aed4c45bc900998b5e11c03023264208James Dong        ilow = -13;
102029a84457aed4c45bc900998b5e11c03023264208James Dong    }
102129a84457aed4c45bc900998b5e11c03023264208James Dong
102229a84457aed4c45bc900998b5e11c03023264208James Dong    ihigh = i0 + range - 1;
102329a84457aed4c45bc900998b5e11c03023264208James Dong    if (ihigh - i0 > 2047) /* clip to conform with the standard */
102429a84457aed4c45bc900998b5e11c03023264208James Dong    {
102529a84457aed4c45bc900998b5e11c03023264208James Dong        ihigh = i0 + 2047;
102629a84457aed4c45bc900998b5e11c03023264208James Dong    }
102729a84457aed4c45bc900998b5e11c03023264208James Dong    if (ihigh > width - 3)
102829a84457aed4c45bc900998b5e11c03023264208James Dong    {
102929a84457aed4c45bc900998b5e11c03023264208James Dong        ihigh = width - 3;  // change from width-1 to width-3 for the same reason as above
103029a84457aed4c45bc900998b5e11c03023264208James Dong    }
103129a84457aed4c45bc900998b5e11c03023264208James Dong
103229a84457aed4c45bc900998b5e11c03023264208James Dong    jlow = j0 - range;
103329a84457aed4c45bc900998b5e11c03023264208James Dong    if (j0 - jlow > MaxVmvR[lev_idx] - 1) /* clip to conform with the standard */
103429a84457aed4c45bc900998b5e11c03023264208James Dong    {
103529a84457aed4c45bc900998b5e11c03023264208James Dong        jlow = j0 - MaxVmvR[lev_idx] + 1;
103629a84457aed4c45bc900998b5e11c03023264208James Dong    }
103729a84457aed4c45bc900998b5e11c03023264208James Dong    if (jlow < -13)     // same reason as above
103829a84457aed4c45bc900998b5e11c03023264208James Dong    {
103929a84457aed4c45bc900998b5e11c03023264208James Dong        jlow = -13;
104029a84457aed4c45bc900998b5e11c03023264208James Dong    }
104129a84457aed4c45bc900998b5e11c03023264208James Dong
104229a84457aed4c45bc900998b5e11c03023264208James Dong    jhigh = j0 + range - 1;
104329a84457aed4c45bc900998b5e11c03023264208James Dong    if (jhigh - j0 > MaxVmvR[lev_idx] - 1) /* clip to conform with the standard */
104429a84457aed4c45bc900998b5e11c03023264208James Dong    {
104529a84457aed4c45bc900998b5e11c03023264208James Dong        jhigh = j0 + MaxVmvR[lev_idx] - 1;
104629a84457aed4c45bc900998b5e11c03023264208James Dong    }
104729a84457aed4c45bc900998b5e11c03023264208James Dong    if (jhigh > height - 3) // same reason as above
104829a84457aed4c45bc900998b5e11c03023264208James Dong    {
104929a84457aed4c45bc900998b5e11c03023264208James Dong        jhigh = height - 3;
105029a84457aed4c45bc900998b5e11c03023264208James Dong    }
105129a84457aed4c45bc900998b5e11c03023264208James Dong
105229a84457aed4c45bc900998b5e11c03023264208James Dong    /* find initial motion vector & predicted MV*/
105329a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCandidateSelection(mvx, mvy, &num_can, i0 >> 4, j0 >> 4, encvid, type_pred, &cmvx, &cmvy);
105429a84457aed4c45bc900998b5e11c03023264208James Dong
105529a84457aed4c45bc900998b5e11c03023264208James Dong    imin = i0;
105629a84457aed4c45bc900998b5e11c03023264208James Dong    jmin = j0; /* needed for fullsearch */
105729a84457aed4c45bc900998b5e11c03023264208James Dong    ncand = ref + i0 + j0 * lx;
105829a84457aed4c45bc900998b5e11c03023264208James Dong
105929a84457aed4c45bc900998b5e11c03023264208James Dong    /* for first row of MB, fullsearch can be used */
106029a84457aed4c45bc900998b5e11c03023264208James Dong    if (FS_en)
106129a84457aed4c45bc900998b5e11c03023264208James Dong    {
106229a84457aed4c45bc900998b5e11c03023264208James Dong        *hp_guess = 0; /* no guess for fast half-pel */
106329a84457aed4c45bc900998b5e11c03023264208James Dong
106429a84457aed4c45bc900998b5e11c03023264208James Dong        dmin =  AVCFullSearch(encvid, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh, cmvx, cmvy);
106529a84457aed4c45bc900998b5e11c03023264208James Dong
106629a84457aed4c45bc900998b5e11c03023264208James Dong        ncand = ref + imin + jmin * lx;
106729a84457aed4c45bc900998b5e11c03023264208James Dong    }
106829a84457aed4c45bc900998b5e11c03023264208James Dong    else
106929a84457aed4c45bc900998b5e11c03023264208James Dong    {   /*       fullsearch the top row to only upto (0,3) MB */
107029a84457aed4c45bc900998b5e11c03023264208James Dong        /*       upto 30% complexity saving with the same complexity */
107129a84457aed4c45bc900998b5e11c03023264208James Dong        if (video->PrevRefFrameNum == 0 && j0 == 0 && i0 <= 64 && type_pred != 1)
107229a84457aed4c45bc900998b5e11c03023264208James Dong        {
107329a84457aed4c45bc900998b5e11c03023264208James Dong            *hp_guess = 0; /* no guess for fast half-pel */
107429a84457aed4c45bc900998b5e11c03023264208James Dong            dmin =  AVCFullSearch(encvid, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh, cmvx, cmvy);
107529a84457aed4c45bc900998b5e11c03023264208James Dong            ncand = ref + imin + jmin * lx;
107629a84457aed4c45bc900998b5e11c03023264208James Dong        }
107729a84457aed4c45bc900998b5e11c03023264208James Dong        else
107829a84457aed4c45bc900998b5e11c03023264208James Dong        {
107929a84457aed4c45bc900998b5e11c03023264208James Dong            /************** initialize candidate **************************/
108029a84457aed4c45bc900998b5e11c03023264208James Dong
108129a84457aed4c45bc900998b5e11c03023264208James Dong            dmin = 65535;
108229a84457aed4c45bc900998b5e11c03023264208James Dong
108329a84457aed4c45bc900998b5e11c03023264208James Dong            /* check if all are equal */
108429a84457aed4c45bc900998b5e11c03023264208James Dong            if (num_can == ALL_CAND_EQUAL)
108529a84457aed4c45bc900998b5e11c03023264208James Dong            {
108629a84457aed4c45bc900998b5e11c03023264208James Dong                i = i0 + mvx[0];
108729a84457aed4c45bc900998b5e11c03023264208James Dong                j = j0 + mvy[0];
108829a84457aed4c45bc900998b5e11c03023264208James Dong
108929a84457aed4c45bc900998b5e11c03023264208James Dong                if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
109029a84457aed4c45bc900998b5e11c03023264208James Dong                {
109129a84457aed4c45bc900998b5e11c03023264208James Dong                    cand = ref + i + j * lx;
109229a84457aed4c45bc900998b5e11c03023264208James Dong
109329a84457aed4c45bc900998b5e11c03023264208James Dong                    d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
109429a84457aed4c45bc900998b5e11c03023264208James Dong                    mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy);
109529a84457aed4c45bc900998b5e11c03023264208James Dong                    d +=  mvcost;
109629a84457aed4c45bc900998b5e11c03023264208James Dong
109729a84457aed4c45bc900998b5e11c03023264208James Dong                    if (d < dmin)
109829a84457aed4c45bc900998b5e11c03023264208James Dong                    {
109929a84457aed4c45bc900998b5e11c03023264208James Dong                        dmin = d;
110029a84457aed4c45bc900998b5e11c03023264208James Dong                        imin = i;
110129a84457aed4c45bc900998b5e11c03023264208James Dong                        jmin = j;
110229a84457aed4c45bc900998b5e11c03023264208James Dong                        ncand = cand;
110329a84457aed4c45bc900998b5e11c03023264208James Dong                        min_sad = d - mvcost; // for rate control
110429a84457aed4c45bc900998b5e11c03023264208James Dong                    }
110529a84457aed4c45bc900998b5e11c03023264208James Dong                }
110629a84457aed4c45bc900998b5e11c03023264208James Dong            }
110729a84457aed4c45bc900998b5e11c03023264208James Dong            else
110829a84457aed4c45bc900998b5e11c03023264208James Dong            {
110929a84457aed4c45bc900998b5e11c03023264208James Dong                /************** evaluate unique candidates **********************/
111029a84457aed4c45bc900998b5e11c03023264208James Dong                for (k = 0; k < num_can; k++)
111129a84457aed4c45bc900998b5e11c03023264208James Dong                {
111229a84457aed4c45bc900998b5e11c03023264208James Dong                    i = i0 + mvx[k];
111329a84457aed4c45bc900998b5e11c03023264208James Dong                    j = j0 + mvy[k];
111429a84457aed4c45bc900998b5e11c03023264208James Dong
111529a84457aed4c45bc900998b5e11c03023264208James Dong                    if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
111629a84457aed4c45bc900998b5e11c03023264208James Dong                    {
111729a84457aed4c45bc900998b5e11c03023264208James Dong                        cand = ref + i + j * lx;
111829a84457aed4c45bc900998b5e11c03023264208James Dong                        d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
111929a84457aed4c45bc900998b5e11c03023264208James Dong                        mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy);
112029a84457aed4c45bc900998b5e11c03023264208James Dong                        d +=  mvcost;
112129a84457aed4c45bc900998b5e11c03023264208James Dong
112229a84457aed4c45bc900998b5e11c03023264208James Dong                        if (d < dmin)
112329a84457aed4c45bc900998b5e11c03023264208James Dong                        {
112429a84457aed4c45bc900998b5e11c03023264208James Dong                            dmin = d;
112529a84457aed4c45bc900998b5e11c03023264208James Dong                            imin = i;
112629a84457aed4c45bc900998b5e11c03023264208James Dong                            jmin = j;
112729a84457aed4c45bc900998b5e11c03023264208James Dong                            ncand = cand;
112829a84457aed4c45bc900998b5e11c03023264208James Dong                            min_sad = d - mvcost; // for rate control
112929a84457aed4c45bc900998b5e11c03023264208James Dong                        }
113029a84457aed4c45bc900998b5e11c03023264208James Dong                    }
113129a84457aed4c45bc900998b5e11c03023264208James Dong                }
113229a84457aed4c45bc900998b5e11c03023264208James Dong            }
113329a84457aed4c45bc900998b5e11c03023264208James Dong
113429a84457aed4c45bc900998b5e11c03023264208James Dong            /******************* local refinement ***************************/
113529a84457aed4c45bc900998b5e11c03023264208James Dong            center_again = 0;
113629a84457aed4c45bc900998b5e11c03023264208James Dong            last_loc = new_loc = 0;
113729a84457aed4c45bc900998b5e11c03023264208James Dong            //          ncand = ref + jmin*lx + imin;  /* center of the search */
113829a84457aed4c45bc900998b5e11c03023264208James Dong            step = 0;
113929a84457aed4c45bc900998b5e11c03023264208James Dong            dn[0] = dmin;
114029a84457aed4c45bc900998b5e11c03023264208James Dong            while (!center_again && step <= max_step)
114129a84457aed4c45bc900998b5e11c03023264208James Dong            {
114229a84457aed4c45bc900998b5e11c03023264208James Dong
114329a84457aed4c45bc900998b5e11c03023264208James Dong                AVCMoveNeighborSAD(dn, last_loc);
114429a84457aed4c45bc900998b5e11c03023264208James Dong
114529a84457aed4c45bc900998b5e11c03023264208James Dong                center_again = 1;
114629a84457aed4c45bc900998b5e11c03023264208James Dong                i = imin;
114729a84457aed4c45bc900998b5e11c03023264208James Dong                j = jmin - 1;
114829a84457aed4c45bc900998b5e11c03023264208James Dong                cand = ref + i + j * lx;
114929a84457aed4c45bc900998b5e11c03023264208James Dong
115029a84457aed4c45bc900998b5e11c03023264208James Dong                /*  starting from [0,-1] */
115129a84457aed4c45bc900998b5e11c03023264208James Dong                /* spiral check one step at a time*/
115229a84457aed4c45bc900998b5e11c03023264208James Dong                for (k = 2; k <= 8; k += 2)
115329a84457aed4c45bc900998b5e11c03023264208James Dong                {
115429a84457aed4c45bc900998b5e11c03023264208James Dong                    if (!tab_exclude[last_loc][k]) /* exclude last step computation */
115529a84457aed4c45bc900998b5e11c03023264208James Dong                    {       /* not already computed */
115629a84457aed4c45bc900998b5e11c03023264208James Dong                        if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
115729a84457aed4c45bc900998b5e11c03023264208James Dong                        {
115829a84457aed4c45bc900998b5e11c03023264208James Dong                            d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info);
115929a84457aed4c45bc900998b5e11c03023264208James Dong                            mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy);
116029a84457aed4c45bc900998b5e11c03023264208James Dong                            d += mvcost;
116129a84457aed4c45bc900998b5e11c03023264208James Dong
116229a84457aed4c45bc900998b5e11c03023264208James Dong                            dn[k] = d; /* keep it for half pel use */
116329a84457aed4c45bc900998b5e11c03023264208James Dong
116429a84457aed4c45bc900998b5e11c03023264208James Dong                            if (d < dmin)
116529a84457aed4c45bc900998b5e11c03023264208James Dong                            {
116629a84457aed4c45bc900998b5e11c03023264208James Dong                                ncand = cand;
116729a84457aed4c45bc900998b5e11c03023264208James Dong                                dmin = d;
116829a84457aed4c45bc900998b5e11c03023264208James Dong                                imin = i;
116929a84457aed4c45bc900998b5e11c03023264208James Dong                                jmin = j;
117029a84457aed4c45bc900998b5e11c03023264208James Dong                                center_again = 0;
117129a84457aed4c45bc900998b5e11c03023264208James Dong                                new_loc = k;
117229a84457aed4c45bc900998b5e11c03023264208James Dong                                min_sad = d - mvcost; // for rate control
117329a84457aed4c45bc900998b5e11c03023264208James Dong                            }
117429a84457aed4c45bc900998b5e11c03023264208James Dong                        }
117529a84457aed4c45bc900998b5e11c03023264208James Dong                    }
117629a84457aed4c45bc900998b5e11c03023264208James Dong                    if (k == 8)  /* end side search*/
117729a84457aed4c45bc900998b5e11c03023264208James Dong                    {
117829a84457aed4c45bc900998b5e11c03023264208James Dong                        if (!center_again)
117929a84457aed4c45bc900998b5e11c03023264208James Dong                        {
118029a84457aed4c45bc900998b5e11c03023264208James Dong                            k = -1; /* start diagonal search */
118129a84457aed4c45bc900998b5e11c03023264208James Dong                            cand -= lx;
118229a84457aed4c45bc900998b5e11c03023264208James Dong                            j--;
118329a84457aed4c45bc900998b5e11c03023264208James Dong                        }
118429a84457aed4c45bc900998b5e11c03023264208James Dong                    }
118529a84457aed4c45bc900998b5e11c03023264208James Dong                    else
118629a84457aed4c45bc900998b5e11c03023264208James Dong                    {
118729a84457aed4c45bc900998b5e11c03023264208James Dong                        next = refine_next[k][0];
118829a84457aed4c45bc900998b5e11c03023264208James Dong                        i += next;
118929a84457aed4c45bc900998b5e11c03023264208James Dong                        cand += next;
119029a84457aed4c45bc900998b5e11c03023264208James Dong                        next = refine_next[k][1];
119129a84457aed4c45bc900998b5e11c03023264208James Dong                        j += next;
119229a84457aed4c45bc900998b5e11c03023264208James Dong                        cand += lx * next;
119329a84457aed4c45bc900998b5e11c03023264208James Dong                    }
119429a84457aed4c45bc900998b5e11c03023264208James Dong                }
119529a84457aed4c45bc900998b5e11c03023264208James Dong                last_loc = new_loc;
119629a84457aed4c45bc900998b5e11c03023264208James Dong                step ++;
119729a84457aed4c45bc900998b5e11c03023264208James Dong            }
119829a84457aed4c45bc900998b5e11c03023264208James Dong            if (!center_again)
119929a84457aed4c45bc900998b5e11c03023264208James Dong                AVCMoveNeighborSAD(dn, last_loc);
120029a84457aed4c45bc900998b5e11c03023264208James Dong
120129a84457aed4c45bc900998b5e11c03023264208James Dong            *hp_guess = AVCFindMin(dn);
120229a84457aed4c45bc900998b5e11c03023264208James Dong
120329a84457aed4c45bc900998b5e11c03023264208James Dong            encvid->rateCtrl->MADofMB[mbnum] = min_sad / 256.0;
120429a84457aed4c45bc900998b5e11c03023264208James Dong        }
120529a84457aed4c45bc900998b5e11c03023264208James Dong    }
120629a84457aed4c45bc900998b5e11c03023264208James Dong
120729a84457aed4c45bc900998b5e11c03023264208James Dong    mot16x16[mbnum].sad = dmin;
120829a84457aed4c45bc900998b5e11c03023264208James Dong    mot16x16[mbnum].x = (imin - i0) << 2;
120929a84457aed4c45bc900998b5e11c03023264208James Dong    mot16x16[mbnum].y = (jmin - j0) << 2;
121029a84457aed4c45bc900998b5e11c03023264208James Dong    best_cand[0] = ncand;
121129a84457aed4c45bc900998b5e11c03023264208James Dong
121229a84457aed4c45bc900998b5e11c03023264208James Dong    if (rateCtrl->subPelEnable) // always enable half-pel search
121329a84457aed4c45bc900998b5e11c03023264208James Dong    {
121429a84457aed4c45bc900998b5e11c03023264208James Dong        /* find half-pel resolution motion vector */
121529a84457aed4c45bc900998b5e11c03023264208James Dong        min_sad = AVCFindHalfPelMB(encvid, cur, mot16x16 + mbnum, best_cand[0], i0, j0, *hp_guess, cmvx, cmvy);
121629a84457aed4c45bc900998b5e11c03023264208James Dong
121729a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->rateCtrl->MADofMB[mbnum] = min_sad / 256.0;
121829a84457aed4c45bc900998b5e11c03023264208James Dong
121929a84457aed4c45bc900998b5e11c03023264208James Dong
122029a84457aed4c45bc900998b5e11c03023264208James Dong        if (encvid->best_qpel_pos == -1)
122129a84457aed4c45bc900998b5e11c03023264208James Dong        {
122229a84457aed4c45bc900998b5e11c03023264208James Dong            ncand = encvid->hpel_cand[encvid->best_hpel_pos];
122329a84457aed4c45bc900998b5e11c03023264208James Dong        }
122429a84457aed4c45bc900998b5e11c03023264208James Dong        else
122529a84457aed4c45bc900998b5e11c03023264208James Dong        {
122629a84457aed4c45bc900998b5e11c03023264208James Dong            ncand = encvid->qpel_cand[encvid->best_qpel_pos];
122729a84457aed4c45bc900998b5e11c03023264208James Dong        }
122829a84457aed4c45bc900998b5e11c03023264208James Dong    }
122929a84457aed4c45bc900998b5e11c03023264208James Dong    else
123029a84457aed4c45bc900998b5e11c03023264208James Dong    {
123129a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->rateCtrl->MADofMB[mbnum] = min_sad / 256.0;
123229a84457aed4c45bc900998b5e11c03023264208James Dong    }
123329a84457aed4c45bc900998b5e11c03023264208James Dong
123429a84457aed4c45bc900998b5e11c03023264208James Dong    /** do motion comp here for now */
123529a84457aed4c45bc900998b5e11c03023264208James Dong    ref = currPic->Sl + i0 + j0 * lx;
123629a84457aed4c45bc900998b5e11c03023264208James Dong    /* copy from the best result to current Picture */
123729a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 0; j < 16; j++)
123829a84457aed4c45bc900998b5e11c03023264208James Dong    {
123929a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 16; i++)
124029a84457aed4c45bc900998b5e11c03023264208James Dong        {
124129a84457aed4c45bc900998b5e11c03023264208James Dong            *ref++ = *ncand++;
124229a84457aed4c45bc900998b5e11c03023264208James Dong        }
124329a84457aed4c45bc900998b5e11c03023264208James Dong        ref += (lx - 16);
124429a84457aed4c45bc900998b5e11c03023264208James Dong        ncand += 8;
124529a84457aed4c45bc900998b5e11c03023264208James Dong    }
124629a84457aed4c45bc900998b5e11c03023264208James Dong
124729a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
124829a84457aed4c45bc900998b5e11c03023264208James Dong}
124929a84457aed4c45bc900998b5e11c03023264208James Dong
125029a84457aed4c45bc900998b5e11c03023264208James Dong#endif
125129a84457aed4c45bc900998b5e11c03023264208James Dong
125229a84457aed4c45bc900998b5e11c03023264208James Dong/*===============================================================================
125329a84457aed4c45bc900998b5e11c03023264208James Dong    Function:   AVCFullSearch
125429a84457aed4c45bc900998b5e11c03023264208James Dong    Date:       09/16/2000
125529a84457aed4c45bc900998b5e11c03023264208James Dong    Purpose:    Perform full-search motion estimation over the range of search
125629a84457aed4c45bc900998b5e11c03023264208James Dong                region in a spiral-outward manner.
125729a84457aed4c45bc900998b5e11c03023264208James Dong    Input/Output:   VideoEncData, current Vol, previou Vop, pointer to the left corner of
125829a84457aed4c45bc900998b5e11c03023264208James Dong                current VOP, current coord (also output), boundaries.
125929a84457aed4c45bc900998b5e11c03023264208James Dong===============================================================================*/
126029a84457aed4c45bc900998b5e11c03023264208James Dongint AVCFullSearch(AVCEncObject *encvid, uint8 *prev, uint8 *cur,
126129a84457aed4c45bc900998b5e11c03023264208James Dong                  int *imin, int *jmin, int ilow, int ihigh, int jlow, int jhigh,
126229a84457aed4c45bc900998b5e11c03023264208James Dong                  int cmvx, int cmvy)
126329a84457aed4c45bc900998b5e11c03023264208James Dong{
126429a84457aed4c45bc900998b5e11c03023264208James Dong    int range = encvid->rateCtrl->mvRange;
126529a84457aed4c45bc900998b5e11c03023264208James Dong    AVCPictureData *currPic = encvid->common->currPic;
126629a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *cand;
126729a84457aed4c45bc900998b5e11c03023264208James Dong    int i, j, k, l;
126829a84457aed4c45bc900998b5e11c03023264208James Dong    int d, dmin;
126929a84457aed4c45bc900998b5e11c03023264208James Dong    int i0 = *imin; /* current position */
127029a84457aed4c45bc900998b5e11c03023264208James Dong    int j0 = *jmin;
127129a84457aed4c45bc900998b5e11c03023264208James Dong    int (*SAD_Macroblock)(uint8*, uint8*, int, void*) = encvid->functionPointer->SAD_Macroblock;
127229a84457aed4c45bc900998b5e11c03023264208James Dong    void *extra_info = encvid->sad_extra_info;
127329a84457aed4c45bc900998b5e11c03023264208James Dong    int lx = currPic->pitch; /* with padding */
127429a84457aed4c45bc900998b5e11c03023264208James Dong
127529a84457aed4c45bc900998b5e11c03023264208James Dong    int offset = i0 + j0 * lx;
127629a84457aed4c45bc900998b5e11c03023264208James Dong
127729a84457aed4c45bc900998b5e11c03023264208James Dong    int lambda_motion = encvid->lambda_motion;
127829a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *mvbits = encvid->mvbits;
127929a84457aed4c45bc900998b5e11c03023264208James Dong    int mvshift = 2;
128029a84457aed4c45bc900998b5e11c03023264208James Dong    int mvcost;
128129a84457aed4c45bc900998b5e11c03023264208James Dong    int min_sad;
128229a84457aed4c45bc900998b5e11c03023264208James Dong
128329a84457aed4c45bc900998b5e11c03023264208James Dong    cand = prev + offset;
128429a84457aed4c45bc900998b5e11c03023264208James Dong
128529a84457aed4c45bc900998b5e11c03023264208James Dong    dmin  = (*SAD_Macroblock)(cand, cur, (65535 << 16) | lx, (void*)extra_info);
128629a84457aed4c45bc900998b5e11c03023264208James Dong    mvcost = MV_COST(lambda_motion, mvshift, 0, 0, cmvx, cmvy);
128729a84457aed4c45bc900998b5e11c03023264208James Dong    min_sad = dmin;
128829a84457aed4c45bc900998b5e11c03023264208James Dong    dmin += mvcost;
128929a84457aed4c45bc900998b5e11c03023264208James Dong
129029a84457aed4c45bc900998b5e11c03023264208James Dong    /* perform spiral search */
129129a84457aed4c45bc900998b5e11c03023264208James Dong    for (k = 1; k <= range; k++)
129229a84457aed4c45bc900998b5e11c03023264208James Dong    {
129329a84457aed4c45bc900998b5e11c03023264208James Dong
129429a84457aed4c45bc900998b5e11c03023264208James Dong        i = i0 - k;
129529a84457aed4c45bc900998b5e11c03023264208James Dong        j = j0 - k;
129629a84457aed4c45bc900998b5e11c03023264208James Dong
129729a84457aed4c45bc900998b5e11c03023264208James Dong        cand = prev + i + j * lx;
129829a84457aed4c45bc900998b5e11c03023264208James Dong
129929a84457aed4c45bc900998b5e11c03023264208James Dong        for (l = 0; l < 8*k; l++)
130029a84457aed4c45bc900998b5e11c03023264208James Dong        {
130129a84457aed4c45bc900998b5e11c03023264208James Dong            /* no need for boundary checking again */
130229a84457aed4c45bc900998b5e11c03023264208James Dong            if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh)
130329a84457aed4c45bc900998b5e11c03023264208James Dong            {
130429a84457aed4c45bc900998b5e11c03023264208James Dong                d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, (void*)extra_info);
130529a84457aed4c45bc900998b5e11c03023264208James Dong                mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy);
130629a84457aed4c45bc900998b5e11c03023264208James Dong                d +=  mvcost;
130729a84457aed4c45bc900998b5e11c03023264208James Dong
130829a84457aed4c45bc900998b5e11c03023264208James Dong                if (d < dmin)
130929a84457aed4c45bc900998b5e11c03023264208James Dong                {
131029a84457aed4c45bc900998b5e11c03023264208James Dong                    dmin = d;
131129a84457aed4c45bc900998b5e11c03023264208James Dong                    *imin = i;
131229a84457aed4c45bc900998b5e11c03023264208James Dong                    *jmin = j;
131329a84457aed4c45bc900998b5e11c03023264208James Dong                    min_sad = d - mvcost;
131429a84457aed4c45bc900998b5e11c03023264208James Dong                }
131529a84457aed4c45bc900998b5e11c03023264208James Dong            }
131629a84457aed4c45bc900998b5e11c03023264208James Dong
131729a84457aed4c45bc900998b5e11c03023264208James Dong            if (l < (k << 1))
131829a84457aed4c45bc900998b5e11c03023264208James Dong            {
131929a84457aed4c45bc900998b5e11c03023264208James Dong                i++;
132029a84457aed4c45bc900998b5e11c03023264208James Dong                cand++;
132129a84457aed4c45bc900998b5e11c03023264208James Dong            }
132229a84457aed4c45bc900998b5e11c03023264208James Dong            else if (l < (k << 2))
132329a84457aed4c45bc900998b5e11c03023264208James Dong            {
132429a84457aed4c45bc900998b5e11c03023264208James Dong                j++;
132529a84457aed4c45bc900998b5e11c03023264208James Dong                cand += lx;
132629a84457aed4c45bc900998b5e11c03023264208James Dong            }
132729a84457aed4c45bc900998b5e11c03023264208James Dong            else if (l < ((k << 2) + (k << 1)))
132829a84457aed4c45bc900998b5e11c03023264208James Dong            {
132929a84457aed4c45bc900998b5e11c03023264208James Dong                i--;
133029a84457aed4c45bc900998b5e11c03023264208James Dong                cand--;
133129a84457aed4c45bc900998b5e11c03023264208James Dong            }
133229a84457aed4c45bc900998b5e11c03023264208James Dong            else
133329a84457aed4c45bc900998b5e11c03023264208James Dong            {
133429a84457aed4c45bc900998b5e11c03023264208James Dong                j--;
133529a84457aed4c45bc900998b5e11c03023264208James Dong                cand -= lx;
133629a84457aed4c45bc900998b5e11c03023264208James Dong            }
133729a84457aed4c45bc900998b5e11c03023264208James Dong        }
133829a84457aed4c45bc900998b5e11c03023264208James Dong    }
133929a84457aed4c45bc900998b5e11c03023264208James Dong
134029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->rateCtrl->MADofMB[encvid->common->mbNum] = (min_sad / 256.0); // for rate control
134129a84457aed4c45bc900998b5e11c03023264208James Dong
134229a84457aed4c45bc900998b5e11c03023264208James Dong    return dmin;
134329a84457aed4c45bc900998b5e11c03023264208James Dong}
134429a84457aed4c45bc900998b5e11c03023264208James Dong
134529a84457aed4c45bc900998b5e11c03023264208James Dong/*===============================================================================
134629a84457aed4c45bc900998b5e11c03023264208James Dong    Function:   AVCCandidateSelection
134729a84457aed4c45bc900998b5e11c03023264208James Dong    Date:       09/16/2000
134829a84457aed4c45bc900998b5e11c03023264208James Dong    Purpose:    Fill up the list of candidate using spatio-temporal correlation
134929a84457aed4c45bc900998b5e11c03023264208James Dong                among neighboring blocks.
135029a84457aed4c45bc900998b5e11c03023264208James Dong    Input/Output:   type_pred = 0: first pass, 1: second pass, or no SCD
135129a84457aed4c45bc900998b5e11c03023264208James Dong    Modified:   , 09/23/01, get rid of redundant candidates before passing back.
135229a84457aed4c45bc900998b5e11c03023264208James Dong                , 09/11/07, added return for modified predicted MV, this will be
135329a84457aed4c45bc900998b5e11c03023264208James Dong                    needed for both fast search and fullsearch.
135429a84457aed4c45bc900998b5e11c03023264208James Dong===============================================================================*/
135529a84457aed4c45bc900998b5e11c03023264208James Dong
135629a84457aed4c45bc900998b5e11c03023264208James Dongvoid AVCCandidateSelection(int *mvx, int *mvy, int *num_can, int imb, int jmb,
135729a84457aed4c45bc900998b5e11c03023264208James Dong                           AVCEncObject *encvid, int type_pred, int *cmvx, int *cmvy)
135829a84457aed4c45bc900998b5e11c03023264208James Dong{
135929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
136029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMV *mot16x16 = encvid->mot16x16;
136129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMV *pmot;
136229a84457aed4c45bc900998b5e11c03023264208James Dong    int mbnum = video->mbNum;
136329a84457aed4c45bc900998b5e11c03023264208James Dong    int mbwidth = video->PicWidthInMbs;
136429a84457aed4c45bc900998b5e11c03023264208James Dong    int mbheight = video->PicHeightInMbs;
136529a84457aed4c45bc900998b5e11c03023264208James Dong    int i, j, same, num1;
136629a84457aed4c45bc900998b5e11c03023264208James Dong
136729a84457aed4c45bc900998b5e11c03023264208James Dong    /* this part is for predicted MV */
136829a84457aed4c45bc900998b5e11c03023264208James Dong    int pmvA_x = 0, pmvA_y = 0, pmvB_x = 0, pmvB_y = 0, pmvC_x = 0, pmvC_y = 0;
136929a84457aed4c45bc900998b5e11c03023264208James Dong    int availA = 0, availB = 0, availC = 0;
137029a84457aed4c45bc900998b5e11c03023264208James Dong
137129a84457aed4c45bc900998b5e11c03023264208James Dong    *num_can = 0;
137229a84457aed4c45bc900998b5e11c03023264208James Dong
137329a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->PrevRefFrameNum != 0) // previous frame is an IDR frame
137429a84457aed4c45bc900998b5e11c03023264208James Dong    {
137529a84457aed4c45bc900998b5e11c03023264208James Dong        /* Spatio-Temporal Candidate (five candidates) */
137629a84457aed4c45bc900998b5e11c03023264208James Dong        if (type_pred == 0) /* first pass */
137729a84457aed4c45bc900998b5e11c03023264208James Dong        {
137829a84457aed4c45bc900998b5e11c03023264208James Dong            pmot = &mot16x16[mbnum]; /* same coordinate previous frame */
137929a84457aed4c45bc900998b5e11c03023264208James Dong            mvx[(*num_can)] = (pmot->x) >> 2;
138029a84457aed4c45bc900998b5e11c03023264208James Dong            mvy[(*num_can)++] = (pmot->y) >> 2;
138129a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb >= (mbwidth >> 1) && imb > 0)  /*left neighbor previous frame */
138229a84457aed4c45bc900998b5e11c03023264208James Dong            {
138329a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-1];
138429a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
138529a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
138629a84457aed4c45bc900998b5e11c03023264208James Dong            }
138729a84457aed4c45bc900998b5e11c03023264208James Dong            else if (imb + 1 < mbwidth)   /*right neighbor previous frame */
138829a84457aed4c45bc900998b5e11c03023264208James Dong            {
138929a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum+1];
139029a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
139129a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
139229a84457aed4c45bc900998b5e11c03023264208James Dong            }
139329a84457aed4c45bc900998b5e11c03023264208James Dong
139429a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb < mbheight - 1)  /*bottom neighbor previous frame */
139529a84457aed4c45bc900998b5e11c03023264208James Dong            {
139629a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum+mbwidth];
139729a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
139829a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
139929a84457aed4c45bc900998b5e11c03023264208James Dong            }
140029a84457aed4c45bc900998b5e11c03023264208James Dong            else if (jmb > 0)   /*upper neighbor previous frame */
140129a84457aed4c45bc900998b5e11c03023264208James Dong            {
140229a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth];
140329a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
140429a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
140529a84457aed4c45bc900998b5e11c03023264208James Dong            }
140629a84457aed4c45bc900998b5e11c03023264208James Dong
140729a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb > 0 && jmb > 0)  /* upper-left neighbor current frame*/
140829a84457aed4c45bc900998b5e11c03023264208James Dong            {
140929a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth-1];
141029a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
141129a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
141229a84457aed4c45bc900998b5e11c03023264208James Dong            }
141329a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb > 0 && imb < mbheight - 1)  /* upper right neighbor current frame*/
141429a84457aed4c45bc900998b5e11c03023264208James Dong            {
141529a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth+1];
141629a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
141729a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
141829a84457aed4c45bc900998b5e11c03023264208James Dong            }
141929a84457aed4c45bc900998b5e11c03023264208James Dong        }
142029a84457aed4c45bc900998b5e11c03023264208James Dong        else    /* second pass */
142129a84457aed4c45bc900998b5e11c03023264208James Dong            /* original ST1 algorithm */
142229a84457aed4c45bc900998b5e11c03023264208James Dong        {
142329a84457aed4c45bc900998b5e11c03023264208James Dong            pmot = &mot16x16[mbnum]; /* same coordinate previous frame */
142429a84457aed4c45bc900998b5e11c03023264208James Dong            mvx[(*num_can)] = (pmot->x) >> 2;
142529a84457aed4c45bc900998b5e11c03023264208James Dong            mvy[(*num_can)++] = (pmot->y) >> 2;
142629a84457aed4c45bc900998b5e11c03023264208James Dong
142729a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb > 0)  /*left neighbor current frame */
142829a84457aed4c45bc900998b5e11c03023264208James Dong            {
142929a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-1];
143029a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
143129a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
143229a84457aed4c45bc900998b5e11c03023264208James Dong            }
143329a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb > 0)  /*upper neighbor current frame */
143429a84457aed4c45bc900998b5e11c03023264208James Dong            {
143529a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth];
143629a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
143729a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
143829a84457aed4c45bc900998b5e11c03023264208James Dong            }
143929a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb < mbwidth - 1)  /*right neighbor previous frame */
144029a84457aed4c45bc900998b5e11c03023264208James Dong            {
144129a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum+1];
144229a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
144329a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
144429a84457aed4c45bc900998b5e11c03023264208James Dong            }
144529a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb < mbheight - 1)  /*bottom neighbor previous frame */
144629a84457aed4c45bc900998b5e11c03023264208James Dong            {
144729a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum+mbwidth];
144829a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
144929a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
145029a84457aed4c45bc900998b5e11c03023264208James Dong            }
145129a84457aed4c45bc900998b5e11c03023264208James Dong        }
145229a84457aed4c45bc900998b5e11c03023264208James Dong
145329a84457aed4c45bc900998b5e11c03023264208James Dong        /* get predicted MV */
145429a84457aed4c45bc900998b5e11c03023264208James Dong        if (imb > 0)    /* get MV from left (A) neighbor either on current or previous frame */
145529a84457aed4c45bc900998b5e11c03023264208James Dong        {
145629a84457aed4c45bc900998b5e11c03023264208James Dong            availA = 1;
145729a84457aed4c45bc900998b5e11c03023264208James Dong            pmot = &mot16x16[mbnum-1];
145829a84457aed4c45bc900998b5e11c03023264208James Dong            pmvA_x = pmot->x;
145929a84457aed4c45bc900998b5e11c03023264208James Dong            pmvA_y = pmot->y;
146029a84457aed4c45bc900998b5e11c03023264208James Dong        }
146129a84457aed4c45bc900998b5e11c03023264208James Dong
146229a84457aed4c45bc900998b5e11c03023264208James Dong        if (jmb > 0) /* get MV from top (B) neighbor either on current or previous frame */
146329a84457aed4c45bc900998b5e11c03023264208James Dong        {
146429a84457aed4c45bc900998b5e11c03023264208James Dong            availB = 1;
146529a84457aed4c45bc900998b5e11c03023264208James Dong            pmot = &mot16x16[mbnum-mbwidth];
146629a84457aed4c45bc900998b5e11c03023264208James Dong            pmvB_x = pmot->x;
146729a84457aed4c45bc900998b5e11c03023264208James Dong            pmvB_y = pmot->y;
146829a84457aed4c45bc900998b5e11c03023264208James Dong
146929a84457aed4c45bc900998b5e11c03023264208James Dong            availC = 1;
147029a84457aed4c45bc900998b5e11c03023264208James Dong
147129a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb < mbwidth - 1) /* get MV from top-right (C) neighbor of current frame */
147229a84457aed4c45bc900998b5e11c03023264208James Dong            {
147329a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth+1];
147429a84457aed4c45bc900998b5e11c03023264208James Dong            }
147529a84457aed4c45bc900998b5e11c03023264208James Dong            else /* get MV from top-left (D) neighbor of current frame */
147629a84457aed4c45bc900998b5e11c03023264208James Dong            {
147729a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth-1];
147829a84457aed4c45bc900998b5e11c03023264208James Dong            }
147929a84457aed4c45bc900998b5e11c03023264208James Dong            pmvC_x = pmot->x;
148029a84457aed4c45bc900998b5e11c03023264208James Dong            pmvC_y = pmot->y;
148129a84457aed4c45bc900998b5e11c03023264208James Dong        }
148229a84457aed4c45bc900998b5e11c03023264208James Dong
148329a84457aed4c45bc900998b5e11c03023264208James Dong    }
148429a84457aed4c45bc900998b5e11c03023264208James Dong    else  /* only Spatial Candidate (four candidates)*/
148529a84457aed4c45bc900998b5e11c03023264208James Dong    {
148629a84457aed4c45bc900998b5e11c03023264208James Dong        if (type_pred == 0) /*first pass*/
148729a84457aed4c45bc900998b5e11c03023264208James Dong        {
148829a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb > 1)  /* neighbor two blocks away to the left */
148929a84457aed4c45bc900998b5e11c03023264208James Dong            {
149029a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-2];
149129a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
149229a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
149329a84457aed4c45bc900998b5e11c03023264208James Dong            }
149429a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb > 0 && jmb > 0)  /* upper-left neighbor */
149529a84457aed4c45bc900998b5e11c03023264208James Dong            {
149629a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth-1];
149729a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
149829a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
149929a84457aed4c45bc900998b5e11c03023264208James Dong            }
150029a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb > 0 && imb < mbheight - 1)  /* upper right neighbor */
150129a84457aed4c45bc900998b5e11c03023264208James Dong            {
150229a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth+1];
150329a84457aed4c45bc900998b5e11c03023264208James Dong                mvx[(*num_can)] = (pmot->x) >> 2;
150429a84457aed4c45bc900998b5e11c03023264208James Dong                mvy[(*num_can)++] = (pmot->y) >> 2;
150529a84457aed4c45bc900998b5e11c03023264208James Dong            }
150629a84457aed4c45bc900998b5e11c03023264208James Dong
150729a84457aed4c45bc900998b5e11c03023264208James Dong            /* get predicted MV */
150829a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb > 1)    /* get MV from 2nd left (A) neighbor either of current frame */
150929a84457aed4c45bc900998b5e11c03023264208James Dong            {
151029a84457aed4c45bc900998b5e11c03023264208James Dong                availA = 1;
151129a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-2];
151229a84457aed4c45bc900998b5e11c03023264208James Dong                pmvA_x = pmot->x;
151329a84457aed4c45bc900998b5e11c03023264208James Dong                pmvA_y = pmot->y;
151429a84457aed4c45bc900998b5e11c03023264208James Dong            }
151529a84457aed4c45bc900998b5e11c03023264208James Dong
151629a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb > 0 && imb > 0) /* get MV from top-left (B) neighbor of current frame */
151729a84457aed4c45bc900998b5e11c03023264208James Dong            {
151829a84457aed4c45bc900998b5e11c03023264208James Dong                availB = 1;
151929a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth-1];
152029a84457aed4c45bc900998b5e11c03023264208James Dong                pmvB_x = pmot->x;
152129a84457aed4c45bc900998b5e11c03023264208James Dong                pmvB_y = pmot->y;
152229a84457aed4c45bc900998b5e11c03023264208James Dong            }
152329a84457aed4c45bc900998b5e11c03023264208James Dong
152429a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb > 0 && imb < mbwidth - 1)
152529a84457aed4c45bc900998b5e11c03023264208James Dong            {
152629a84457aed4c45bc900998b5e11c03023264208James Dong                availC = 1;
152729a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth+1];
152829a84457aed4c45bc900998b5e11c03023264208James Dong                pmvC_x = pmot->x;
152929a84457aed4c45bc900998b5e11c03023264208James Dong                pmvC_y = pmot->y;
153029a84457aed4c45bc900998b5e11c03023264208James Dong            }
153129a84457aed4c45bc900998b5e11c03023264208James Dong        }
153229a84457aed4c45bc900998b5e11c03023264208James Dong//#ifdef SCENE_CHANGE_DETECTION
153329a84457aed4c45bc900998b5e11c03023264208James Dong        /* second pass (ST2 algorithm)*/
153429a84457aed4c45bc900998b5e11c03023264208James Dong        else
153529a84457aed4c45bc900998b5e11c03023264208James Dong        {
153629a84457aed4c45bc900998b5e11c03023264208James Dong            if (type_pred == 1) /*  4/7/01 */
153729a84457aed4c45bc900998b5e11c03023264208James Dong            {
153829a84457aed4c45bc900998b5e11c03023264208James Dong                if (imb > 0)  /*left neighbor current frame */
153929a84457aed4c45bc900998b5e11c03023264208James Dong                {
154029a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum-1];
154129a84457aed4c45bc900998b5e11c03023264208James Dong                    mvx[(*num_can)] = (pmot->x) >> 2;
154229a84457aed4c45bc900998b5e11c03023264208James Dong                    mvy[(*num_can)++] = (pmot->y) >> 2;
154329a84457aed4c45bc900998b5e11c03023264208James Dong                }
154429a84457aed4c45bc900998b5e11c03023264208James Dong                if (jmb > 0)  /*upper neighbor current frame */
154529a84457aed4c45bc900998b5e11c03023264208James Dong                {
154629a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum-mbwidth];
154729a84457aed4c45bc900998b5e11c03023264208James Dong                    mvx[(*num_can)] = (pmot->x) >> 2;
154829a84457aed4c45bc900998b5e11c03023264208James Dong                    mvy[(*num_can)++] = (pmot->y) >> 2;
154929a84457aed4c45bc900998b5e11c03023264208James Dong                }
155029a84457aed4c45bc900998b5e11c03023264208James Dong                if (imb < mbwidth - 1)  /*right neighbor current frame */
155129a84457aed4c45bc900998b5e11c03023264208James Dong                {
155229a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum+1];
155329a84457aed4c45bc900998b5e11c03023264208James Dong                    mvx[(*num_can)] = (pmot->x) >> 2;
155429a84457aed4c45bc900998b5e11c03023264208James Dong                    mvy[(*num_can)++] = (pmot->y) >> 2;
155529a84457aed4c45bc900998b5e11c03023264208James Dong                }
155629a84457aed4c45bc900998b5e11c03023264208James Dong                if (jmb < mbheight - 1)  /*bottom neighbor current frame */
155729a84457aed4c45bc900998b5e11c03023264208James Dong                {
155829a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum+mbwidth];
155929a84457aed4c45bc900998b5e11c03023264208James Dong                    mvx[(*num_can)] = (pmot->x) >> 2;
156029a84457aed4c45bc900998b5e11c03023264208James Dong                    mvy[(*num_can)++] = (pmot->y) >> 2;
156129a84457aed4c45bc900998b5e11c03023264208James Dong                }
156229a84457aed4c45bc900998b5e11c03023264208James Dong            }
156329a84457aed4c45bc900998b5e11c03023264208James Dong            //#else
156429a84457aed4c45bc900998b5e11c03023264208James Dong            else /* original ST1 algorithm */
156529a84457aed4c45bc900998b5e11c03023264208James Dong            {
156629a84457aed4c45bc900998b5e11c03023264208James Dong                if (imb > 0)  /*left neighbor current frame */
156729a84457aed4c45bc900998b5e11c03023264208James Dong                {
156829a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum-1];
156929a84457aed4c45bc900998b5e11c03023264208James Dong                    mvx[(*num_can)] = (pmot->x) >> 2;
157029a84457aed4c45bc900998b5e11c03023264208James Dong                    mvy[(*num_can)++] = (pmot->y) >> 2;
157129a84457aed4c45bc900998b5e11c03023264208James Dong
157229a84457aed4c45bc900998b5e11c03023264208James Dong                    if (jmb > 0)  /*upper-left neighbor current frame */
157329a84457aed4c45bc900998b5e11c03023264208James Dong                    {
157429a84457aed4c45bc900998b5e11c03023264208James Dong                        pmot = &mot16x16[mbnum-mbwidth-1];
157529a84457aed4c45bc900998b5e11c03023264208James Dong                        mvx[(*num_can)] = (pmot->x) >> 2;
157629a84457aed4c45bc900998b5e11c03023264208James Dong                        mvy[(*num_can)++] = (pmot->y) >> 2;
157729a84457aed4c45bc900998b5e11c03023264208James Dong                    }
157829a84457aed4c45bc900998b5e11c03023264208James Dong
157929a84457aed4c45bc900998b5e11c03023264208James Dong                }
158029a84457aed4c45bc900998b5e11c03023264208James Dong                if (jmb > 0)  /*upper neighbor current frame */
158129a84457aed4c45bc900998b5e11c03023264208James Dong                {
158229a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum-mbwidth];
158329a84457aed4c45bc900998b5e11c03023264208James Dong                    mvx[(*num_can)] = (pmot->x) >> 2;
158429a84457aed4c45bc900998b5e11c03023264208James Dong                    mvy[(*num_can)++] = (pmot->y) >> 2;
158529a84457aed4c45bc900998b5e11c03023264208James Dong
158629a84457aed4c45bc900998b5e11c03023264208James Dong                    if (imb < mbheight - 1)  /*upper-right neighbor current frame */
158729a84457aed4c45bc900998b5e11c03023264208James Dong                    {
158829a84457aed4c45bc900998b5e11c03023264208James Dong                        pmot = &mot16x16[mbnum-mbwidth+1];
158929a84457aed4c45bc900998b5e11c03023264208James Dong                        mvx[(*num_can)] = (pmot->x) >> 2;
159029a84457aed4c45bc900998b5e11c03023264208James Dong                        mvy[(*num_can)++] = (pmot->y) >> 2;
159129a84457aed4c45bc900998b5e11c03023264208James Dong                    }
159229a84457aed4c45bc900998b5e11c03023264208James Dong                }
159329a84457aed4c45bc900998b5e11c03023264208James Dong            }
159429a84457aed4c45bc900998b5e11c03023264208James Dong
159529a84457aed4c45bc900998b5e11c03023264208James Dong            /* get predicted MV */
159629a84457aed4c45bc900998b5e11c03023264208James Dong            if (imb > 0)    /* get MV from left (A) neighbor either on current or previous frame */
159729a84457aed4c45bc900998b5e11c03023264208James Dong            {
159829a84457aed4c45bc900998b5e11c03023264208James Dong                availA = 1;
159929a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-1];
160029a84457aed4c45bc900998b5e11c03023264208James Dong                pmvA_x = pmot->x;
160129a84457aed4c45bc900998b5e11c03023264208James Dong                pmvA_y = pmot->y;
160229a84457aed4c45bc900998b5e11c03023264208James Dong            }
160329a84457aed4c45bc900998b5e11c03023264208James Dong
160429a84457aed4c45bc900998b5e11c03023264208James Dong            if (jmb > 0) /* get MV from top (B) neighbor either on current or previous frame */
160529a84457aed4c45bc900998b5e11c03023264208James Dong            {
160629a84457aed4c45bc900998b5e11c03023264208James Dong                availB = 1;
160729a84457aed4c45bc900998b5e11c03023264208James Dong                pmot = &mot16x16[mbnum-mbwidth];
160829a84457aed4c45bc900998b5e11c03023264208James Dong                pmvB_x = pmot->x;
160929a84457aed4c45bc900998b5e11c03023264208James Dong                pmvB_y = pmot->y;
161029a84457aed4c45bc900998b5e11c03023264208James Dong
161129a84457aed4c45bc900998b5e11c03023264208James Dong                availC = 1;
161229a84457aed4c45bc900998b5e11c03023264208James Dong
161329a84457aed4c45bc900998b5e11c03023264208James Dong                if (imb < mbwidth - 1) /* get MV from top-right (C) neighbor of current frame */
161429a84457aed4c45bc900998b5e11c03023264208James Dong                {
161529a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum-mbwidth+1];
161629a84457aed4c45bc900998b5e11c03023264208James Dong                }
161729a84457aed4c45bc900998b5e11c03023264208James Dong                else /* get MV from top-left (D) neighbor of current frame */
161829a84457aed4c45bc900998b5e11c03023264208James Dong                {
161929a84457aed4c45bc900998b5e11c03023264208James Dong                    pmot = &mot16x16[mbnum-mbwidth-1];
162029a84457aed4c45bc900998b5e11c03023264208James Dong                }
162129a84457aed4c45bc900998b5e11c03023264208James Dong                pmvC_x = pmot->x;
162229a84457aed4c45bc900998b5e11c03023264208James Dong                pmvC_y = pmot->y;
162329a84457aed4c45bc900998b5e11c03023264208James Dong            }
162429a84457aed4c45bc900998b5e11c03023264208James Dong        }
162529a84457aed4c45bc900998b5e11c03023264208James Dong//#endif
162629a84457aed4c45bc900998b5e11c03023264208James Dong    }
162729a84457aed4c45bc900998b5e11c03023264208James Dong
162829a84457aed4c45bc900998b5e11c03023264208James Dong    /*  3/23/01, remove redundant candidate (possible k-mean) */
162929a84457aed4c45bc900998b5e11c03023264208James Dong    num1 = *num_can;
163029a84457aed4c45bc900998b5e11c03023264208James Dong    *num_can = 1;
163129a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 1; i < num1; i++)
163229a84457aed4c45bc900998b5e11c03023264208James Dong    {
163329a84457aed4c45bc900998b5e11c03023264208James Dong        same = 0;
163429a84457aed4c45bc900998b5e11c03023264208James Dong        j = 0;
163529a84457aed4c45bc900998b5e11c03023264208James Dong        while (!same && j < *num_can)
163629a84457aed4c45bc900998b5e11c03023264208James Dong        {
163729a84457aed4c45bc900998b5e11c03023264208James Dong#if (CANDIDATE_DISTANCE==0)
163829a84457aed4c45bc900998b5e11c03023264208James Dong            if (mvx[i] == mvx[j] && mvy[i] == mvy[j])
163929a84457aed4c45bc900998b5e11c03023264208James Dong#else
164029a84457aed4c45bc900998b5e11c03023264208James Dong            // modified k-mean,  3/24/01, shouldn't be greater than 3
164129a84457aed4c45bc900998b5e11c03023264208James Dong            if (AVC_ABS(mvx[i] - mvx[j]) + AVC_ABS(mvy[i] - mvy[j]) < CANDIDATE_DISTANCE)
164229a84457aed4c45bc900998b5e11c03023264208James Dong#endif
164329a84457aed4c45bc900998b5e11c03023264208James Dong                same = 1;
164429a84457aed4c45bc900998b5e11c03023264208James Dong            j++;
164529a84457aed4c45bc900998b5e11c03023264208James Dong        }
164629a84457aed4c45bc900998b5e11c03023264208James Dong        if (!same)
164729a84457aed4c45bc900998b5e11c03023264208James Dong        {
164829a84457aed4c45bc900998b5e11c03023264208James Dong            mvx[*num_can] = mvx[i];
164929a84457aed4c45bc900998b5e11c03023264208James Dong            mvy[*num_can] = mvy[i];
165029a84457aed4c45bc900998b5e11c03023264208James Dong            (*num_can)++;
165129a84457aed4c45bc900998b5e11c03023264208James Dong        }
165229a84457aed4c45bc900998b5e11c03023264208James Dong    }
165329a84457aed4c45bc900998b5e11c03023264208James Dong
165429a84457aed4c45bc900998b5e11c03023264208James Dong    if (num1 == 5 && *num_can == 1)
165529a84457aed4c45bc900998b5e11c03023264208James Dong        *num_can = ALL_CAND_EQUAL; /* all are equal */
165629a84457aed4c45bc900998b5e11c03023264208James Dong
165729a84457aed4c45bc900998b5e11c03023264208James Dong    /* calculate predicted MV */
165829a84457aed4c45bc900998b5e11c03023264208James Dong
165929a84457aed4c45bc900998b5e11c03023264208James Dong    if (availA && !(availB || availC))
166029a84457aed4c45bc900998b5e11c03023264208James Dong    {
166129a84457aed4c45bc900998b5e11c03023264208James Dong        *cmvx = pmvA_x;
166229a84457aed4c45bc900998b5e11c03023264208James Dong        *cmvy = pmvA_y;
166329a84457aed4c45bc900998b5e11c03023264208James Dong    }
166429a84457aed4c45bc900998b5e11c03023264208James Dong    else
166529a84457aed4c45bc900998b5e11c03023264208James Dong    {
166629a84457aed4c45bc900998b5e11c03023264208James Dong        *cmvx = AVC_MEDIAN(pmvA_x, pmvB_x, pmvC_x);
166729a84457aed4c45bc900998b5e11c03023264208James Dong        *cmvy = AVC_MEDIAN(pmvA_y, pmvB_y, pmvC_y);
166829a84457aed4c45bc900998b5e11c03023264208James Dong    }
166929a84457aed4c45bc900998b5e11c03023264208James Dong
167029a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
167129a84457aed4c45bc900998b5e11c03023264208James Dong}
167229a84457aed4c45bc900998b5e11c03023264208James Dong
167329a84457aed4c45bc900998b5e11c03023264208James Dong
167429a84457aed4c45bc900998b5e11c03023264208James Dong/*************************************************************
167529a84457aed4c45bc900998b5e11c03023264208James Dong    Function:   AVCMoveNeighborSAD
167629a84457aed4c45bc900998b5e11c03023264208James Dong    Date:       3/27/01
167729a84457aed4c45bc900998b5e11c03023264208James Dong    Purpose:    Move neighboring SAD around when center has shifted
167829a84457aed4c45bc900998b5e11c03023264208James Dong*************************************************************/
167929a84457aed4c45bc900998b5e11c03023264208James Dong
168029a84457aed4c45bc900998b5e11c03023264208James Dongvoid AVCMoveNeighborSAD(int dn[], int new_loc)
168129a84457aed4c45bc900998b5e11c03023264208James Dong{
168229a84457aed4c45bc900998b5e11c03023264208James Dong    int tmp[9];
168329a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[0] = dn[0];
168429a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[1] = dn[1];
168529a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[2] = dn[2];
168629a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[3] = dn[3];
168729a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[4] = dn[4];
168829a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[5] = dn[5];
168929a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[6] = dn[6];
169029a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[7] = dn[7];
169129a84457aed4c45bc900998b5e11c03023264208James Dong    tmp[8] = dn[8];
169229a84457aed4c45bc900998b5e11c03023264208James Dong    dn[0] = dn[1] = dn[2] = dn[3] = dn[4] = dn[5] = dn[6] = dn[7] = dn[8] = 65536;
169329a84457aed4c45bc900998b5e11c03023264208James Dong
169429a84457aed4c45bc900998b5e11c03023264208James Dong    switch (new_loc)
169529a84457aed4c45bc900998b5e11c03023264208James Dong    {
169629a84457aed4c45bc900998b5e11c03023264208James Dong        case 0:
169729a84457aed4c45bc900998b5e11c03023264208James Dong            break;
169829a84457aed4c45bc900998b5e11c03023264208James Dong        case 1:
169929a84457aed4c45bc900998b5e11c03023264208James Dong            dn[4] = tmp[2];
170029a84457aed4c45bc900998b5e11c03023264208James Dong            dn[5] = tmp[0];
170129a84457aed4c45bc900998b5e11c03023264208James Dong            dn[6] = tmp[8];
170229a84457aed4c45bc900998b5e11c03023264208James Dong            break;
170329a84457aed4c45bc900998b5e11c03023264208James Dong        case 2:
170429a84457aed4c45bc900998b5e11c03023264208James Dong            dn[4] = tmp[3];
170529a84457aed4c45bc900998b5e11c03023264208James Dong            dn[5] = tmp[4];
170629a84457aed4c45bc900998b5e11c03023264208James Dong            dn[6] = tmp[0];
170729a84457aed4c45bc900998b5e11c03023264208James Dong            dn[7] = tmp[8];
170829a84457aed4c45bc900998b5e11c03023264208James Dong            dn[8] = tmp[1];
170929a84457aed4c45bc900998b5e11c03023264208James Dong            break;
171029a84457aed4c45bc900998b5e11c03023264208James Dong        case 3:
171129a84457aed4c45bc900998b5e11c03023264208James Dong            dn[6] = tmp[4];
171229a84457aed4c45bc900998b5e11c03023264208James Dong            dn[7] = tmp[0];
171329a84457aed4c45bc900998b5e11c03023264208James Dong            dn[8] = tmp[2];
171429a84457aed4c45bc900998b5e11c03023264208James Dong            break;
171529a84457aed4c45bc900998b5e11c03023264208James Dong        case 4:
171629a84457aed4c45bc900998b5e11c03023264208James Dong            dn[1] = tmp[2];
171729a84457aed4c45bc900998b5e11c03023264208James Dong            dn[2] = tmp[3];
171829a84457aed4c45bc900998b5e11c03023264208James Dong            dn[6] = tmp[5];
171929a84457aed4c45bc900998b5e11c03023264208James Dong            dn[7] = tmp[6];
172029a84457aed4c45bc900998b5e11c03023264208James Dong            dn[8] = tmp[0];
172129a84457aed4c45bc900998b5e11c03023264208James Dong            break;
172229a84457aed4c45bc900998b5e11c03023264208James Dong        case 5:
172329a84457aed4c45bc900998b5e11c03023264208James Dong            dn[1] = tmp[0];
172429a84457aed4c45bc900998b5e11c03023264208James Dong            dn[2] = tmp[4];
172529a84457aed4c45bc900998b5e11c03023264208James Dong            dn[8] = tmp[6];
172629a84457aed4c45bc900998b5e11c03023264208James Dong            break;
172729a84457aed4c45bc900998b5e11c03023264208James Dong        case 6:
172829a84457aed4c45bc900998b5e11c03023264208James Dong            dn[1] = tmp[8];
172929a84457aed4c45bc900998b5e11c03023264208James Dong            dn[2] = tmp[0];
173029a84457aed4c45bc900998b5e11c03023264208James Dong            dn[3] = tmp[4];
173129a84457aed4c45bc900998b5e11c03023264208James Dong            dn[4] = tmp[5];
173229a84457aed4c45bc900998b5e11c03023264208James Dong            dn[8] = tmp[7];
173329a84457aed4c45bc900998b5e11c03023264208James Dong            break;
173429a84457aed4c45bc900998b5e11c03023264208James Dong        case 7:
173529a84457aed4c45bc900998b5e11c03023264208James Dong            dn[2] = tmp[8];
173629a84457aed4c45bc900998b5e11c03023264208James Dong            dn[3] = tmp[0];
173729a84457aed4c45bc900998b5e11c03023264208James Dong            dn[4] = tmp[6];
173829a84457aed4c45bc900998b5e11c03023264208James Dong            break;
173929a84457aed4c45bc900998b5e11c03023264208James Dong        case 8:
174029a84457aed4c45bc900998b5e11c03023264208James Dong            dn[2] = tmp[1];
174129a84457aed4c45bc900998b5e11c03023264208James Dong            dn[3] = tmp[2];
174229a84457aed4c45bc900998b5e11c03023264208James Dong            dn[4] = tmp[0];
174329a84457aed4c45bc900998b5e11c03023264208James Dong            dn[5] = tmp[6];
174429a84457aed4c45bc900998b5e11c03023264208James Dong            dn[6] = tmp[7];
174529a84457aed4c45bc900998b5e11c03023264208James Dong            break;
174629a84457aed4c45bc900998b5e11c03023264208James Dong    }
174729a84457aed4c45bc900998b5e11c03023264208James Dong    dn[0] = tmp[new_loc];
174829a84457aed4c45bc900998b5e11c03023264208James Dong
174929a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
175029a84457aed4c45bc900998b5e11c03023264208James Dong}
175129a84457aed4c45bc900998b5e11c03023264208James Dong
175229a84457aed4c45bc900998b5e11c03023264208James Dong/*  3/28/01, find minimal of dn[9] */
175329a84457aed4c45bc900998b5e11c03023264208James Dong
175429a84457aed4c45bc900998b5e11c03023264208James Dongint AVCFindMin(int dn[])
175529a84457aed4c45bc900998b5e11c03023264208James Dong{
175629a84457aed4c45bc900998b5e11c03023264208James Dong    int min, i;
175729a84457aed4c45bc900998b5e11c03023264208James Dong    int dmin;
175829a84457aed4c45bc900998b5e11c03023264208James Dong
175929a84457aed4c45bc900998b5e11c03023264208James Dong    dmin = dn[1];
176029a84457aed4c45bc900998b5e11c03023264208James Dong    min = 1;
176129a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 2; i < 9; i++)
176229a84457aed4c45bc900998b5e11c03023264208James Dong    {
176329a84457aed4c45bc900998b5e11c03023264208James Dong        if (dn[i] < dmin)
176429a84457aed4c45bc900998b5e11c03023264208James Dong        {
176529a84457aed4c45bc900998b5e11c03023264208James Dong            dmin = dn[i];
176629a84457aed4c45bc900998b5e11c03023264208James Dong            min = i;
176729a84457aed4c45bc900998b5e11c03023264208James Dong        }
176829a84457aed4c45bc900998b5e11c03023264208James Dong    }
176929a84457aed4c45bc900998b5e11c03023264208James Dong
177029a84457aed4c45bc900998b5e11c03023264208James Dong    return min;
177129a84457aed4c45bc900998b5e11c03023264208James Dong}
177229a84457aed4c45bc900998b5e11c03023264208James Dong
177329a84457aed4c45bc900998b5e11c03023264208James Dong
177429a84457aed4c45bc900998b5e11c03023264208James Dong
1775