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