11cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* ------------------------------------------------------------------ 21cc31e629e8132df390ae692873c847d1c2f62c0James Dong * Copyright (C) 1998-2009 PacketVideo 31cc31e629e8132df390ae692873c847d1c2f62c0James Dong * 41cc31e629e8132df390ae692873c847d1c2f62c0James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 51cc31e629e8132df390ae692873c847d1c2f62c0James Dong * you may not use this file except in compliance with the License. 61cc31e629e8132df390ae692873c847d1c2f62c0James Dong * You may obtain a copy of the License at 71cc31e629e8132df390ae692873c847d1c2f62c0James Dong * 81cc31e629e8132df390ae692873c847d1c2f62c0James Dong * http://www.apache.org/licenses/LICENSE-2.0 91cc31e629e8132df390ae692873c847d1c2f62c0James Dong * 101cc31e629e8132df390ae692873c847d1c2f62c0James Dong * Unless required by applicable law or agreed to in writing, software 111cc31e629e8132df390ae692873c847d1c2f62c0James Dong * distributed under the License is distributed on an "AS IS" BASIS, 121cc31e629e8132df390ae692873c847d1c2f62c0James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 131cc31e629e8132df390ae692873c847d1c2f62c0James Dong * express or implied. 141cc31e629e8132df390ae692873c847d1c2f62c0James Dong * See the License for the specific language governing permissions 151cc31e629e8132df390ae692873c847d1c2f62c0James Dong * and limitations under the License. 161cc31e629e8132df390ae692873c847d1c2f62c0James Dong * ------------------------------------------------------------------- 171cc31e629e8132df390ae692873c847d1c2f62c0James Dong */ 181cc31e629e8132df390ae692873c847d1c2f62c0James Dong#include "avcenc_lib.h" 191cc31e629e8132df390ae692873c847d1c2f62c0James Dong 201cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define MIN_GOP 1 /* minimum size of GOP, 1/23/01, need to be tested */ 211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 221cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define DEFAULT_REF_IDX 0 /* always from the first frame in the reflist */ 231cc31e629e8132df390ae692873c847d1c2f62c0James Dong 241cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define ALL_CAND_EQUAL 10 /* any number greater than 5 will work */ 251cc31e629e8132df390ae692873c847d1c2f62c0James Dong 261cc31e629e8132df390ae692873c847d1c2f62c0James Dong 271cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* from TMN 3.2 */ 281cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define PREF_NULL_VEC 129 /* zero vector bias */ 291cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define PREF_16_VEC 129 /* 1MV bias versus 4MVs*/ 301cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define PREF_INTRA 3024//512 /* bias for INTRA coding */ 311cc31e629e8132df390ae692873c847d1c2f62c0James Dong 321cc31e629e8132df390ae692873c847d1c2f62c0James Dongconst static int tab_exclude[9][9] = // [last_loc][curr_loc] 331cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 341cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 0, 0, 0, 0, 0, 0, 0, 0}, 351cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 0, 0, 0, 1, 1, 1, 0, 0}, 361cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 0, 0, 0, 1, 1, 1, 1, 1}, 371cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 0, 0, 0, 0, 0, 1, 1, 1}, 381cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 1, 1, 0, 0, 0, 1, 1, 1}, 391cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 1, 1, 0, 0, 0, 0, 0, 1}, 401cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 1, 1, 1, 1, 0, 0, 0, 1}, 411cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 0, 1, 1, 1, 0, 0, 0, 0}, 421cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 0, 1, 1, 1, 1, 1, 0, 0} 431cc31e629e8132df390ae692873c847d1c2f62c0James Dong}; //to decide whether to continue or compute 441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 451cc31e629e8132df390ae692873c847d1c2f62c0James Dongconst static int refine_next[8][2] = /* [curr_k][increment] */ 461cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 471cc31e629e8132df390ae692873c847d1c2f62c0James Dong {0, 0}, {2, 0}, {1, 1}, {0, 2}, { -1, 1}, { -2, 0}, { -1, -1}, {0, -2} 481cc31e629e8132df390ae692873c847d1c2f62c0James Dong}; 491cc31e629e8132df390ae692873c847d1c2f62c0James Dong 501cc31e629e8132df390ae692873c847d1c2f62c0James Dong#ifdef _SAD_STAT 511cc31e629e8132df390ae692873c847d1c2f62c0James Donguint32 num_MB = 0; 521cc31e629e8132df390ae692873c847d1c2f62c0James Donguint32 num_cand = 0; 531cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif 541cc31e629e8132df390ae692873c847d1c2f62c0James Dong 551cc31e629e8132df390ae692873c847d1c2f62c0James Dong/************************************************************************/ 561cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define TH_INTER_2 100 /* temporary for now */ 571cc31e629e8132df390ae692873c847d1c2f62c0James Dong 581cc31e629e8132df390ae692873c847d1c2f62c0James Dong//#define FIXED_INTERPRED_MODE AVC_P16 591cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define FIXED_REF_IDX 0 601cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define FIXED_MVX 0 611cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define FIXED_MVY 0 621cc31e629e8132df390ae692873c847d1c2f62c0James Dong 631cc31e629e8132df390ae692873c847d1c2f62c0James Dong// only use when AVC_P8 or AVC_P8ref0 641cc31e629e8132df390ae692873c847d1c2f62c0James Dong#define FIXED_SUBMB_MODE AVC_4x4 651cc31e629e8132df390ae692873c847d1c2f62c0James Dong/*************************************************************************/ 661cc31e629e8132df390ae692873c847d1c2f62c0James Dong 671cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* Initialize arrays necessary for motion search */ 681cc31e629e8132df390ae692873c847d1c2f62c0James DongAVCEnc_Status InitMotionSearchModule(AVCHandle *avcHandle) 691cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 701cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject; 711cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 721cc31e629e8132df390ae692873c847d1c2f62c0James Dong int search_range = rateCtrl->mvRange; 731cc31e629e8132df390ae692873c847d1c2f62c0James Dong int number_of_subpel_positions = 4 * (2 * search_range + 3); 741cc31e629e8132df390ae692873c847d1c2f62c0James Dong int max_mv_bits, max_mvd; 751cc31e629e8132df390ae692873c847d1c2f62c0James Dong int temp_bits = 0; 761cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *mvbits; 771cc31e629e8132df390ae692873c847d1c2f62c0James Dong int bits, imax, imin, i; 781cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8* subpel_pred = (uint8*) encvid->subpel_pred; // all 16 sub-pel positions 791cc31e629e8132df390ae692873c847d1c2f62c0James Dong 801cc31e629e8132df390ae692873c847d1c2f62c0James Dong 811cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (number_of_subpel_positions > 0) 821cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 831cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp_bits++; 841cc31e629e8132df390ae692873c847d1c2f62c0James Dong number_of_subpel_positions >>= 1; 851cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 861cc31e629e8132df390ae692873c847d1c2f62c0James Dong 871cc31e629e8132df390ae692873c847d1c2f62c0James Dong max_mv_bits = 3 + 2 * temp_bits; 881cc31e629e8132df390ae692873c847d1c2f62c0James Dong max_mvd = (1 << (max_mv_bits >> 1)) - 1; 891cc31e629e8132df390ae692873c847d1c2f62c0James Dong 901cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->mvbits_array = (uint8*) avcHandle->CBAVC_Malloc(encvid->avcHandle->userData, 911cc31e629e8132df390ae692873c847d1c2f62c0James Dong sizeof(uint8) * (2 * max_mvd + 1), DEFAULT_ATTR); 921cc31e629e8132df390ae692873c847d1c2f62c0James Dong 931cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (encvid->mvbits_array == NULL) 941cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 951cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_MEMORY_FAIL; 961cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 971cc31e629e8132df390ae692873c847d1c2f62c0James Dong 981cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvbits = encvid->mvbits = encvid->mvbits_array + max_mvd; 991cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1001cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvbits[0] = 1; 1011cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (bits = 3; bits <= max_mv_bits; bits += 2) 1021cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1031cc31e629e8132df390ae692873c847d1c2f62c0James Dong imax = 1 << (bits >> 1); 1041cc31e629e8132df390ae692873c847d1c2f62c0James Dong imin = imax >> 1; 1051cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1061cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = imin; i < imax; i++) mvbits[-i] = mvbits[i] = bits; 1071cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1081cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1091cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* initialize half-pel search */ 1101cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[0] = subpel_pred + REF_CENTER; 1111cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[1] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1 ; 1121cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[2] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1; 1131cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[3] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25; 1141cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[4] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25; 1151cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[5] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 25; 1161cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[6] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1171cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[7] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1181cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->hpel_cand[8] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE; 1191cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1201cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* For quarter-pel interpolation around best half-pel result */ 1211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1221cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[0][0] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE; 1231cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[0][1] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1; 1241cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[0][2] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1251cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[0][3] = subpel_pred + REF_CENTER; 1261cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1271cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1281cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[1][0] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE; 1291cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[1][1] = subpel_pred + REF_CENTER - 24; 1301cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[1][2] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE; 1311cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[1][3] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1; 1321cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1331cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[2][0] = subpel_pred + REF_CENTER - 24; 1341cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[2][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1; 1351cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[2][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1; 1361cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[2][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1; 1371cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1381cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[3][0] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 1; 1391cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[3][1] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 1; 1401cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[3][2] = subpel_pred + REF_CENTER; 1411cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[3][3] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25; 1421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1431cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[4][0] = subpel_pred + REF_CENTER; 1441cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[4][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25; 1451cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[4][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 25; 1461cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[4][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 25; 1471cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1481cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[5][0] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1491cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[5][1] = subpel_pred + REF_CENTER; 1501cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[5][2] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1511cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[5][3] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 25; 1521cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1531cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[6][0] = subpel_pred + REF_CENTER - 1; 1541cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[6][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1551cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[6][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE + 24; 1561cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[6][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1571cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1581cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[7][0] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE; 1591cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[7][1] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE; 1601cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[7][2] = subpel_pred + REF_CENTER - 1; 1611cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[7][3] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE + 24; 1621cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1631cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[8][0] = subpel_pred + REF_CENTER - 25; 1641cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[8][1] = subpel_pred + V0Q_H2Q * SUBPEL_PRED_BLK_SIZE; 1651cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[8][2] = subpel_pred + V2Q_H0Q * SUBPEL_PRED_BLK_SIZE; 1661cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->bilin_base[8][3] = subpel_pred + V2Q_H2Q * SUBPEL_PRED_BLK_SIZE; 1671cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1681cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1691cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_SUCCESS; 1701cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 1711cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1721cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* Clean-up memory */ 1731cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid CleanMotionSearchModule(AVCHandle *avcHandle) 1741cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 1751cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCEncObject *encvid = (AVCEncObject*) avcHandle->AVCObject; 1761cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1771cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (encvid->mvbits_array) 1781cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 1791cc31e629e8132df390ae692873c847d1c2f62c0James Dong avcHandle->CBAVC_Free(avcHandle->userData, (int)(encvid->mvbits_array)); 1801cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->mvbits = NULL; 1811cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 1821cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1831cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 1841cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 1851cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1861cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1871cc31e629e8132df390ae692873c847d1c2f62c0James Dongbool IntraDecisionABE(int *min_cost, uint8 *cur, int pitch, bool ave) 1881cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 1891cc31e629e8132df390ae692873c847d1c2f62c0James Dong int j; 1901cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *out; 1911cc31e629e8132df390ae692873c847d1c2f62c0James Dong int temp, SBE; 1921cc31e629e8132df390ae692873c847d1c2f62c0James Dong OsclFloat ABE; 1931cc31e629e8132df390ae692873c847d1c2f62c0James Dong bool intra = true; 1941cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1951cc31e629e8132df390ae692873c847d1c2f62c0James Dong SBE = 0; 1961cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* top neighbor */ 1971cc31e629e8132df390ae692873c847d1c2f62c0James Dong out = cur - pitch; 1981cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (j = 0; j < 16; j++) 1991cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2001cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp = out[j] - cur[j]; 2011cc31e629e8132df390ae692873c847d1c2f62c0James Dong SBE += ((temp >= 0) ? temp : -temp); 2021cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2031cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2041cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* left neighbor */ 2051cc31e629e8132df390ae692873c847d1c2f62c0James Dong out = cur - 1; 2061cc31e629e8132df390ae692873c847d1c2f62c0James Dong out -= pitch; 2071cc31e629e8132df390ae692873c847d1c2f62c0James Dong cur -= pitch; 2081cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (j = 0; j < 16; j++) 2091cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2101cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp = *(out += pitch) - *(cur += pitch); 2111cc31e629e8132df390ae692873c847d1c2f62c0James Dong SBE += ((temp >= 0) ? temp : -temp); 2121cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2131cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2141cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* compare mincost/384 and SBE/64 */ 2151cc31e629e8132df390ae692873c847d1c2f62c0James Dong ABE = SBE / 32.0; //ABE = SBE/64.0; // 2161cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (ABE >= *min_cost / 256.0) //if( ABE*0.8 >= min_cost/384.0) // 2171cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2181cc31e629e8132df390ae692873c847d1c2f62c0James Dong intra = false; // no possibility of intra, just use inter 2191cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2201cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 2211cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2221cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (ave == true) 2231cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2241cc31e629e8132df390ae692873c847d1c2f62c0James Dong *min_cost = (*min_cost + (int)(SBE * 8)) >> 1; // possibility of intra, averaging the cost 2251cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2261cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 2271cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2281cc31e629e8132df390ae692873c847d1c2f62c0James Dong *min_cost = (int)(SBE * 8); 2291cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2301cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2311cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2321cc31e629e8132df390ae692873c847d1c2f62c0James Dong return intra; 2331cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 2341cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2351cc31e629e8132df390ae692873c847d1c2f62c0James Dong/******* main function for macroblock prediction for the entire frame ***/ 2361cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* if turns out to be IDR frame, set video->nal_unit_type to AVC_NALTYPE_IDR */ 2371cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCMotionEstimation(AVCEncObject *encvid) 2381cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 2391cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 2401cc31e629e8132df390ae692873c847d1c2f62c0James Dong int slice_type = video->slice_type; 2411cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCFrameIO *currInput = encvid->currInput; 2421cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCPictureData *refPic = video->RefPicList0[0]; 2431cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i, j, k; 2441cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbwidth = video->PicWidthInMbs; 2451cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbheight = video->PicHeightInMbs; 2461cc31e629e8132df390ae692873c847d1c2f62c0James Dong int totalMB = video->PicSizeInMbs; 2471cc31e629e8132df390ae692873c847d1c2f62c0James Dong int pitch = currInput->pitch; 2481cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMacroblock *currMB, *mblock = video->mblock; 2491cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMV *mot_mb_16x16, *mot16x16 = encvid->mot16x16; 2501cc31e629e8132df390ae692873c847d1c2f62c0James Dong // AVCMV *mot_mb_16x8, *mot_mb_8x16, *mot_mb_8x8, etc; 2511cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 2521cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *intraSearch = encvid->intraSearch; 2531cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint FS_en = encvid->fullsearch_enable; 2541cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2551cc31e629e8132df390ae692873c847d1c2f62c0James Dong int NumIntraSearch, start_i, numLoop, incr_i; 2561cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbnum, offset; 2571cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *cur, *best_cand[5]; 2581cc31e629e8132df390ae692873c847d1c2f62c0James Dong int totalSAD = 0; /* average SAD for rate control */ 2591cc31e629e8132df390ae692873c847d1c2f62c0James Dong int type_pred; 2601cc31e629e8132df390ae692873c847d1c2f62c0James Dong int abe_cost; 2611cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2621cc31e629e8132df390ae692873c847d1c2f62c0James Dong#ifdef HTFM 2631cc31e629e8132df390ae692873c847d1c2f62c0James Dong /***** HYPOTHESIS TESTING ********/ /* 2/28/01 */ 2641cc31e629e8132df390ae692873c847d1c2f62c0James Dong int collect = 0; 2651cc31e629e8132df390ae692873c847d1c2f62c0James Dong HTFM_Stat htfm_stat; 2661cc31e629e8132df390ae692873c847d1c2f62c0James Dong double newvar[16]; 2671cc31e629e8132df390ae692873c847d1c2f62c0James Dong double exp_lamda[15]; 2681cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*********************************/ 2691cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif 2701cc31e629e8132df390ae692873c847d1c2f62c0James Dong int hp_guess = 0; 2711cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint32 mv_uint32; 2721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2731cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset = 0; 2741cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2751cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (slice_type == AVC_I_SLICE) 2761cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2771cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* cannot do I16 prediction here because it needs full decoding. */ 2781cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < totalMB; i++) 2791cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2801cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->min_cost[i] = 0x7FFFFFFF; /* max value for int */ 2811cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2821cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2831cc31e629e8132df390ae692873c847d1c2f62c0James Dong memset(intraSearch, 1, sizeof(uint8)*totalMB); 2841cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2851cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->firstIntraRefreshMBIndx = 0; /* reset this */ 2861cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2871cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 2881cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2891cc31e629e8132df390ae692873c847d1c2f62c0James Dong else // P_SLICE 2901cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2911cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < totalMB; i++) 2921cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 2931cc31e629e8132df390ae692873c847d1c2f62c0James Dong mblock[i].mb_intra = 0; 2941cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2951cc31e629e8132df390ae692873c847d1c2f62c0James Dong memset(intraSearch, 1, sizeof(uint8)*totalMB); 2961cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 2971cc31e629e8132df390ae692873c847d1c2f62c0James Dong 2981cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (refPic->padded == 0) 2991cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3001cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCPaddingEdge(refPic); 3011cc31e629e8132df390ae692873c847d1c2f62c0James Dong refPic->padded = 1; 3021cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3031cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Random INTRA update */ 3041cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->intraMBRate) 3051cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3061cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRasterIntraUpdate(encvid, mblock, totalMB, rateCtrl->intraMBRate); 3071cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3081cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3091cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->sad_extra_info = NULL; 3101cc31e629e8132df390ae692873c847d1c2f62c0James Dong#ifdef HTFM 3111cc31e629e8132df390ae692873c847d1c2f62c0James Dong /***** HYPOTHESIS TESTING ********/ 3121cc31e629e8132df390ae692873c847d1c2f62c0James Dong InitHTFM(video, &htfm_stat, newvar, &collect); 3131cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*********************************/ 3141cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif 3151cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3161cc31e629e8132df390ae692873c847d1c2f62c0James Dong if ((rateCtrl->scdEnable == 1) 3171cc31e629e8132df390ae692873c847d1c2f62c0James Dong && ((rateCtrl->frame_rate < 5.0) || (video->sliceHdr->frame_num > MIN_GOP))) 3181cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* do not try to detect a new scene if low frame rate and too close to previous I-frame */ 3191cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3201cc31e629e8132df390ae692873c847d1c2f62c0James Dong incr_i = 2; 3211cc31e629e8132df390ae692873c847d1c2f62c0James Dong numLoop = 2; 3221cc31e629e8132df390ae692873c847d1c2f62c0James Dong start_i = 1; 3231cc31e629e8132df390ae692873c847d1c2f62c0James Dong type_pred = 0; /* for initial candidate selection */ 3241cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3251cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 3261cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3271cc31e629e8132df390ae692873c847d1c2f62c0James Dong incr_i = 1; 3281cc31e629e8132df390ae692873c847d1c2f62c0James Dong numLoop = 1; 3291cc31e629e8132df390ae692873c847d1c2f62c0James Dong start_i = 0; 3301cc31e629e8132df390ae692873c847d1c2f62c0James Dong type_pred = 2; 3311cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3321cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3331cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* First pass, loop thru half the macroblock */ 3341cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* determine scene change */ 3351cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Second pass, for the rest of macroblocks */ 3361cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumIntraSearch = 0; // to be intra searched in the encoding loop. 3371cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (numLoop--) 3381cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3391cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (j = 0; j < mbheight; j++) 3401cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3411cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (incr_i > 1) 3421cc31e629e8132df390ae692873c847d1c2f62c0James Dong start_i = (start_i == 0 ? 1 : 0) ; /* toggle 0 and 1 */ 3431cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3441cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset = pitch * (j << 4) + (start_i << 4); 3451cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3461cc31e629e8132df390ae692873c847d1c2f62c0James Dong mbnum = j * mbwidth + start_i; 3471cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3481cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = start_i; i < mbwidth; i += incr_i) 3491cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3501cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->mbNum = mbnum; 3511cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->currMB = currMB = mblock + mbnum; 3521cc31e629e8132df390ae692873c847d1c2f62c0James Dong mot_mb_16x16 = mot16x16 + mbnum; 3531cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3541cc31e629e8132df390ae692873c847d1c2f62c0James Dong cur = currInput->YCbCr[0] + offset; 3551cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3561cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (currMB->mb_intra == 0) /* for INTER mode */ 3571cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3581cc31e629e8132df390ae692873c847d1c2f62c0James Dong#if defined(HTFM) 3591cc31e629e8132df390ae692873c847d1c2f62c0James Dong HTFMPrepareCurMB_AVC(encvid, &htfm_stat, cur, pitch); 3601cc31e629e8132df390ae692873c847d1c2f62c0James Dong#else 3611cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCPrepareCurMB(encvid, cur, pitch); 3621cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif 3631cc31e629e8132df390ae692873c847d1c2f62c0James Dong /************************************************************/ 3641cc31e629e8132df390ae692873c847d1c2f62c0James Dong /******** full-pel 1MV search **********************/ 3651cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3661cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMBMotionSearch(encvid, cur, best_cand, i << 4, j << 4, type_pred, 3671cc31e629e8132df390ae692873c847d1c2f62c0James Dong FS_en, &hp_guess); 3681cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3691cc31e629e8132df390ae692873c847d1c2f62c0James Dong abe_cost = encvid->min_cost[mbnum] = mot_mb_16x16->sad; 3701cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3711cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* set mbMode and MVs */ 3721cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->mbMode = AVC_P16; 3731cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MBPartPredMode[0][0] = AVC_Pred_L0; 3741cc31e629e8132df390ae692873c847d1c2f62c0James Dong mv_uint32 = ((mot_mb_16x16->y) << 16) | ((mot_mb_16x16->x) & 0xffff); 3751cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (k = 0; k < 32; k += 2) 3761cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3771cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->mvL0[k>>1] = mv_uint32; 3781cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3791cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3801cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* make a decision whether it should be tested for intra or not */ 3811cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i != mbwidth - 1 && j != mbheight - 1 && i != 0 && j != 0) 3821cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3831cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (false == IntraDecisionABE(&abe_cost, cur, pitch, true)) 3841cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3851cc31e629e8132df390ae692873c847d1c2f62c0James Dong intraSearch[mbnum] = 0; 3861cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3871cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 3881cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3891cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumIntraSearch++; 3901cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->MADofMB[mbnum] = abe_cost; 3911cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3921cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3931cc31e629e8132df390ae692873c847d1c2f62c0James Dong else // boundary MBs, always do intra search 3941cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 3951cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumIntraSearch++; 3961cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 3971cc31e629e8132df390ae692873c847d1c2f62c0James Dong 3981cc31e629e8132df390ae692873c847d1c2f62c0James Dong totalSAD += (int) rateCtrl->MADofMB[mbnum];//mot_mb_16x16->sad; 3991cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4001cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* INTRA update, use for prediction */ 4011cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4021cc31e629e8132df390ae692873c847d1c2f62c0James Dong mot_mb_16x16[0].x = mot_mb_16x16[0].y = 0; 4031cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4041cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* reset all other MVs to zero */ 4051cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* mot_mb_16x8, mot_mb_8x16, mot_mb_8x8, etc. */ 4061cc31e629e8132df390ae692873c847d1c2f62c0James Dong abe_cost = encvid->min_cost[mbnum] = 0x7FFFFFFF; /* max value for int */ 4071cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4081cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i != mbwidth - 1 && j != mbheight - 1 && i != 0 && j != 0) 4091cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4101cc31e629e8132df390ae692873c847d1c2f62c0James Dong IntraDecisionABE(&abe_cost, cur, pitch, false); 4111cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4121cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->MADofMB[mbnum] = abe_cost; 4131cc31e629e8132df390ae692873c847d1c2f62c0James Dong totalSAD += abe_cost; 4141cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4151cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4161cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumIntraSearch++ ; 4171cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* cannot do I16 prediction here because it needs full decoding. */ 4181cc31e629e8132df390ae692873c847d1c2f62c0James Dong // intraSearch[mbnum] = 1; 4191cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4201cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4221cc31e629e8132df390ae692873c847d1c2f62c0James Dong mbnum += incr_i; 4231cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset += (incr_i << 4); 4241cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4251cc31e629e8132df390ae692873c847d1c2f62c0James Dong } /* for i */ 4261cc31e629e8132df390ae692873c847d1c2f62c0James Dong } /* for j */ 4271cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4281cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* since we cannot do intra/inter decision here, the SCD has to be 4291cc31e629e8132df390ae692873c847d1c2f62c0James Dong based on other criteria such as motion vectors coherency or the SAD */ 4301cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (incr_i > 1 && numLoop) /* scene change on and first loop */ 4311cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4321cc31e629e8132df390ae692873c847d1c2f62c0James Dong //if(NumIntraSearch > ((totalMB>>3)<<1) + (totalMB>>3)) /* 75% of 50%MBs */ 4331cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (NumIntraSearch*99 > (48*totalMB)) /* 20% of 50%MBs */ 4341cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* need to do more investigation about this threshold since the NumIntraSearch 4351cc31e629e8132df390ae692873c847d1c2f62c0James Dong only show potential intra MBs, not the actual one */ 4361cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4371cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* we can choose to just encode I_SLICE without IDR */ 4381cc31e629e8132df390ae692873c847d1c2f62c0James Dong //video->nal_unit_type = AVC_NALTYPE_IDR; 4391cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->nal_unit_type = AVC_NALTYPE_SLICE; 4401cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->sliceHdr->slice_type = AVC_I_ALL_SLICE; 4411cc31e629e8132df390ae692873c847d1c2f62c0James Dong video->slice_type = AVC_I_SLICE; 4421cc31e629e8132df390ae692873c847d1c2f62c0James Dong memset(intraSearch, 1, sizeof(uint8)*totalMB); 4431cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = totalMB; 4441cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (i--) 4451cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4461cc31e629e8132df390ae692873c847d1c2f62c0James Dong mblock[i].mb_intra = 1; 4471cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->min_cost[i] = 0x7FFFFFFF; /* max value for int */ 4481cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4491cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4501cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->totalSAD = totalSAD * 2; /* SAD */ 4511cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4521cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 4531cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4541cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4551cc31e629e8132df390ae692873c847d1c2f62c0James Dong /******** no scene change, continue motion search **********************/ 4561cc31e629e8132df390ae692873c847d1c2f62c0James Dong start_i = 0; 4571cc31e629e8132df390ae692873c847d1c2f62c0James Dong type_pred++; /* second pass */ 4581cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4591cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4601cc31e629e8132df390ae692873c847d1c2f62c0James Dong rateCtrl->totalSAD = totalSAD; /* SAD */ 4611cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4621cc31e629e8132df390ae692873c847d1c2f62c0James Dong#ifdef HTFM 4631cc31e629e8132df390ae692873c847d1c2f62c0James Dong /***** HYPOTHESIS TESTING ********/ 4641cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (collect) 4651cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 4661cc31e629e8132df390ae692873c847d1c2f62c0James Dong collect = 0; 4671cc31e629e8132df390ae692873c847d1c2f62c0James Dong UpdateHTFM(encvid, newvar, exp_lamda, &htfm_stat); 4681cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 4691cc31e629e8132df390ae692873c847d1c2f62c0James Dong /*********************************/ 4701cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif 4711cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4721cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 4731cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 4741cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4751cc31e629e8132df390ae692873c847d1c2f62c0James Dong/*===================================================================== 4761cc31e629e8132df390ae692873c847d1c2f62c0James Dong Function: PaddingEdge 4771cc31e629e8132df390ae692873c847d1c2f62c0James Dong Date: 09/16/2000 4781cc31e629e8132df390ae692873c847d1c2f62c0James Dong Purpose: Pad edge of a Vop 4791cc31e629e8132df390ae692873c847d1c2f62c0James Dong=====================================================================*/ 4801cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4811cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCPaddingEdge(AVCPictureData *refPic) 4821cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 4831cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *src, *dst; 4841cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 4851cc31e629e8132df390ae692873c847d1c2f62c0James Dong int pitch, width, height; 4861cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint32 temp1, temp2; 4871cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4881cc31e629e8132df390ae692873c847d1c2f62c0James Dong width = refPic->width; 4891cc31e629e8132df390ae692873c847d1c2f62c0James Dong height = refPic->height; 4901cc31e629e8132df390ae692873c847d1c2f62c0James Dong pitch = refPic->pitch; 4911cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4921cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* pad top */ 4931cc31e629e8132df390ae692873c847d1c2f62c0James Dong src = refPic->Sl; 4941cc31e629e8132df390ae692873c847d1c2f62c0James Dong 4951cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp1 = *src; /* top-left corner */ 4961cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp2 = src[width-1]; /* top-right corner */ 4971cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp1 |= (temp1 << 8); 4981cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp1 |= (temp1 << 16); 4991cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp2 |= (temp2 << 8); 5001cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp2 |= (temp2 << 16); 5011cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5021cc31e629e8132df390ae692873c847d1c2f62c0James Dong dst = src - (pitch << 4); 5031cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5041cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 16)) = temp1; 5051cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 12)) = temp1; 5061cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 8)) = temp1; 5071cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 4)) = temp1; 5081cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5091cc31e629e8132df390ae692873c847d1c2f62c0James Dong memcpy(dst, src, width); 5101cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5111cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst += width)) = temp2; 5121cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst + 4)) = temp2; 5131cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst + 8)) = temp2; 5141cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst + 12)) = temp2; 5151cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5161cc31e629e8132df390ae692873c847d1c2f62c0James Dong dst = dst - width - 16; 5171cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5181cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = 15; 5191cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (i--) 5201cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5211cc31e629e8132df390ae692873c847d1c2f62c0James Dong memcpy(dst + pitch, dst, pitch); 5221cc31e629e8132df390ae692873c847d1c2f62c0James Dong dst += pitch; 5231cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5241cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5251cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* pad sides */ 5261cc31e629e8132df390ae692873c847d1c2f62c0James Dong dst += (pitch + 16); 5271cc31e629e8132df390ae692873c847d1c2f62c0James Dong src = dst; 5281cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = height; 5291cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (i--) 5301cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5311cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp1 = *src; 5321cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp2 = src[width-1]; 5331cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp1 |= (temp1 << 8); 5341cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp1 |= (temp1 << 16); 5351cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp2 |= (temp2 << 8); 5361cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp2 |= (temp2 << 16); 5371cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5381cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 16)) = temp1; 5391cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 12)) = temp1; 5401cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 8)) = temp1; 5411cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst - 4)) = temp1; 5421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5431cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst += width)) = temp2; 5441cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst + 4)) = temp2; 5451cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst + 8)) = temp2; 5461cc31e629e8132df390ae692873c847d1c2f62c0James Dong *((uint32*)(dst + 12)) = temp2; 5471cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5481cc31e629e8132df390ae692873c847d1c2f62c0James Dong src += pitch; 5491cc31e629e8132df390ae692873c847d1c2f62c0James Dong dst = src; 5501cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5511cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5521cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* pad bottom */ 5531cc31e629e8132df390ae692873c847d1c2f62c0James Dong dst -= 16; 5541cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = 16; 5551cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (i--) 5561cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5571cc31e629e8132df390ae692873c847d1c2f62c0James Dong memcpy(dst, dst - pitch, pitch); 5581cc31e629e8132df390ae692873c847d1c2f62c0James Dong dst += pitch; 5591cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5601cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5611cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5621cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 5631cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 5641cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5651cc31e629e8132df390ae692873c847d1c2f62c0James Dong/*=========================================================================== 5661cc31e629e8132df390ae692873c847d1c2f62c0James Dong Function: AVCRasterIntraUpdate 5671cc31e629e8132df390ae692873c847d1c2f62c0James Dong Date: 2/26/01 5681cc31e629e8132df390ae692873c847d1c2f62c0James Dong Purpose: To raster-scan assign INTRA-update . 5691cc31e629e8132df390ae692873c847d1c2f62c0James Dong N macroblocks are updated (also was programmable). 5701cc31e629e8132df390ae692873c847d1c2f62c0James Dong===========================================================================*/ 5711cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCRasterIntraUpdate(AVCEncObject *encvid, AVCMacroblock *mblock, int totalMB, int numRefresh) 5721cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 5731cc31e629e8132df390ae692873c847d1c2f62c0James Dong int indx, i; 5741cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5751cc31e629e8132df390ae692873c847d1c2f62c0James Dong indx = encvid->firstIntraRefreshMBIndx; 5761cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < numRefresh && indx < totalMB; i++) 5771cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5781cc31e629e8132df390ae692873c847d1c2f62c0James Dong (mblock + indx)->mb_intra = 1; 5791cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->intraSearch[indx++] = 1; 5801cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5811cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5821cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* if read the end of frame, reset and loop around */ 5831cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (indx >= totalMB - 1) 5841cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5851cc31e629e8132df390ae692873c847d1c2f62c0James Dong indx = 0; 5861cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (i < numRefresh && indx < totalMB) 5871cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 5881cc31e629e8132df390ae692873c847d1c2f62c0James Dong (mblock + indx)->mb_intra = 1; 5891cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->intraSearch[indx++] = 1; 5901cc31e629e8132df390ae692873c847d1c2f62c0James Dong i++; 5911cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5921cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 5931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5941cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->firstIntraRefreshMBIndx = indx; /* update with a new value */ 5951cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5961cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 5971cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 5981cc31e629e8132df390ae692873c847d1c2f62c0James Dong 5991cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6001cc31e629e8132df390ae692873c847d1c2f62c0James Dong#ifdef HTFM 6011cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid InitHTFM(VideoEncData *encvid, HTFM_Stat *htfm_stat, double *newvar, int *collect) 6021cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 6031cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 6041cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 6051cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lx = video->currPic->width; // padding 6061cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lx2 = lx << 1; 6071cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lx3 = lx2 + lx; 6081cc31e629e8132df390ae692873c847d1c2f62c0James Dong int rx = video->currPic->pitch; 6091cc31e629e8132df390ae692873c847d1c2f62c0James Dong int rx2 = rx << 1; 6101cc31e629e8132df390ae692873c847d1c2f62c0James Dong int rx3 = rx2 + rx; 6111cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6121cc31e629e8132df390ae692873c847d1c2f62c0James Dong int *offset, *offset2; 6131cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6141cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* 4/11/01, collect data every 30 frames, doesn't have to be base layer */ 6151cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (((int)video->sliceHdr->frame_num) % 30 == 1) 6161cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6171cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6181cc31e629e8132df390ae692873c847d1c2f62c0James Dong *collect = 1; 6191cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6201cc31e629e8132df390ae692873c847d1c2f62c0James Dong htfm_stat->countbreak = 0; 6211cc31e629e8132df390ae692873c847d1c2f62c0James Dong htfm_stat->abs_dif_mad_avg = 0; 6221cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6231cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 16; i++) 6241cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6251cc31e629e8132df390ae692873c847d1c2f62c0James Dong newvar[i] = 0.0; 6261cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6271cc31e629e8132df390ae692873c847d1c2f62c0James Dong// encvid->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM_Collect; 6281cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_Macroblock = &SAD_MB_HTFM_Collect; 6291cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[0] = NULL; 6301cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFM_Collectxh; 6311cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFM_Collectyh; 6321cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFM_Collectxhyh; 6331cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->sad_extra_info = (void*)(htfm_stat); 6341cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset = htfm_stat->offsetArray; 6351cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2 = htfm_stat->offsetRef; 6361cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6371cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 6381cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6391cc31e629e8132df390ae692873c847d1c2f62c0James Dong// encvid->functionPointer->SAD_MB_PADDING = &SAD_MB_PADDING_HTFM; 6401cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_Macroblock = &SAD_MB_HTFM; 6411cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[0] = NULL; 6421cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[1] = &SAD_MB_HP_HTFMxh; 6431cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[2] = &SAD_MB_HP_HTFMyh; 6441cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->functionPointer->SAD_MB_HalfPel[3] = &SAD_MB_HP_HTFMxhyh; 6451cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->sad_extra_info = (void*)(encvid->nrmlz_th); 6461cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset = encvid->nrmlz_th + 16; 6471cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2 = encvid->nrmlz_th + 32; 6481cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6491cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6501cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[0] = 0; 6511cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[1] = lx2 + 2; 6521cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[2] = 2; 6531cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[3] = lx2; 6541cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[4] = lx + 1; 6551cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[5] = lx3 + 3; 6561cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[6] = lx + 3; 6571cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[7] = lx3 + 1; 6581cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[8] = lx; 6591cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[9] = lx3 + 2; 6601cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[10] = lx3 ; 6611cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[11] = lx + 2 ; 6621cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[12] = 1; 6631cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[13] = lx2 + 3; 6641cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[14] = lx2 + 1; 6651cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset[15] = 3; 6661cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6671cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[0] = 0; 6681cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[1] = rx2 + 2; 6691cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[2] = 2; 6701cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[3] = rx2; 6711cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[4] = rx + 1; 6721cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[5] = rx3 + 3; 6731cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[6] = rx + 3; 6741cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[7] = rx3 + 1; 6751cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[8] = rx; 6761cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[9] = rx3 + 2; 6771cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[10] = rx3 ; 6781cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[11] = rx + 2 ; 6791cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[12] = 1; 6801cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[13] = rx2 + 3; 6811cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[14] = rx2 + 1; 6821cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset2[15] = 3; 6831cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6841cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 6851cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 6861cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6871cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid UpdateHTFM(AVCEncObject *encvid, double *newvar, double *exp_lamda, HTFM_Stat *htfm_stat) 6881cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 6891cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (htfm_stat->countbreak == 0) 6901cc31e629e8132df390ae692873c847d1c2f62c0James Dong htfm_stat->countbreak = 1; 6911cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6921cc31e629e8132df390ae692873c847d1c2f62c0James Dong newvar[0] = (double)(htfm_stat->abs_dif_mad_avg) / (htfm_stat->countbreak * 16.); 6931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 6941cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (newvar[0] < 0.001) 6951cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 6961cc31e629e8132df390ae692873c847d1c2f62c0James Dong newvar[0] = 0.001; /* to prevent floating overflow */ 6971cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 6981cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[0] = 1 / (newvar[0] * 1.4142136); 6991cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[1] = exp_lamda[0] * 1.5825; 7001cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[2] = exp_lamda[0] * 2.1750; 7011cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[3] = exp_lamda[0] * 3.5065; 7021cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[4] = exp_lamda[0] * 3.1436; 7031cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[5] = exp_lamda[0] * 3.5315; 7041cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[6] = exp_lamda[0] * 3.7449; 7051cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[7] = exp_lamda[0] * 4.5854; 7061cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[8] = exp_lamda[0] * 4.6191; 7071cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[9] = exp_lamda[0] * 5.4041; 7081cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[10] = exp_lamda[0] * 6.5974; 7091cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[11] = exp_lamda[0] * 10.5341; 7101cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[12] = exp_lamda[0] * 10.0719; 7111cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[13] = exp_lamda[0] * 12.0516; 7121cc31e629e8132df390ae692873c847d1c2f62c0James Dong exp_lamda[14] = exp_lamda[0] * 15.4552; 7131cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7141cc31e629e8132df390ae692873c847d1c2f62c0James Dong CalcThreshold(HTFM_Pf, exp_lamda, encvid->nrmlz_th); 7151cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 7161cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 7171cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7181cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7191cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid CalcThreshold(double pf, double exp_lamda[], int nrmlz_th[]) 7201cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 7211cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 7221cc31e629e8132df390ae692873c847d1c2f62c0James Dong double temp[15]; 7231cc31e629e8132df390ae692873c847d1c2f62c0James Dong // printf("\nLamda: "); 7241cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7251cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* parametric PREMODELling */ 7261cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 15; i++) 7271cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7281cc31e629e8132df390ae692873c847d1c2f62c0James Dong // printf("%g ",exp_lamda[i]); 7291cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (pf < 0.5) 7301cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp[i] = 1 / exp_lamda[i] * M4VENC_LOG(2 * pf); 7311cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 7321cc31e629e8132df390ae692873c847d1c2f62c0James Dong temp[i] = -1 / exp_lamda[i] * M4VENC_LOG(2 * (1 - pf)); 7331cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7341cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7351cc31e629e8132df390ae692873c847d1c2f62c0James Dong nrmlz_th[15] = 0; 7361cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 15; i++) /* scale upto no.pixels */ 7371cc31e629e8132df390ae692873c847d1c2f62c0James Dong nrmlz_th[i] = (int)(temp[i] * ((i + 1) << 4) + 0.5); 7381cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7391cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 7401cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 7411cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7421cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid HTFMPrepareCurMB_AVC(AVCEncObject *encvid, HTFM_Stat *htfm_stat, uint8 *cur, int pitch) 7431cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 7441cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 7451cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint32 *htfmMB = (uint32*)(encvid->currYMB); 7461cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *ptr, byte; 7471cc31e629e8132df390ae692873c847d1c2f62c0James Dong int *offset; 7481cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 7491cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint32 word; 7501cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7511cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (((int)video->sliceHdr->frame_num) % 30 == 1) 7521cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7531cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset = htfm_stat->offsetArray; 7541cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7551cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 7561cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7571cc31e629e8132df390ae692873c847d1c2f62c0James Dong offset = encvid->nrmlz_th + 16; 7581cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7591cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7601cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 16; i++) 7611cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 7621cc31e629e8132df390ae692873c847d1c2f62c0James Dong ptr = cur + offset[i]; 7631cc31e629e8132df390ae692873c847d1c2f62c0James Dong word = ptr[0]; 7641cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[4]; 7651cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 8); 7661cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[8]; 7671cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 16); 7681cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[12]; 7691cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 24); 7701cc31e629e8132df390ae692873c847d1c2f62c0James Dong *htfmMB++ = word; 7711cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7721cc31e629e8132df390ae692873c847d1c2f62c0James Dong word = *(ptr += (pitch << 2)); 7731cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[4]; 7741cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 8); 7751cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[8]; 7761cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 16); 7771cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[12]; 7781cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 24); 7791cc31e629e8132df390ae692873c847d1c2f62c0James Dong *htfmMB++ = word; 7801cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7811cc31e629e8132df390ae692873c847d1c2f62c0James Dong word = *(ptr += (pitch << 2)); 7821cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[4]; 7831cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 8); 7841cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[8]; 7851cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 16); 7861cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[12]; 7871cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 24); 7881cc31e629e8132df390ae692873c847d1c2f62c0James Dong *htfmMB++ = word; 7891cc31e629e8132df390ae692873c847d1c2f62c0James Dong 7901cc31e629e8132df390ae692873c847d1c2f62c0James Dong word = *(ptr += (pitch << 2)); 7911cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[4]; 7921cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 8); 7931cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[8]; 7941cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 16); 7951cc31e629e8132df390ae692873c847d1c2f62c0James Dong byte = ptr[12]; 7961cc31e629e8132df390ae692873c847d1c2f62c0James Dong word |= (byte << 24); 7971cc31e629e8132df390ae692873c847d1c2f62c0James Dong *htfmMB++ = word; 7981cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 7991cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8001cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 8011cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 8021cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8031cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8041cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif // HTFM 8051cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8061cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCPrepareCurMB(AVCEncObject *encvid, uint8 *cur, int pitch) 8071cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 8081cc31e629e8132df390ae692873c847d1c2f62c0James Dong void* tmp = (void*)(encvid->currYMB); 8091cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint32 *currYMB = (uint32*) tmp; 8101cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 8111cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8121cc31e629e8132df390ae692873c847d1c2f62c0James Dong cur -= pitch; 8131cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8141cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 16; i++) 8151cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8161cc31e629e8132df390ae692873c847d1c2f62c0James Dong *currYMB++ = *((uint32*)(cur += pitch)); 8171cc31e629e8132df390ae692873c847d1c2f62c0James Dong *currYMB++ = *((uint32*)(cur + 4)); 8181cc31e629e8132df390ae692873c847d1c2f62c0James Dong *currYMB++ = *((uint32*)(cur + 8)); 8191cc31e629e8132df390ae692873c847d1c2f62c0James Dong *currYMB++ = *((uint32*)(cur + 12)); 8201cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8221cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 8231cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 8241cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8251cc31e629e8132df390ae692873c847d1c2f62c0James Dong#ifdef FIXED_INTERPRED_MODE 8261cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8271cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* due to the complexity of the predicted motion vector, we may not decide to skip 8281cc31e629e8132df390ae692873c847d1c2f62c0James Donga macroblock here just yet. */ 8291cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* We will find the best motion vector and the best intra prediction mode for each block. */ 8301cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* output are 8311cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumMbPart, currMB->MbPartWidth, currMB->MbPartHeight, 8321cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumSubMbPart[], currMB->SubMbPartWidth[], currMB->SubMbPartHeight, 8331cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MBPartPredMode[][] (L0 or L1 or BiPred) 8341cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->RefIdx[], currMB->ref_idx_L0[], 8351cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->mvL0[], currMB->mvL1[] 8361cc31e629e8132df390ae692873c847d1c2f62c0James Dong */ 8371cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8381cc31e629e8132df390ae692873c847d1c2f62c0James DongAVCEnc_Status AVCMBMotionSearch(AVCEncObject *encvid, AVCMacroblock *currMB, int mbNum, 8391cc31e629e8132df390ae692873c847d1c2f62c0James Dong int num_pass) 8401cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 8411cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 8421cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbPartIdx, subMbPartIdx; 8431cc31e629e8132df390ae692873c847d1c2f62c0James Dong int16 *mv; 8441cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i; 8451cc31e629e8132df390ae692873c847d1c2f62c0James Dong int SubMbPartHeight, SubMbPartWidth, NumSubMbPart; 8461cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8471cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* assign value to currMB->MBPartPredMode[][x],subMbMode[],NumSubMbPart[],SubMbPartWidth[],SubMbPartHeight[] */ 8481cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8491cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->mbMode = FIXED_INTERPRED_MODE; 8501cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->mb_intra = 0; 8511cc31e629e8132df390ae692873c847d1c2f62c0James Dong 8521cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (currMB->mbMode == AVC_P16) 8531cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8541cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumMbPart = 1; 8551cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartWidth = 16; 8561cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartHeight = 16; 8571cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartHeight[0] = 16; 8581cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartWidth[0] = 16; 8591cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumSubMbPart[0] = 1; 8601cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8611cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (currMB->mbMode == AVC_P16x8) 8621cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8631cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumMbPart = 2; 8641cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartWidth = 16; 8651cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartHeight = 8; 8661cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 2; i++) 8671cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8681cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartWidth[i] = 16; 8691cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartHeight[i] = 8; 8701cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumSubMbPart[i] = 1; 8711cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8721cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8731cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (currMB->mbMode == AVC_P8x16) 8741cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8751cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumMbPart = 2; 8761cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartWidth = 8; 8771cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartHeight = 16; 8781cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 2; i++) 8791cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8801cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartWidth[i] = 8; 8811cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartHeight[i] = 16; 8821cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumSubMbPart[i] = 1; 8831cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8841cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8851cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (currMB->mbMode == AVC_P8 || currMB->mbMode == AVC_P8ref0) 8861cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8871cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumMbPart = 4; 8881cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartWidth = 8; 8891cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MbPartHeight = 8; 8901cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (FIXED_SUBMB_MODE == AVC_8x8) 8911cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8921cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartHeight = 8; 8931cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartWidth = 8; 8941cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumSubMbPart = 1; 8951cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 8961cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (FIXED_SUBMB_MODE == AVC_8x4) 8971cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 8981cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartHeight = 4; 8991cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartWidth = 8; 9001cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumSubMbPart = 2; 9011cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9021cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (FIXED_SUBMB_MODE == AVC_4x8) 9031cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9041cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartHeight = 8; 9051cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartWidth = 4; 9061cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumSubMbPart = 2; 9071cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9081cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (FIXED_SUBMB_MODE == AVC_4x4) 9091cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9101cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartHeight = 4; 9111cc31e629e8132df390ae692873c847d1c2f62c0James Dong SubMbPartWidth = 4; 9121cc31e629e8132df390ae692873c847d1c2f62c0James Dong NumSubMbPart = 4; 9131cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9141cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9151cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 4; i++) 9161cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9171cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->subMbMode[i] = FIXED_SUBMB_MODE; 9181cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartHeight[i] = SubMbPartHeight; 9191cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartWidth[i] = SubMbPartWidth; 9201cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumSubMbPart[i] = NumSubMbPart; 9211cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9221cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9231cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* it's probably intra mode */ 9241cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9251cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_SUCCESS; 9261cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9271cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9281cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++) 9291cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9301cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->MBPartPredMode[mbPartIdx][0] = AVC_Pred_L0; 9311cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->ref_idx_L0[mbPartIdx] = FIXED_REF_IDX; 9321cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->RefIdx[mbPartIdx] = video->RefPicList0[FIXED_REF_IDX]->RefIdx; 9331cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9341cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (subMbPartIdx = 0; subMbPartIdx < 4; subMbPartIdx++) 9351cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 9361cc31e629e8132df390ae692873c847d1c2f62c0James Dong mv = (int16*)(currMB->mvL0 + (mbPartIdx << 2) + subMbPartIdx); 9371cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9381cc31e629e8132df390ae692873c847d1c2f62c0James Dong *mv++ = FIXED_MVX; 9391cc31e629e8132df390ae692873c847d1c2f62c0James Dong *mv = FIXED_MVY; 9401cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9411cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 9421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9431cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->min_cost = 0; 9441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9451cc31e629e8132df390ae692873c847d1c2f62c0James Dong return AVCENC_SUCCESS; 9461cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 9471cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9481cc31e629e8132df390ae692873c847d1c2f62c0James Dong#else /* perform the search */ 9491cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9501cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* This option #1 search is very similar to PV's MPEG4 motion search algorithm. 9511cc31e629e8132df390ae692873c847d1c2f62c0James Dong The search is done in hierarchical manner from 16x16 MB down to smaller and smaller 9521cc31e629e8132df390ae692873c847d1c2f62c0James Dong partition. At each level, a decision can be made to stop the search if the expected 9531cc31e629e8132df390ae692873c847d1c2f62c0James Dong prediction gain is not worth the computation. The decision can also be made at the finest 9541cc31e629e8132df390ae692873c847d1c2f62c0James Dong level for more fullsearch-like behavior with the price of heavier computation. */ 9551cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCMBMotionSearch(AVCEncObject *encvid, uint8 *cur, uint8 *best_cand[], 9561cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i0, int j0, int type_pred, int FS_en, int *hp_guess) 9571cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 9581cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 9591cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCPictureData *currPic = video->currPic; 9601cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCSeqParamSet *currSPS = video->currSeqParams; 9611cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCRateControl *rateCtrl = encvid->rateCtrl; 9621cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMacroblock *currMB = video->currMB; 9631cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *ref, *cand, *ncand; 9641cc31e629e8132df390ae692873c847d1c2f62c0James Dong void *extra_info = encvid->sad_extra_info; 9651cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbnum = video->mbNum; 9661cc31e629e8132df390ae692873c847d1c2f62c0James Dong int width = currPic->width; /* 6/12/01, must be multiple of 16 */ 9671cc31e629e8132df390ae692873c847d1c2f62c0James Dong int height = currPic->height; 9681cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMV *mot16x16 = encvid->mot16x16; 9691cc31e629e8132df390ae692873c847d1c2f62c0James Dong int (*SAD_Macroblock)(uint8*, uint8*, int, void*) = encvid->functionPointer->SAD_Macroblock; 9701cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9711cc31e629e8132df390ae692873c847d1c2f62c0James Dong int range = rateCtrl->mvRange; 9721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9731cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lx = currPic->pitch; /* padding */ 9741cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i, j, imin, jmin, ilow, ihigh, jlow, jhigh; 9751cc31e629e8132df390ae692873c847d1c2f62c0James Dong int d, dmin, dn[9]; 9761cc31e629e8132df390ae692873c847d1c2f62c0James Dong int k; 9771cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mvx[5], mvy[5]; 9781cc31e629e8132df390ae692873c847d1c2f62c0James Dong int num_can, center_again; 9791cc31e629e8132df390ae692873c847d1c2f62c0James Dong int last_loc, new_loc = 0; 9801cc31e629e8132df390ae692873c847d1c2f62c0James Dong int step, max_step = range >> 1; 9811cc31e629e8132df390ae692873c847d1c2f62c0James Dong int next; 9821cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9831cc31e629e8132df390ae692873c847d1c2f62c0James Dong int cmvx, cmvy; /* estimated predicted MV */ 9841cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lev_idx; 9851cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lambda_motion = encvid->lambda_motion; 9861cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *mvbits = encvid->mvbits; 9871cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mvshift = 2; 9881cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mvcost; 9891cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9901cc31e629e8132df390ae692873c847d1c2f62c0James Dong int min_sad = 65535; 9911cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9921cc31e629e8132df390ae692873c847d1c2f62c0James Dong ref = video->RefPicList0[DEFAULT_REF_IDX]->Sl; /* origin of actual frame */ 9931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 9941cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* have to initialize these params, necessary for interprediction part */ 9951cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumMbPart = 1; 9961cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartHeight[0] = 16; 9971cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->SubMbPartWidth[0] = 16; 9981cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->NumSubMbPart[0] = 1; 9991cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->ref_idx_L0[0] = currMB->ref_idx_L0[1] = 10001cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->ref_idx_L0[2] = currMB->ref_idx_L0[3] = DEFAULT_REF_IDX; 10011cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->ref_idx_L1[0] = currMB->ref_idx_L1[1] = 10021cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->ref_idx_L1[2] = currMB->ref_idx_L1[3] = DEFAULT_REF_IDX; 10031cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->RefIdx[0] = currMB->RefIdx[1] = 10041cc31e629e8132df390ae692873c847d1c2f62c0James Dong currMB->RefIdx[2] = currMB->RefIdx[3] = video->RefPicList0[DEFAULT_REF_IDX]->RefIdx; 10051cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10061cc31e629e8132df390ae692873c847d1c2f62c0James Dong cur = encvid->currYMB; /* use smaller memory space for current MB */ 10071cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10081cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* find limit of the search (adjusting search range)*/ 10091cc31e629e8132df390ae692873c847d1c2f62c0James Dong lev_idx = mapLev2Idx[currSPS->level_idc]; 10101cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10111cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* we can make this part dynamic based on previous statistics */ 10121cc31e629e8132df390ae692873c847d1c2f62c0James Dong ilow = i0 - range; 10131cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i0 - ilow > 2047) /* clip to conform with the standard */ 10141cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10151cc31e629e8132df390ae692873c847d1c2f62c0James Dong ilow = i0 - 2047; 10161cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10171cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (ilow < -13) // change it from -15 to -13 because of 6-tap filter needs extra 2 lines. 10181cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10191cc31e629e8132df390ae692873c847d1c2f62c0James Dong ilow = -13; 10201cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10221cc31e629e8132df390ae692873c847d1c2f62c0James Dong ihigh = i0 + range - 1; 10231cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (ihigh - i0 > 2047) /* clip to conform with the standard */ 10241cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10251cc31e629e8132df390ae692873c847d1c2f62c0James Dong ihigh = i0 + 2047; 10261cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10271cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (ihigh > width - 3) 10281cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10291cc31e629e8132df390ae692873c847d1c2f62c0James Dong ihigh = width - 3; // change from width-1 to width-3 for the same reason as above 10301cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10311cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10321cc31e629e8132df390ae692873c847d1c2f62c0James Dong jlow = j0 - range; 10331cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (j0 - jlow > MaxVmvR[lev_idx] - 1) /* clip to conform with the standard */ 10341cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10351cc31e629e8132df390ae692873c847d1c2f62c0James Dong jlow = j0 - MaxVmvR[lev_idx] + 1; 10361cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10371cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jlow < -13) // same reason as above 10381cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10391cc31e629e8132df390ae692873c847d1c2f62c0James Dong jlow = -13; 10401cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10411cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10421cc31e629e8132df390ae692873c847d1c2f62c0James Dong jhigh = j0 + range - 1; 10431cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jhigh - j0 > MaxVmvR[lev_idx] - 1) /* clip to conform with the standard */ 10441cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10451cc31e629e8132df390ae692873c847d1c2f62c0James Dong jhigh = j0 + MaxVmvR[lev_idx] - 1; 10461cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10471cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jhigh > height - 3) // same reason as above 10481cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10491cc31e629e8132df390ae692873c847d1c2f62c0James Dong jhigh = height - 3; 10501cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10511cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10521cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* find initial motion vector & predicted MV*/ 10531cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCandidateSelection(mvx, mvy, &num_can, i0 >> 4, j0 >> 4, encvid, type_pred, &cmvx, &cmvy); 10541cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10551cc31e629e8132df390ae692873c847d1c2f62c0James Dong imin = i0; 10561cc31e629e8132df390ae692873c847d1c2f62c0James Dong jmin = j0; /* needed for fullsearch */ 10571cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = ref + i0 + j0 * lx; 10581cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10591cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* for first row of MB, fullsearch can be used */ 10601cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (FS_en) 10611cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10621cc31e629e8132df390ae692873c847d1c2f62c0James Dong *hp_guess = 0; /* no guess for fast half-pel */ 10631cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10641cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = AVCFullSearch(encvid, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh, cmvx, cmvy); 10651cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10661cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = ref + imin + jmin * lx; 10671cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10681cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 10691cc31e629e8132df390ae692873c847d1c2f62c0James Dong { /* fullsearch the top row to only upto (0,3) MB */ 10701cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* upto 30% complexity saving with the same complexity */ 10711cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (video->PrevRefFrameNum == 0 && j0 == 0 && i0 <= 64 && type_pred != 1) 10721cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10731cc31e629e8132df390ae692873c847d1c2f62c0James Dong *hp_guess = 0; /* no guess for fast half-pel */ 10741cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = AVCFullSearch(encvid, ref, cur, &imin, &jmin, ilow, ihigh, jlow, jhigh, cmvx, cmvy); 10751cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = ref + imin + jmin * lx; 10761cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 10771cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 10781cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10791cc31e629e8132df390ae692873c847d1c2f62c0James Dong /************** initialize candidate **************************/ 10801cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10811cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = 65535; 10821cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10831cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* check if all are equal */ 10841cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (num_can == ALL_CAND_EQUAL) 10851cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10861cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = i0 + mvx[0]; 10871cc31e629e8132df390ae692873c847d1c2f62c0James Dong j = j0 + mvy[0]; 10881cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10891cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh) 10901cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10911cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand = ref + i + j * lx; 10921cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10931cc31e629e8132df390ae692873c847d1c2f62c0James Dong d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info); 10941cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy); 10951cc31e629e8132df390ae692873c847d1c2f62c0James Dong d += mvcost; 10961cc31e629e8132df390ae692873c847d1c2f62c0James Dong 10971cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (d < dmin) 10981cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 10991cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = d; 11001cc31e629e8132df390ae692873c847d1c2f62c0James Dong imin = i; 11011cc31e629e8132df390ae692873c847d1c2f62c0James Dong jmin = j; 11021cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = cand; 11031cc31e629e8132df390ae692873c847d1c2f62c0James Dong min_sad = d - mvcost; // for rate control 11041cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11051cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11061cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11071cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 11081cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11091cc31e629e8132df390ae692873c847d1c2f62c0James Dong /************** evaluate unique candidates **********************/ 11101cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (k = 0; k < num_can; k++) 11111cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11121cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = i0 + mvx[k]; 11131cc31e629e8132df390ae692873c847d1c2f62c0James Dong j = j0 + mvy[k]; 11141cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11151cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh) 11161cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11171cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand = ref + i + j * lx; 11181cc31e629e8132df390ae692873c847d1c2f62c0James Dong d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info); 11191cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy); 11201cc31e629e8132df390ae692873c847d1c2f62c0James Dong d += mvcost; 11211cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11221cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (d < dmin) 11231cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11241cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = d; 11251cc31e629e8132df390ae692873c847d1c2f62c0James Dong imin = i; 11261cc31e629e8132df390ae692873c847d1c2f62c0James Dong jmin = j; 11271cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = cand; 11281cc31e629e8132df390ae692873c847d1c2f62c0James Dong min_sad = d - mvcost; // for rate control 11291cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11301cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11311cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11321cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11331cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11341cc31e629e8132df390ae692873c847d1c2f62c0James Dong /******************* local refinement ***************************/ 11351cc31e629e8132df390ae692873c847d1c2f62c0James Dong center_again = 0; 11361cc31e629e8132df390ae692873c847d1c2f62c0James Dong last_loc = new_loc = 0; 11371cc31e629e8132df390ae692873c847d1c2f62c0James Dong // ncand = ref + jmin*lx + imin; /* center of the search */ 11381cc31e629e8132df390ae692873c847d1c2f62c0James Dong step = 0; 11391cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[0] = dmin; 11401cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (!center_again && step <= max_step) 11411cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11421cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11431cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMoveNeighborSAD(dn, last_loc); 11441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11451cc31e629e8132df390ae692873c847d1c2f62c0James Dong center_again = 1; 11461cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = imin; 11471cc31e629e8132df390ae692873c847d1c2f62c0James Dong j = jmin - 1; 11481cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand = ref + i + j * lx; 11491cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11501cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* starting from [0,-1] */ 11511cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* spiral check one step at a time*/ 11521cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (k = 2; k <= 8; k += 2) 11531cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11541cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!tab_exclude[last_loc][k]) /* exclude last step computation */ 11551cc31e629e8132df390ae692873c847d1c2f62c0James Dong { /* not already computed */ 11561cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh) 11571cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11581cc31e629e8132df390ae692873c847d1c2f62c0James Dong d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, extra_info); 11591cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy); 11601cc31e629e8132df390ae692873c847d1c2f62c0James Dong d += mvcost; 11611cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11621cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[k] = d; /* keep it for half pel use */ 11631cc31e629e8132df390ae692873c847d1c2f62c0James Dong 11641cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (d < dmin) 11651cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11661cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = cand; 11671cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = d; 11681cc31e629e8132df390ae692873c847d1c2f62c0James Dong imin = i; 11691cc31e629e8132df390ae692873c847d1c2f62c0James Dong jmin = j; 11701cc31e629e8132df390ae692873c847d1c2f62c0James Dong center_again = 0; 11711cc31e629e8132df390ae692873c847d1c2f62c0James Dong new_loc = k; 11721cc31e629e8132df390ae692873c847d1c2f62c0James Dong min_sad = d - mvcost; // for rate control 11731cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11741cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11751cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11761cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (k == 8) /* end side search*/ 11771cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11781cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!center_again) 11791cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11801cc31e629e8132df390ae692873c847d1c2f62c0James Dong k = -1; /* start diagonal search */ 11811cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand -= lx; 11821cc31e629e8132df390ae692873c847d1c2f62c0James Dong j--; 11831cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11841cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11851cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 11861cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 11871cc31e629e8132df390ae692873c847d1c2f62c0James Dong next = refine_next[k][0]; 11881cc31e629e8132df390ae692873c847d1c2f62c0James Dong i += next; 11891cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand += next; 11901cc31e629e8132df390ae692873c847d1c2f62c0James Dong next = refine_next[k][1]; 11911cc31e629e8132df390ae692873c847d1c2f62c0James Dong j += next; 11921cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand += lx * next; 11931cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11941cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11951cc31e629e8132df390ae692873c847d1c2f62c0James Dong last_loc = new_loc; 11961cc31e629e8132df390ae692873c847d1c2f62c0James Dong step ++; 11971cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 11981cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!center_again) 11991cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMoveNeighborSAD(dn, last_loc); 12001cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12011cc31e629e8132df390ae692873c847d1c2f62c0James Dong *hp_guess = AVCFindMin(dn); 12021cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12031cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->rateCtrl->MADofMB[mbnum] = min_sad / 256.0; 12041cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12051cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12061cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12071cc31e629e8132df390ae692873c847d1c2f62c0James Dong mot16x16[mbnum].sad = dmin; 12081cc31e629e8132df390ae692873c847d1c2f62c0James Dong mot16x16[mbnum].x = (imin - i0) << 2; 12091cc31e629e8132df390ae692873c847d1c2f62c0James Dong mot16x16[mbnum].y = (jmin - j0) << 2; 12101cc31e629e8132df390ae692873c847d1c2f62c0James Dong best_cand[0] = ncand; 12111cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12121cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (rateCtrl->subPelEnable) // always enable half-pel search 12131cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 12141cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* find half-pel resolution motion vector */ 12151cc31e629e8132df390ae692873c847d1c2f62c0James Dong min_sad = AVCFindHalfPelMB(encvid, cur, mot16x16 + mbnum, best_cand[0], i0, j0, *hp_guess, cmvx, cmvy); 12161cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12171cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->rateCtrl->MADofMB[mbnum] = min_sad / 256.0; 12181cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12191cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12201cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (encvid->best_qpel_pos == -1) 12211cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 12221cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = encvid->hpel_cand[encvid->best_hpel_pos]; 12231cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12241cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 12251cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 12261cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand = encvid->qpel_cand[encvid->best_qpel_pos]; 12271cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12281cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12291cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 12301cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 12311cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->rateCtrl->MADofMB[mbnum] = min_sad / 256.0; 12321cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12331cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12341cc31e629e8132df390ae692873c847d1c2f62c0James Dong /** do motion comp here for now */ 12351cc31e629e8132df390ae692873c847d1c2f62c0James Dong ref = currPic->Sl + i0 + j0 * lx; 12361cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* copy from the best result to current Picture */ 12371cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (j = 0; j < 16; j++) 12381cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 12391cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 0; i < 16; i++) 12401cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 12411cc31e629e8132df390ae692873c847d1c2f62c0James Dong *ref++ = *ncand++; 12421cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12431cc31e629e8132df390ae692873c847d1c2f62c0James Dong ref += (lx - 16); 12441cc31e629e8132df390ae692873c847d1c2f62c0James Dong ncand += 8; 12451cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 12461cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12471cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 12481cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 12491cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12501cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif 12511cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12521cc31e629e8132df390ae692873c847d1c2f62c0James Dong/*=============================================================================== 12531cc31e629e8132df390ae692873c847d1c2f62c0James Dong Function: AVCFullSearch 12541cc31e629e8132df390ae692873c847d1c2f62c0James Dong Date: 09/16/2000 12551cc31e629e8132df390ae692873c847d1c2f62c0James Dong Purpose: Perform full-search motion estimation over the range of search 12561cc31e629e8132df390ae692873c847d1c2f62c0James Dong region in a spiral-outward manner. 12571cc31e629e8132df390ae692873c847d1c2f62c0James Dong Input/Output: VideoEncData, current Vol, previou Vop, pointer to the left corner of 12581cc31e629e8132df390ae692873c847d1c2f62c0James Dong current VOP, current coord (also output), boundaries. 12591cc31e629e8132df390ae692873c847d1c2f62c0James Dong===============================================================================*/ 12601cc31e629e8132df390ae692873c847d1c2f62c0James Dongint AVCFullSearch(AVCEncObject *encvid, uint8 *prev, uint8 *cur, 12611cc31e629e8132df390ae692873c847d1c2f62c0James Dong int *imin, int *jmin, int ilow, int ihigh, int jlow, int jhigh, 12621cc31e629e8132df390ae692873c847d1c2f62c0James Dong int cmvx, int cmvy) 12631cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 12641cc31e629e8132df390ae692873c847d1c2f62c0James Dong int range = encvid->rateCtrl->mvRange; 12651cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCPictureData *currPic = encvid->common->currPic; 12661cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *cand; 12671cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i, j, k, l; 12681cc31e629e8132df390ae692873c847d1c2f62c0James Dong int d, dmin; 12691cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i0 = *imin; /* current position */ 12701cc31e629e8132df390ae692873c847d1c2f62c0James Dong int j0 = *jmin; 12711cc31e629e8132df390ae692873c847d1c2f62c0James Dong int (*SAD_Macroblock)(uint8*, uint8*, int, void*) = encvid->functionPointer->SAD_Macroblock; 12721cc31e629e8132df390ae692873c847d1c2f62c0James Dong void *extra_info = encvid->sad_extra_info; 12731cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lx = currPic->pitch; /* with padding */ 12741cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12751cc31e629e8132df390ae692873c847d1c2f62c0James Dong int offset = i0 + j0 * lx; 12761cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12771cc31e629e8132df390ae692873c847d1c2f62c0James Dong int lambda_motion = encvid->lambda_motion; 12781cc31e629e8132df390ae692873c847d1c2f62c0James Dong uint8 *mvbits = encvid->mvbits; 12791cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mvshift = 2; 12801cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mvcost; 12811cc31e629e8132df390ae692873c847d1c2f62c0James Dong int min_sad; 12821cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12831cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand = prev + offset; 12841cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12851cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = (*SAD_Macroblock)(cand, cur, (65535 << 16) | lx, (void*)extra_info); 12861cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvcost = MV_COST(lambda_motion, mvshift, 0, 0, cmvx, cmvy); 12871cc31e629e8132df390ae692873c847d1c2f62c0James Dong min_sad = dmin; 12881cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin += mvcost; 12891cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12901cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* perform spiral search */ 12911cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (k = 1; k <= range; k++) 12921cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 12931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12941cc31e629e8132df390ae692873c847d1c2f62c0James Dong i = i0 - k; 12951cc31e629e8132df390ae692873c847d1c2f62c0James Dong j = j0 - k; 12961cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12971cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand = prev + i + j * lx; 12981cc31e629e8132df390ae692873c847d1c2f62c0James Dong 12991cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (l = 0; l < 8*k; l++) 13001cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13011cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* no need for boundary checking again */ 13021cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (i >= ilow && i <= ihigh && j >= jlow && j <= jhigh) 13031cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13041cc31e629e8132df390ae692873c847d1c2f62c0James Dong d = (*SAD_Macroblock)(cand, cur, (dmin << 16) | lx, (void*)extra_info); 13051cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvcost = MV_COST(lambda_motion, mvshift, i - i0, j - j0, cmvx, cmvy); 13061cc31e629e8132df390ae692873c847d1c2f62c0James Dong d += mvcost; 13071cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13081cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (d < dmin) 13091cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13101cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = d; 13111cc31e629e8132df390ae692873c847d1c2f62c0James Dong *imin = i; 13121cc31e629e8132df390ae692873c847d1c2f62c0James Dong *jmin = j; 13131cc31e629e8132df390ae692873c847d1c2f62c0James Dong min_sad = d - mvcost; 13141cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13151cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13161cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13171cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (l < (k << 1)) 13181cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13191cc31e629e8132df390ae692873c847d1c2f62c0James Dong i++; 13201cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand++; 13211cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13221cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (l < (k << 2)) 13231cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13241cc31e629e8132df390ae692873c847d1c2f62c0James Dong j++; 13251cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand += lx; 13261cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13271cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (l < ((k << 2) + (k << 1))) 13281cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13291cc31e629e8132df390ae692873c847d1c2f62c0James Dong i--; 13301cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand--; 13311cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13321cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 13331cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13341cc31e629e8132df390ae692873c847d1c2f62c0James Dong j--; 13351cc31e629e8132df390ae692873c847d1c2f62c0James Dong cand -= lx; 13361cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13371cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13381cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13391cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13401cc31e629e8132df390ae692873c847d1c2f62c0James Dong encvid->rateCtrl->MADofMB[encvid->common->mbNum] = (min_sad / 256.0); // for rate control 13411cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13421cc31e629e8132df390ae692873c847d1c2f62c0James Dong return dmin; 13431cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 13441cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13451cc31e629e8132df390ae692873c847d1c2f62c0James Dong/*=============================================================================== 13461cc31e629e8132df390ae692873c847d1c2f62c0James Dong Function: AVCCandidateSelection 13471cc31e629e8132df390ae692873c847d1c2f62c0James Dong Date: 09/16/2000 13481cc31e629e8132df390ae692873c847d1c2f62c0James Dong Purpose: Fill up the list of candidate using spatio-temporal correlation 13491cc31e629e8132df390ae692873c847d1c2f62c0James Dong among neighboring blocks. 13501cc31e629e8132df390ae692873c847d1c2f62c0James Dong Input/Output: type_pred = 0: first pass, 1: second pass, or no SCD 13511cc31e629e8132df390ae692873c847d1c2f62c0James Dong Modified: , 09/23/01, get rid of redundant candidates before passing back. 13521cc31e629e8132df390ae692873c847d1c2f62c0James Dong , 09/11/07, added return for modified predicted MV, this will be 13531cc31e629e8132df390ae692873c847d1c2f62c0James Dong needed for both fast search and fullsearch. 13541cc31e629e8132df390ae692873c847d1c2f62c0James Dong===============================================================================*/ 13551cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13561cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCCandidateSelection(int *mvx, int *mvy, int *num_can, int imb, int jmb, 13571cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCEncObject *encvid, int type_pred, int *cmvx, int *cmvy) 13581cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 13591cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCCommonObj *video = encvid->common; 13601cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMV *mot16x16 = encvid->mot16x16; 13611cc31e629e8132df390ae692873c847d1c2f62c0James Dong AVCMV *pmot; 13621cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbnum = video->mbNum; 13631cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbwidth = video->PicWidthInMbs; 13641cc31e629e8132df390ae692873c847d1c2f62c0James Dong int mbheight = video->PicHeightInMbs; 13651cc31e629e8132df390ae692873c847d1c2f62c0James Dong int i, j, same, num1; 13661cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13671cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* this part is for predicted MV */ 13681cc31e629e8132df390ae692873c847d1c2f62c0James Dong int pmvA_x = 0, pmvA_y = 0, pmvB_x = 0, pmvB_y = 0, pmvC_x = 0, pmvC_y = 0; 13691cc31e629e8132df390ae692873c847d1c2f62c0James Dong int availA = 0, availB = 0, availC = 0; 13701cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13711cc31e629e8132df390ae692873c847d1c2f62c0James Dong *num_can = 0; 13721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13731cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (video->PrevRefFrameNum != 0) // previous frame is an IDR frame 13741cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13751cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* Spatio-Temporal Candidate (five candidates) */ 13761cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (type_pred == 0) /* first pass */ 13771cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13781cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum]; /* same coordinate previous frame */ 13791cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 13801cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 13811cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb >= (mbwidth >> 1) && imb > 0) /*left neighbor previous frame */ 13821cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13831cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-1]; 13841cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 13851cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 13861cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13871cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (imb + 1 < mbwidth) /*right neighbor previous frame */ 13881cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13891cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum+1]; 13901cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 13911cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 13921cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 13931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 13941cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb < mbheight - 1) /*bottom neighbor previous frame */ 13951cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 13961cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum+mbwidth]; 13971cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 13981cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 13991cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14001cc31e629e8132df390ae692873c847d1c2f62c0James Dong else if (jmb > 0) /*upper neighbor previous frame */ 14011cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14021cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth]; 14031cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14041cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14051cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14061cc31e629e8132df390ae692873c847d1c2f62c0James Dong 14071cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 0 && jmb > 0) /* upper-left neighbor current frame*/ 14081cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14091cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth-1]; 14101cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14111cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14121cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14131cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0 && imb < mbheight - 1) /* upper right neighbor current frame*/ 14141cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14151cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth+1]; 14161cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14171cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14181cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14191cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14201cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* second pass */ 14211cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* original ST1 algorithm */ 14221cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14231cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum]; /* same coordinate previous frame */ 14241cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14251cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14261cc31e629e8132df390ae692873c847d1c2f62c0James Dong 14271cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 0) /*left neighbor current frame */ 14281cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14291cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-1]; 14301cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14311cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14321cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14331cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0) /*upper neighbor current frame */ 14341cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14351cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth]; 14361cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14371cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14381cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14391cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb < mbwidth - 1) /*right neighbor previous frame */ 14401cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14411cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum+1]; 14421cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14431cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14441cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14451cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb < mbheight - 1) /*bottom neighbor previous frame */ 14461cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14471cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum+mbwidth]; 14481cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14491cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14501cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14511cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14521cc31e629e8132df390ae692873c847d1c2f62c0James Dong 14531cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* get predicted MV */ 14541cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 0) /* get MV from left (A) neighbor either on current or previous frame */ 14551cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14561cc31e629e8132df390ae692873c847d1c2f62c0James Dong availA = 1; 14571cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-1]; 14581cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvA_x = pmot->x; 14591cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvA_y = pmot->y; 14601cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14611cc31e629e8132df390ae692873c847d1c2f62c0James Dong 14621cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0) /* get MV from top (B) neighbor either on current or previous frame */ 14631cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14641cc31e629e8132df390ae692873c847d1c2f62c0James Dong availB = 1; 14651cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth]; 14661cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvB_x = pmot->x; 14671cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvB_y = pmot->y; 14681cc31e629e8132df390ae692873c847d1c2f62c0James Dong 14691cc31e629e8132df390ae692873c847d1c2f62c0James Dong availC = 1; 14701cc31e629e8132df390ae692873c847d1c2f62c0James Dong 14711cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb < mbwidth - 1) /* get MV from top-right (C) neighbor of current frame */ 14721cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14731cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth+1]; 14741cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14751cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* get MV from top-left (D) neighbor of current frame */ 14761cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14771cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth-1]; 14781cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14791cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvC_x = pmot->x; 14801cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvC_y = pmot->y; 14811cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14821cc31e629e8132df390ae692873c847d1c2f62c0James Dong 14831cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14841cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* only Spatial Candidate (four candidates)*/ 14851cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14861cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (type_pred == 0) /*first pass*/ 14871cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14881cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 1) /* neighbor two blocks away to the left */ 14891cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14901cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-2]; 14911cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14921cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14931cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 14941cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 0 && jmb > 0) /* upper-left neighbor */ 14951cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 14961cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth-1]; 14971cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 14981cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 14991cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15001cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0 && imb < mbheight - 1) /* upper right neighbor */ 15011cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15021cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth+1]; 15031cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15041cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15051cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15061cc31e629e8132df390ae692873c847d1c2f62c0James Dong 15071cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* get predicted MV */ 15081cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 1) /* get MV from 2nd left (A) neighbor either of current frame */ 15091cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15101cc31e629e8132df390ae692873c847d1c2f62c0James Dong availA = 1; 15111cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-2]; 15121cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvA_x = pmot->x; 15131cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvA_y = pmot->y; 15141cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15151cc31e629e8132df390ae692873c847d1c2f62c0James Dong 15161cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0 && imb > 0) /* get MV from top-left (B) neighbor of current frame */ 15171cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15181cc31e629e8132df390ae692873c847d1c2f62c0James Dong availB = 1; 15191cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth-1]; 15201cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvB_x = pmot->x; 15211cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvB_y = pmot->y; 15221cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15231cc31e629e8132df390ae692873c847d1c2f62c0James Dong 15241cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0 && imb < mbwidth - 1) 15251cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15261cc31e629e8132df390ae692873c847d1c2f62c0James Dong availC = 1; 15271cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth+1]; 15281cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvC_x = pmot->x; 15291cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvC_y = pmot->y; 15301cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15311cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15321cc31e629e8132df390ae692873c847d1c2f62c0James Dong//#ifdef SCENE_CHANGE_DETECTION 15331cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* second pass (ST2 algorithm)*/ 15341cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 15351cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15361cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (type_pred == 1) /* 4/7/01 */ 15371cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15381cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 0) /*left neighbor current frame */ 15391cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15401cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-1]; 15411cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15421cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15431cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15441cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0) /*upper neighbor current frame */ 15451cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15461cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth]; 15471cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15481cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15491cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15501cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb < mbwidth - 1) /*right neighbor current frame */ 15511cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15521cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum+1]; 15531cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15541cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15551cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15561cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb < mbheight - 1) /*bottom neighbor current frame */ 15571cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15581cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum+mbwidth]; 15591cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15601cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15611cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15621cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15631cc31e629e8132df390ae692873c847d1c2f62c0James Dong //#else 15641cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* original ST1 algorithm */ 15651cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15661cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 0) /*left neighbor current frame */ 15671cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15681cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-1]; 15691cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15701cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15711cc31e629e8132df390ae692873c847d1c2f62c0James Dong 15721cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0) /*upper-left neighbor current frame */ 15731cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15741cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth-1]; 15751cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15761cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15771cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15781cc31e629e8132df390ae692873c847d1c2f62c0James Dong 15791cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15801cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0) /*upper neighbor current frame */ 15811cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15821cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth]; 15831cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15841cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15851cc31e629e8132df390ae692873c847d1c2f62c0James Dong 15861cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb < mbheight - 1) /*upper-right neighbor current frame */ 15871cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15881cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth+1]; 15891cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[(*num_can)] = (pmot->x) >> 2; 15901cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[(*num_can)++] = (pmot->y) >> 2; 15911cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15921cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15931cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 15941cc31e629e8132df390ae692873c847d1c2f62c0James Dong 15951cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* get predicted MV */ 15961cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb > 0) /* get MV from left (A) neighbor either on current or previous frame */ 15971cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 15981cc31e629e8132df390ae692873c847d1c2f62c0James Dong availA = 1; 15991cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-1]; 16001cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvA_x = pmot->x; 16011cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvA_y = pmot->y; 16021cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16031cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16041cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (jmb > 0) /* get MV from top (B) neighbor either on current or previous frame */ 16051cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16061cc31e629e8132df390ae692873c847d1c2f62c0James Dong availB = 1; 16071cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth]; 16081cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvB_x = pmot->x; 16091cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvB_y = pmot->y; 16101cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16111cc31e629e8132df390ae692873c847d1c2f62c0James Dong availC = 1; 16121cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16131cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (imb < mbwidth - 1) /* get MV from top-right (C) neighbor of current frame */ 16141cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16151cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth+1]; 16161cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16171cc31e629e8132df390ae692873c847d1c2f62c0James Dong else /* get MV from top-left (D) neighbor of current frame */ 16181cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16191cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmot = &mot16x16[mbnum-mbwidth-1]; 16201cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16211cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvC_x = pmot->x; 16221cc31e629e8132df390ae692873c847d1c2f62c0James Dong pmvC_y = pmot->y; 16231cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16241cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16251cc31e629e8132df390ae692873c847d1c2f62c0James Dong//#endif 16261cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16271cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16281cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* 3/23/01, remove redundant candidate (possible k-mean) */ 16291cc31e629e8132df390ae692873c847d1c2f62c0James Dong num1 = *num_can; 16301cc31e629e8132df390ae692873c847d1c2f62c0James Dong *num_can = 1; 16311cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 1; i < num1; i++) 16321cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16331cc31e629e8132df390ae692873c847d1c2f62c0James Dong same = 0; 16341cc31e629e8132df390ae692873c847d1c2f62c0James Dong j = 0; 16351cc31e629e8132df390ae692873c847d1c2f62c0James Dong while (!same && j < *num_can) 16361cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16371cc31e629e8132df390ae692873c847d1c2f62c0James Dong#if (CANDIDATE_DISTANCE==0) 16381cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (mvx[i] == mvx[j] && mvy[i] == mvy[j]) 16391cc31e629e8132df390ae692873c847d1c2f62c0James Dong#else 16401cc31e629e8132df390ae692873c847d1c2f62c0James Dong // modified k-mean, 3/24/01, shouldn't be greater than 3 16411cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (AVC_ABS(mvx[i] - mvx[j]) + AVC_ABS(mvy[i] - mvy[j]) < CANDIDATE_DISTANCE) 16421cc31e629e8132df390ae692873c847d1c2f62c0James Dong#endif 16431cc31e629e8132df390ae692873c847d1c2f62c0James Dong same = 1; 16441cc31e629e8132df390ae692873c847d1c2f62c0James Dong j++; 16451cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16461cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (!same) 16471cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16481cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvx[*num_can] = mvx[i]; 16491cc31e629e8132df390ae692873c847d1c2f62c0James Dong mvy[*num_can] = mvy[i]; 16501cc31e629e8132df390ae692873c847d1c2f62c0James Dong (*num_can)++; 16511cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16521cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16531cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16541cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (num1 == 5 && *num_can == 1) 16551cc31e629e8132df390ae692873c847d1c2f62c0James Dong *num_can = ALL_CAND_EQUAL; /* all are equal */ 16561cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16571cc31e629e8132df390ae692873c847d1c2f62c0James Dong /* calculate predicted MV */ 16581cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16591cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (availA && !(availB || availC)) 16601cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16611cc31e629e8132df390ae692873c847d1c2f62c0James Dong *cmvx = pmvA_x; 16621cc31e629e8132df390ae692873c847d1c2f62c0James Dong *cmvy = pmvA_y; 16631cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16641cc31e629e8132df390ae692873c847d1c2f62c0James Dong else 16651cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16661cc31e629e8132df390ae692873c847d1c2f62c0James Dong *cmvx = AVC_MEDIAN(pmvA_x, pmvB_x, pmvC_x); 16671cc31e629e8132df390ae692873c847d1c2f62c0James Dong *cmvy = AVC_MEDIAN(pmvA_y, pmvB_y, pmvC_y); 16681cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 16691cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16701cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 16711cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 16721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16731cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16741cc31e629e8132df390ae692873c847d1c2f62c0James Dong/************************************************************* 16751cc31e629e8132df390ae692873c847d1c2f62c0James Dong Function: AVCMoveNeighborSAD 16761cc31e629e8132df390ae692873c847d1c2f62c0James Dong Date: 3/27/01 16771cc31e629e8132df390ae692873c847d1c2f62c0James Dong Purpose: Move neighboring SAD around when center has shifted 16781cc31e629e8132df390ae692873c847d1c2f62c0James Dong*************************************************************/ 16791cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16801cc31e629e8132df390ae692873c847d1c2f62c0James Dongvoid AVCMoveNeighborSAD(int dn[], int new_loc) 16811cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 16821cc31e629e8132df390ae692873c847d1c2f62c0James Dong int tmp[9]; 16831cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[0] = dn[0]; 16841cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[1] = dn[1]; 16851cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[2] = dn[2]; 16861cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[3] = dn[3]; 16871cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[4] = dn[4]; 16881cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[5] = dn[5]; 16891cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[6] = dn[6]; 16901cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[7] = dn[7]; 16911cc31e629e8132df390ae692873c847d1c2f62c0James Dong tmp[8] = dn[8]; 16921cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[0] = dn[1] = dn[2] = dn[3] = dn[4] = dn[5] = dn[6] = dn[7] = dn[8] = 65536; 16931cc31e629e8132df390ae692873c847d1c2f62c0James Dong 16941cc31e629e8132df390ae692873c847d1c2f62c0James Dong switch (new_loc) 16951cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 16961cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 0: 16971cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 16981cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 1: 16991cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[4] = tmp[2]; 17001cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[5] = tmp[0]; 17011cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[6] = tmp[8]; 17021cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17031cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 2: 17041cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[4] = tmp[3]; 17051cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[5] = tmp[4]; 17061cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[6] = tmp[0]; 17071cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[7] = tmp[8]; 17081cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[8] = tmp[1]; 17091cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17101cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 3: 17111cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[6] = tmp[4]; 17121cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[7] = tmp[0]; 17131cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[8] = tmp[2]; 17141cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17151cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 4: 17161cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[1] = tmp[2]; 17171cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[2] = tmp[3]; 17181cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[6] = tmp[5]; 17191cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[7] = tmp[6]; 17201cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[8] = tmp[0]; 17211cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17221cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 5: 17231cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[1] = tmp[0]; 17241cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[2] = tmp[4]; 17251cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[8] = tmp[6]; 17261cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17271cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 6: 17281cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[1] = tmp[8]; 17291cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[2] = tmp[0]; 17301cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[3] = tmp[4]; 17311cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[4] = tmp[5]; 17321cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[8] = tmp[7]; 17331cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17341cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 7: 17351cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[2] = tmp[8]; 17361cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[3] = tmp[0]; 17371cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[4] = tmp[6]; 17381cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17391cc31e629e8132df390ae692873c847d1c2f62c0James Dong case 8: 17401cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[2] = tmp[1]; 17411cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[3] = tmp[2]; 17421cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[4] = tmp[0]; 17431cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[5] = tmp[6]; 17441cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[6] = tmp[7]; 17451cc31e629e8132df390ae692873c847d1c2f62c0James Dong break; 17461cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 17471cc31e629e8132df390ae692873c847d1c2f62c0James Dong dn[0] = tmp[new_loc]; 17481cc31e629e8132df390ae692873c847d1c2f62c0James Dong 17491cc31e629e8132df390ae692873c847d1c2f62c0James Dong return ; 17501cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 17511cc31e629e8132df390ae692873c847d1c2f62c0James Dong 17521cc31e629e8132df390ae692873c847d1c2f62c0James Dong/* 3/28/01, find minimal of dn[9] */ 17531cc31e629e8132df390ae692873c847d1c2f62c0James Dong 17541cc31e629e8132df390ae692873c847d1c2f62c0James Dongint AVCFindMin(int dn[]) 17551cc31e629e8132df390ae692873c847d1c2f62c0James Dong{ 17561cc31e629e8132df390ae692873c847d1c2f62c0James Dong int min, i; 17571cc31e629e8132df390ae692873c847d1c2f62c0James Dong int dmin; 17581cc31e629e8132df390ae692873c847d1c2f62c0James Dong 17591cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = dn[1]; 17601cc31e629e8132df390ae692873c847d1c2f62c0James Dong min = 1; 17611cc31e629e8132df390ae692873c847d1c2f62c0James Dong for (i = 2; i < 9; i++) 17621cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 17631cc31e629e8132df390ae692873c847d1c2f62c0James Dong if (dn[i] < dmin) 17641cc31e629e8132df390ae692873c847d1c2f62c0James Dong { 17651cc31e629e8132df390ae692873c847d1c2f62c0James Dong dmin = dn[i]; 17661cc31e629e8132df390ae692873c847d1c2f62c0James Dong min = i; 17671cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 17681cc31e629e8132df390ae692873c847d1c2f62c0James Dong } 17691cc31e629e8132df390ae692873c847d1c2f62c0James Dong 17701cc31e629e8132df390ae692873c847d1c2f62c0James Dong return min; 17711cc31e629e8132df390ae692873c847d1c2f62c0James Dong} 17721cc31e629e8132df390ae692873c847d1c2f62c0James Dong 17731cc31e629e8132df390ae692873c847d1c2f62c0James Dong 17741cc31e629e8132df390ae692873c847d1c2f62c0James Dong 1775