[svn] / branches / dev-api-3 / xvidcore / src / motion / motion_est.c Repository:
ViewVC logotype

Diff of /branches/dev-api-3/xvidcore/src/motion/motion_est.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 835, Wed Feb 12 12:16:50 2003 UTC revision 836, Wed Feb 12 12:57:27 2003 UTC
# Line 44  Line 44 
44  #include "motion.h"  #include "motion.h"
45  #include "sad.h"  #include "sad.h"
46  #include "../utils/emms.h"  #include "../utils/emms.h"
47    #include "../dct/fdct.h"
48    
49  #define INITIAL_SKIP_THRESH     (10)  #define INITIAL_SKIP_THRESH     (10)
50  #define FINAL_SKIP_THRESH       (50)  #define FINAL_SKIP_THRESH       (50)
51  #define MAX_SAD00_FOR_SKIP      (20)  #define MAX_SAD00_FOR_SKIP      (20)
52  #define MAX_CHROMA_SAD_FOR_SKIP (22)  #define MAX_CHROMA_SAD_FOR_SKIP (22)
53    
54  #define CHECK_CANDIDATE(X,Y,D) { CheckCandidate((X),(Y), (D), &iDirection, data ); }  #define CHECK_CANDIDATE(X,Y,D) { \
55    CheckCandidate((X),(Y), (D), &iDirection, data ); }
56    
57  static __inline uint32_t  static __inline uint32_t
58  d_mv_bits(int x, int y, const VECTOR pred, const uint32_t iFcode, const int qpel, const int rrv)  d_mv_bits(int x, int y, const VECTOR pred, const uint32_t iFcode, const int qpel, const int rrv)
# Line 437  Line 439 
439          if (data->chroma) sad += ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3],          if (data->chroma) sad += ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3],
440                                                                                  (yc >> 1) + roundtab_79[yc & 0x3], data);                                                                                  (yc >> 1) + roundtab_79[yc & 0x3], data);
441    
   
442          if (sad < *(data->iMinSAD)) {          if (sad < *(data->iMinSAD)) {
443                  *(data->iMinSAD) = sad;                  *(data->iMinSAD) = sad;
444                  current->x = x; current->y = y;                  current->x = x; current->y = y;
# Line 629  Line 630 
630          }          }
631  }  }
632    
633    
634    static void
635    CheckCandidateBits16(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)
636    {
637    
638            static int16_t in[64], coeff[64];
639            int32_t bits = 0, sum;
640            VECTOR * current;
641            const uint8_t * ptr;
642            int i, cbp = 0, t, xc, yc;
643    
644            if ( (x > data->max_dx) || (x < data->min_dx)
645                    || (y > data->max_dy) || (y < data->min_dy) ) return;
646    
647            if (!data->qpel_precision) {
648                    ptr = GetReference(x, y, data);
649                    current = data->currentMV;
650                    xc = x; yc = y;
651            } else { // x and y are in 1/4 precision
652                    ptr = Interpolate16x16qpel(x, y, 0, data);
653                    current = data->currentQMV;
654                    xc = x/2; yc = y/2;
655            }
656    
657            for(i = 0; i < 4; i++) {
658                    int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);
659                    transfer_8to16subro(in, data->Cur + s, ptr + s, data->iEdgedWidth);
660                    fdct(in);
661                    if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);
662                    else sum = quant4_inter(coeff, in, data->lambda16);
663                    if (sum > 0) {
664                            cbp |= 1 << (5 - i);
665                            bits += data->temp[i] = CodeCoeffInter_CalcBits(coeff, scan_tables[0]);
666                    } else data->temp[i] = 0;
667            }
668    
669            bits += t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0);
670    
671            if (bits < data->iMinSAD[0]) { // there is still a chance, adding chroma
672                    xc = (xc >> 1) + roundtab_79[xc & 0x3];
673                    yc = (yc >> 1) + roundtab_79[yc & 0x3];
674    
675                    //chroma U
676                    ptr = interpolate8x8_switch2(data->RefQ + 64, data->RefCU, 0, 0, xc, yc,  data->iEdgedWidth/2, data->rounding);
677                    transfer_8to16subro(in, ptr, data->CurU, data->iEdgedWidth/2);
678                    fdct(in);
679                    if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);
680                    else sum = quant4_inter(coeff, in, data->lambda16);
681                    if (sum > 0) {
682                            cbp |= 1 << (5 - 4);
683                            bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);
684                    }
685    
686                    if (bits < data->iMinSAD[0]) {
687                            //chroma V
688                            ptr = interpolate8x8_switch2(data->RefQ + 64, data->RefCV, 0, 0, xc, yc,  data->iEdgedWidth/2, data->rounding);
689                            transfer_8to16subro(in, ptr, data->CurV, data->iEdgedWidth/2);
690                            fdct(in);
691                            if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);
692                            else sum = quant4_inter(coeff, in, data->lambda16);
693                            if (sum > 0) {
694                                    cbp |= 1 << (5 - 5);
695                                    bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);
696                            }
697                    }
698            }
699    
700            bits += cbpy_tab[15-(cbp>>2)].len;
701            bits += mcbpc_inter_tab[(MODE_INTER & 7) | ((cbp & 3) << 3)].len;
702    
703            if (bits < data->iMinSAD[0]) {
704                    data->iMinSAD[0] = bits;
705                    current[0].x = x; current[0].y = y;
706                    *dir = Direction;
707            }
708    
709            if (data->temp[0] + t < data->iMinSAD[1]) {
710                    data->iMinSAD[1] = data->temp[0] + t; current[1].x = x; current[1].y = y; }
711            if (data->temp[1] < data->iMinSAD[2]) {
712                    data->iMinSAD[2] = data->temp[1]; current[2].x = x; current[2].y = y; }
713            if (data->temp[2] < data->iMinSAD[3]) {
714                    data->iMinSAD[3] = data->temp[2]; current[3].x = x; current[3].y = y; }
715            if (data->temp[3] < data->iMinSAD[4]) {
716                    data->iMinSAD[4] = data->temp[3]; current[4].x = x; current[4].y = y; }
717    
718    }
719    static void
720    CheckCandidateBits8(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)
721    {
722    
723            static int16_t in[64], coeff[64];
724            int32_t sum, bits;
725            VECTOR * current;
726            const uint8_t * ptr;
727            int cbp;
728    
729            if ( (x > data->max_dx) || (x < data->min_dx)
730                    || (y > data->max_dy) || (y < data->min_dy) ) return;
731    
732            if (!data->qpel_precision) {
733                    ptr = GetReference(x, y, data);
734                    current = data->currentMV;
735            } else { // x and y are in 1/4 precision
736                    ptr = Interpolate8x8qpel(x, y, 0, 0, data);
737                    current = data->currentQMV;
738            }
739    
740            transfer_8to16subro(in, data->Cur, ptr, data->iEdgedWidth);
741            fdct(in);
742            if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);
743            else sum = quant4_inter(coeff, in, data->lambda16);
744            if (sum > 0) {
745                    bits = CodeCoeffInter_CalcBits(coeff, scan_tables[0]);
746                    cbp = 1;
747            } else cbp = bits = 0;
748    
749            bits += sum = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0);
750    
751            if (bits < data->iMinSAD[0]) {
752                    data->temp[0] = cbp;
753                    data->iMinSAD[0] = bits;
754                    current[0].x = x; current[0].y = y;
755                    *dir = Direction;
756            }
757    }
758    
759  /* CHECK_CANDIATE FUNCTIONS END */  /* CHECK_CANDIATE FUNCTIONS END */
760    
761  /* MAINSEARCH FUNCTIONS START */  /* MAINSEARCH FUNCTIONS START */
# Line 844  Line 971 
971          uint32_t mb_width = pParam->mb_width;          uint32_t mb_width = pParam->mb_width;
972          uint32_t mb_height = pParam->mb_height;          uint32_t mb_height = pParam->mb_height;
973          const uint32_t iEdgedWidth = pParam->edged_width;          const uint32_t iEdgedWidth = pParam->edged_width;
974            const uint32_t MotionFlags = MakeGoodMotionFlags(current->motion_flags, current->global_flags);
975    
976          uint32_t x, y;          uint32_t x, y;
977          uint32_t iIntra = 0;          uint32_t iIntra = 0;
978          int32_t InterBias, quant = current->quant, sad00;          int32_t quant = current->quant, sad00;
979    
980          // some pre-initialized thingies for SearchP          // some pre-initialized thingies for SearchP
981          int32_t temp[8];          int32_t temp[8];
# Line 864  Line 992 
992          Data.iFcode = current->fcode;          Data.iFcode = current->fcode;
993          Data.rounding = pParam->m_rounding_type;          Data.rounding = pParam->m_rounding_type;
994          Data.qpel = pParam->m_quarterpel;          Data.qpel = pParam->m_quarterpel;
995          Data.chroma = current->motion_flags & PMV_CHROMA16;          Data.chroma = MotionFlags & PMV_CHROMA16;
996          Data.rrv = current->global_flags & XVID_REDUCED;          Data.rrv = current->global_flags & XVID_REDUCED;
997    
998          if ((current->global_flags & XVID_REDUCED)) {          if ((current->global_flags & XVID_REDUCED)) {
999                  mb_width = (pParam->width + 31) / 32;                  mb_width = (pParam->width + 31) / 32;
1000                  mb_height = (pParam->height + 31) / 32;                  mb_height = (pParam->height + 31) / 32;
1001                  Data.qpel = Data.chroma = 0;                  Data.qpel = 0;
1002          }          }
1003    
1004          Data.RefQ = pRefV->u; // a good place, also used in MC (for similar purpose)          Data.RefQ = pRefV->u; // a good place, also used in MC (for similar purpose)
# Line 922  Line 1050 
1050                          }                          }
1051    
1052                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
1053                                                  y, current->motion_flags, pMB->quant,                                                  y, MotionFlags, current->global_flags, pMB->quant,
1054                                                  &Data, pParam, pMBs, reference->mbs,                                                  &Data, pParam, pMBs, reference->mbs,
1055                                                  current->global_flags & XVID_INTER4V, pMB);                                                  current->global_flags & XVID_INTER4V, pMB);
1056    
1057  /* final skip decision, a.k.a. "the vector you found, really that good?" */  /* final skip decision, a.k.a. "the vector you found, really that good?" */
1058                          if (!(current->global_flags & XVID_GMC))        {                          if (!(current->global_flags & XVID_GMC))        {
1059                                  if ( (pMB->dquant == NO_CHANGE) && (sad00 < pMB->quant * MAX_SAD00_FOR_SKIP)                                  if ( pMB->dquant == NO_CHANGE && sad00 < pMB->quant * MAX_SAD00_FOR_SKIP) {
1060                                          && ((100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH * (Data.rrv ? 4:1)) )                                          if (!(current->global_flags & XVID_MODEDECISION_BITS)) {
1061                                          if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv)) {                                                  if ( (100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH * (Data.rrv ? 4:1) )
1062                                                            if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv))
1063                                                  SkipMacroblockP(pMB, sad00);                                                  SkipMacroblockP(pMB, sad00);
1064                                                  continue;                                          } else { // BITS mode decision
1065                                          }                                                  if (pMB->sad16 > 10)
1066                          }                                                          SkipMacroblockP(pMB, sad00);  // more than 10 bits would be used for this MB - skip
1067    
 /* finally, intra decision */  
   
                         InterBias = MV16_INTER_BIAS;  
                         if (pMB->quant > 8) InterBias += 100 * (pMB->quant - 8); // to make high quants work  
                         if (y != 0)  
                                 if ((pMB - pParam->mb_width)->mode == MODE_INTRA ) InterBias -= 80;  
                         if (x != 0)  
                                 if ((pMB - 1)->mode == MODE_INTRA ) InterBias -= 80;  
   
                         if (Data.chroma) InterBias += 50; // to compensate bigger SAD  
                         if (Data.rrv) InterBias *= 4;  
   
                         if (InterBias < pMB->sad16) {  
                                 int32_t deviation;  
                                 if (!Data.rrv)  
                                         deviation = dev16(pCurrent->y + (x + y * iEdgedWidth) * 16, iEdgedWidth);  
                                 else {  
                                         deviation = dev16(pCurrent->y + (x + y * iEdgedWidth) * 32, iEdgedWidth)  
                                                 + dev16(pCurrent->y + (x + y * iEdgedWidth) * 32 + 16, iEdgedWidth)  
                                                 + dev16(pCurrent->y + (x + y * iEdgedWidth) * 32 + 16 * iEdgedWidth, iEdgedWidth)  
                                                 + dev16(pCurrent->y + (x + y * iEdgedWidth) * 32 + 16 * (iEdgedWidth+1), iEdgedWidth);  
                                 }  
                                 if (deviation < (pMB->sad16 - InterBias)) {  
                                         if (++iIntra >= iLimit) return 1;  
                                         SkipMacroblockP(pMB, 0); //same thing  
                                         pMB->mode = MODE_INTRA;  
1068                                  }                                  }
1069                          }                          }
1070                  }                  }
1071                            if (pMB->mode == MODE_INTRA)
1072                                    if (++iIntra > iLimit) return 1;
1073                    }
1074          }          }
1075    
1076          if (current->global_flags & XVID_GMC )  /* GMC only for S(GMC)-VOPs */          if (current->global_flags & XVID_GMC )  /* GMC only for S(GMC)-VOPs */
1077          {          {
1078                  current->warp = GlobalMotionEst( pMBs, pParam, current, reference, pRefH, pRefV, pRefHV);                  current->warp = GlobalMotionEst( pMBs, pParam, current, reference, pRefH, pRefV, pRefHV);
1079          }          }
   
1080          return 0;          return 0;
1081  }  }
1082    
# Line 1035  Line 1140 
1140          }          }
1141  }  }
1142    
1143    static int
1144    ModeDecision(const uint32_t iQuant, SearchData * const Data,
1145                    int inter4v,
1146                    MACROBLOCK * const pMB,
1147                    const MACROBLOCK * const pMBs,
1148                    const int x, const int y,
1149                    const MBParam * const pParam,
1150                    const uint32_t MotionFlags,
1151                    const uint32_t GlobalFlags)
1152    {
1153    
1154            int mode = MODE_INTER;
1155    
1156            if (!(GlobalFlags & XVID_MODEDECISION_BITS)) { //normal, fast, SAD-based mode decision
1157                    int intra = 0;
1158                    int sad;
1159                    int InterBias = MV16_INTER_BIAS;
1160                    if (inter4v == 0 || Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] +
1161                            Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant) {
1162                                    mode = 0; //inter
1163                                    sad = Data->iMinSAD[0];
1164                    } else {
1165                            mode = MODE_INTER4V;
1166                            sad = Data->iMinSAD[1] + Data->iMinSAD[2] +
1167                                                    Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant;
1168                            Data->iMinSAD[0] = sad;
1169                    }
1170    
1171                    /* intra decision */
1172    
1173                    if (iQuant > 8) InterBias += 100 * (iQuant - 8); // to make high quants work
1174                    if (y != 0)
1175                            if ((pMB - pParam->mb_width)->mode == MODE_INTRA ) InterBias -= 80;
1176                    if (x != 0)
1177                            if ((pMB - 1)->mode == MODE_INTRA ) InterBias -= 80;
1178    
1179                    if (Data->chroma) InterBias += 50; // to compensate bigger SAD
1180                    if (Data->rrv) InterBias *= 4;
1181    
1182                    if (InterBias < pMB->sad16) {
1183                            int32_t deviation;
1184                            if (!Data->rrv) deviation = dev16(Data->Cur, Data->iEdgedWidth);
1185                            else deviation = dev16(Data->Cur, Data->iEdgedWidth) +
1186                                    dev16(Data->Cur+8, Data->iEdgedWidth) +
1187                                    dev16(Data->Cur + 8*Data->iEdgedWidth, Data->iEdgedWidth) +
1188                                    dev16(Data->Cur+8+8*Data->iEdgedWidth, Data->iEdgedWidth);
1189    
1190                            if (deviation < (sad - InterBias))  return MODE_INTRA;// intra
1191                    }
1192                    return mode;
1193    
1194            } else {
1195    
1196                    int bits, intra, i;
1197                    VECTOR backup[5], *v;
1198                    Data->lambda16 = iQuant;
1199                    Data->lambda8 = pParam->m_quant_type;
1200    
1201                    v = Data->qpel ? Data->currentQMV : Data->currentMV;
1202                    for (i = 0; i < 5; i++) {
1203                            Data->iMinSAD[i] = 256*4096;
1204                            backup[i] = v[i];
1205                    }
1206    
1207                    bits = CountMBBitsInter(Data, pMBs, x, y, pParam, MotionFlags);
1208                    if (bits == 0) return MODE_INTER; // quick stop
1209    
1210                    if (inter4v) {
1211                            int inter4v = CountMBBitsInter4v(Data, pMB, pMBs, x, y, pParam, MotionFlags, backup);
1212                            if (inter4v < bits) { Data->iMinSAD[0] = bits = inter4v; mode = MODE_INTER4V; }
1213                    }
1214    
1215    
1216                    intra = CountMBBitsIntra(Data);
1217    
1218                    if (intra < bits) { *Data->iMinSAD = bits = intra; return MODE_INTRA; }
1219    
1220                    return mode;
1221            }
1222    }
1223    
1224  static void  static void
1225  SearchP(const IMAGE * const pRef,  SearchP(const IMAGE * const pRef,
1226                  const uint8_t * const pRefH,                  const uint8_t * const pRefH,
# Line 1044  Line 1230 
1230                  const int x,                  const int x,
1231                  const int y,                  const int y,
1232                  const uint32_t MotionFlags,                  const uint32_t MotionFlags,
1233                    const uint32_t GlobalFlags,
1234                  const uint32_t iQuant,                  const uint32_t iQuant,
1235                  SearchData * const Data,                  SearchData * const Data,
1236                  const MBParam * const pParam,                  const MBParam * const pParam,
# Line 1093  Line 1280 
1280          Data->iMinSAD[3] = pMB->sad8[2];          Data->iMinSAD[3] = pMB->sad8[2];
1281          Data->iMinSAD[4] = pMB->sad8[3];          Data->iMinSAD[4] = pMB->sad8[3];
1282    
1283          if (x | y) {          if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) || (x | y)) {
1284                  threshA = Data->temp[0]; // that's when we keep this SAD atm                  threshA = Data->temp[0]; // that's where we keep this SAD atm
1285                  if (threshA < 512) threshA = 512;                  if (threshA < 512) threshA = 512;
1286                  else if (threshA > 1024) threshA = 1024;                  else if (threshA > 1024) threshA = 1024;
1287          } else threshA = 512;          } else
1288                    threshA = 512;
1289    
1290          PreparePredictionsP(pmv, x, y, pParam->mb_width, pParam->mb_height,          PreparePredictionsP(pmv, x, y, pParam->mb_width, pParam->mb_height,
1291                                          prevMBs + x + y * pParam->mb_width, Data->rrv);                                          prevMBs + x + y * pParam->mb_width, Data->rrv);
# Line 1117  Line 1305 
1305    
1306          if ((Data->iMinSAD[0] <= threshA) ||          if ((Data->iMinSAD[0] <= threshA) ||
1307                          (MVequal(Data->currentMV[0], (prevMBs+x+y*pParam->mb_width)->mvs[0]) &&                          (MVequal(Data->currentMV[0], (prevMBs+x+y*pParam->mb_width)->mvs[0]) &&
1308                          (Data->iMinSAD[0] < (prevMBs+x+y*pParam->mb_width)->sad16)))                          (Data->iMinSAD[0] < (prevMBs+x+y*pParam->mb_width)->sad16))) {
1309                  inter4v = 0;                  if (!(GlobalFlags & XVID_MODEDECISION_BITS)) inter4v = 0;       }
1310          else {          else {
1311    
1312                  MainSearchFunc * MainSearchPtr;                  MainSearchFunc * MainSearchPtr;
# Line 1126  Line 1314 
1314                  else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;                  else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;
1315                          else MainSearchPtr = DiamondSearch;                          else MainSearchPtr = DiamondSearch;
1316    
1317                  (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, iDirection);                  MainSearchPtr(Data->currentMV->x, Data->currentMV->y, Data, iDirection);
1318    
1319  /* extended search, diamond starting in 0,0 and in prediction.  /* extended search, diamond starting in 0,0 and in prediction.
1320          note that this search is/might be done in halfpel positions,          note that this search is/might be done in halfpel positions,
# Line 1138  Line 1326 
1326                          if (Data->rrv) {                          if (Data->rrv) {
1327                                  startMV.x = RRV_MV_SCALEUP(startMV.x);                                  startMV.x = RRV_MV_SCALEUP(startMV.x);
1328                                  startMV.y = RRV_MV_SCALEUP(startMV.y);                                  startMV.y = RRV_MV_SCALEUP(startMV.y);
1329                          } else                          }
                                 if (!(MotionFlags & PMV_HALFPELREFINE16)) // who's gonna use extsearch and no halfpel?  
                                         startMV.x = EVEN(startMV.x); startMV.y = EVEN(startMV.y);  
1330                          if (!(MVequal(startMV, backupMV))) {                          if (!(MVequal(startMV, backupMV))) {
1331                                  bSAD = Data->iMinSAD[0]; Data->iMinSAD[0] = MV_MAX_ERROR;                                  bSAD = Data->iMinSAD[0]; Data->iMinSAD[0] = MV_MAX_ERROR;
1332    
1333                                  CheckCandidate(startMV.x, startMV.y, 255, &iDirection, Data);                                  CheckCandidate(startMV.x, startMV.y, 255, &iDirection, Data);
1334                                  (*MainSearchPtr)(startMV.x, startMV.y, Data, 255);                                  MainSearchPtr(startMV.x, startMV.y, Data, 255);
1335                                  if (bSAD < Data->iMinSAD[0]) {                                  if (bSAD < Data->iMinSAD[0]) {
1336                                          Data->currentMV[0] = backupMV;                                          Data->currentMV[0] = backupMV;
1337                                          Data->iMinSAD[0] = bSAD; }                                          Data->iMinSAD[0] = bSAD; }
1338                          }                          }
1339    
1340                          backupMV = Data->currentMV[0];                          backupMV = Data->currentMV[0];
1341                          if (MotionFlags & PMV_HALFPELREFINE16 && !Data->rrv) startMV.x = startMV.y = 1;                          startMV.x = startMV.y = 1;
                         else startMV.x = startMV.y = 0;  
1342                          if (!(MVequal(startMV, backupMV))) {                          if (!(MVequal(startMV, backupMV))) {
1343                                  bSAD = Data->iMinSAD[0]; Data->iMinSAD[0] = MV_MAX_ERROR;                                  bSAD = Data->iMinSAD[0]; Data->iMinSAD[0] = MV_MAX_ERROR;
1344    
1345                                  CheckCandidate(startMV.x, startMV.y, 255, &iDirection, Data);                                  CheckCandidate(startMV.x, startMV.y, 255, &iDirection, Data);
1346                                  (*MainSearchPtr)(startMV.x, startMV.y, Data, 255);                                  MainSearchPtr(startMV.x, startMV.y, Data, 255);
1347                                  if (bSAD < Data->iMinSAD[0]) {                                  if (bSAD < Data->iMinSAD[0]) {
1348                                          Data->currentMV[0] = backupMV;                                          Data->currentMV[0] = backupMV;
1349                                          Data->iMinSAD[0] = bSAD; }                                          Data->iMinSAD[0] = bSAD; }
# Line 1166  Line 1351 
1351                  }                  }
1352          }          }
1353    
1354          if (MotionFlags & PMV_HALFPELREFINE16) SubpelRefine(Data);          if (MotionFlags & PMV_HALFPELREFINE16)
1355                    if ((!(MotionFlags & HALFPELREFINE16_BITS)) || Data->iMinSAD[0] < 200*(int)iQuant)
1356                            SubpelRefine(Data);
1357    
1358          for(i = 0; i < 5; i++) {          for(i = 0; i < 5; i++) {
1359                  Data->currentQMV[i].x = 2 * Data->currentMV[i].x; // initialize qpel vectors                  Data->currentQMV[i].x = 2 * Data->currentMV[i].x; // initialize qpel vectors
1360                  Data->currentQMV[i].y = 2 * Data->currentMV[i].y;                  Data->currentQMV[i].y = 2 * Data->currentMV[i].y;
1361          }          }
1362    
1363          if (Data->qpel && MotionFlags & PMV_QUARTERPELREFINE16) {          if (MotionFlags & PMV_QUARTERPELREFINE16)
1364                    if ((!(MotionFlags & QUARTERPELREFINE16_BITS)) || (Data->iMinSAD[0] < 200*(int)iQuant)) {
1365                  Data->qpel_precision = 1;                  Data->qpel_precision = 1;
1366                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16,                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16,
1367                                  pParam->width, pParam->height, Data->iFcode, 1, 0);                                  pParam->width, pParam->height, Data->iFcode, 1, 0);
# Line 1181  Line 1369 
1369                  SubpelRefine(Data);                  SubpelRefine(Data);
1370          }          }
1371    
1372          if (Data->iMinSAD[0] < (int32_t)iQuant * 30) inter4v = 0;          if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) && (Data->iMinSAD[0] < (int32_t)iQuant * 30)) inter4v = 0;
1373          if (inter4v) {  
1374            if (inter4v && (!(GlobalFlags & XVID_MODEDECISION_BITS) ||
1375                            (!(MotionFlags & QUARTERPELREFINE8_BITS)) || (!(MotionFlags & HALFPELREFINE8_BITS)) ||
1376                            ((!(MotionFlags & EXTSEARCH_BITS)) && (!(MotionFlags&PMV_EXTSEARCH8)) ))) {
1377                    // if decision is BITS-based and all refinement steps will be done in BITS domain, there is no reason to call this loop
1378    
1379                  SearchData Data8;                  SearchData Data8;
1380                  memcpy(&Data8, Data, sizeof(SearchData)); //quick copy of common data                  memcpy(&Data8, Data, sizeof(SearchData)); //quick copy of common data
1381    
# Line 1191  Line 1384 
1384                  Search8(Data, 2*x, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 2, &Data8);                  Search8(Data, 2*x, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 2, &Data8);
1385                  Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8);                  Search8(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8);
1386    
1387                  if (Data->chroma) {                  if ((Data->chroma) && (!(GlobalFlags & XVID_MODEDECISION_BITS))) {
1388                            // chroma is only used for comparsion to INTER. if the comparsion will be done in BITS domain, there is no reason to compute it
1389                          int sumx = 0, sumy = 0;                          int sumx = 0, sumy = 0;
1390                          const int div = 1 + Data->qpel;                          const int div = 1 + Data->qpel;
1391                          const VECTOR * const mv = Data->qpel ? pMB->qmvs : pMB->mvs;                          const VECTOR * const mv = Data->qpel ? pMB->qmvs : pMB->mvs;
# Line 1206  Line 1400 
1400                  }                  }
1401          }          }
1402    
1403            inter4v = ModeDecision(iQuant, Data, inter4v, pMB, pMBs, x, y, pParam, MotionFlags, GlobalFlags);
1404    
1405          if (Data->rrv) {          if (Data->rrv) {
1406                          Data->currentMV[0].x = RRV_MV_SCALEDOWN(Data->currentMV[0].x);                          Data->currentMV[0].x = RRV_MV_SCALEDOWN(Data->currentMV[0].x);
1407                          Data->currentMV[0].y = RRV_MV_SCALEDOWN(Data->currentMV[0].y);                          Data->currentMV[0].y = RRV_MV_SCALEDOWN(Data->currentMV[0].y);
1408          }          }
1409    
1410          if (!(inter4v) ||          if (inter4v == MODE_INTER) {
                 (Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] +  
                         Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant )) {  
 // INTER MODE  
1411                  pMB->mode = MODE_INTER;                  pMB->mode = MODE_INTER;
1412                  pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0];                  pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0];
1413                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = Data->iMinSAD[0];                  pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = Data->iMinSAD[0];
# Line 1228  Line 1421 
1421                          pMB->pmvs[0].x = Data->currentMV[0].x - Data->predMV.x;                          pMB->pmvs[0].x = Data->currentMV[0].x - Data->predMV.x;
1422                          pMB->pmvs[0].y = Data->currentMV[0].y - Data->predMV.y;                          pMB->pmvs[0].y = Data->currentMV[0].y - Data->predMV.y;
1423                  }                  }
1424          } else {  
1425  // INTER4V MODE; all other things are already set in Search8          } else if (inter4v == MODE_INTER4V) {
1426                  pMB->mode = MODE_INTER4V;                  pMB->mode = MODE_INTER4V;
1427                  pMB->sad16 = Data->iMinSAD[1] + Data->iMinSAD[2] +                  pMB->sad16 = Data->iMinSAD[0];
1428                          Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * iQuant;          } else { // INTRA mode
1429                    SkipMacroblockP(pMB, 0); // not skip, but similar enough
1430                    pMB->mode = MODE_INTRA;
1431          }          }
1432    
1433  }  }
1434    
1435  static void  static void
# Line 1280  Line 1476 
1476                  if (!Data->rrv) CheckCandidate = CheckCandidate8;                  if (!Data->rrv) CheckCandidate = CheckCandidate8;
1477                  else CheckCandidate = CheckCandidate16no4v;                  else CheckCandidate = CheckCandidate16no4v;
1478    
1479                  if (MotionFlags & PMV_EXTSEARCH8) {                  if (MotionFlags & PMV_EXTSEARCH8 && (!(MotionFlags & EXTSEARCH_BITS))) {
1480                          int32_t temp_sad = *(Data->iMinSAD); // store current MinSAD                          int32_t temp_sad = *(Data->iMinSAD); // store current MinSAD
1481    
1482                          MainSearchFunc *MainSearchPtr;                          MainSearchFunc *MainSearchPtr;
# Line 1288  Line 1484 
1484                                  else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamondSearch;                                  else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamondSearch;
1485                                          else MainSearchPtr = DiamondSearch;                                          else MainSearchPtr = DiamondSearch;
1486    
1487                          (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, 255);                          MainSearchPtr(Data->currentMV->x, Data->currentMV->y, Data, 255);
1488    
1489                          if(*(Data->iMinSAD) < temp_sad) {                          if(*(Data->iMinSAD) < temp_sad) {
1490                                          Data->currentQMV->x = 2 * Data->currentMV->x; // update our qpel vector                                          Data->currentQMV->x = 2 * Data->currentMV->x; // update our qpel vector
# Line 1435  Line 1631 
1631          else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;          else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;
1632                  else MainSearchPtr = DiamondSearch;                  else MainSearchPtr = DiamondSearch;
1633    
1634          (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, iDirection);          MainSearchPtr(Data->currentMV->x, Data->currentMV->y, Data, iDirection);
1635    
1636          SubpelRefine(Data);          SubpelRefine(Data);
1637    
# Line 1612  Line 1808 
1808                  else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;                  else if (MotionFlags & PMV_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;
1809                          else MainSearchPtr = DiamondSearch;                          else MainSearchPtr = DiamondSearch;
1810    
1811          (*MainSearchPtr)(0, 0, Data, 255);          MainSearchPtr(0, 0, Data, 255);
1812    
1813          SubpelRefine(Data);          SubpelRefine(Data);
1814    
# Line 2224  Line 2420 
2420    
2421          return gmc;          return gmc;
2422  }  }
2423    
2424    // functions which perform BITS-based search/bitcount
2425    
2426    static int
2427    CountMBBitsInter(SearchData * const Data,
2428                                    const MACROBLOCK * const pMBs, const int x, const int y,
2429                                    const MBParam * const pParam,
2430                                    const uint32_t MotionFlags)
2431    {
2432            int i, iDirection;
2433            int32_t bsad[5];
2434    
2435            CheckCandidate = CheckCandidateBits16;
2436    
2437            if (Data->qpel) {
2438                    for(i = 0; i < 5; i++) {
2439                            Data->currentMV[i].x = Data->currentQMV[i].x/2;
2440                            Data->currentMV[i].y = Data->currentQMV[i].y/2;
2441                    }
2442                    Data->qpel_precision = 1;
2443                    CheckCandidateBits16(Data->currentQMV[0].x, Data->currentQMV[0].y, 255, &iDirection, Data);
2444    
2445                    //checking if this vector is perfect. if it is, we stop.
2446                    if (Data->temp[0] == 0 && Data->temp[1] == 0 && Data->temp[2] == 0 && Data->temp[3] == 0)
2447                            return 0; //quick stop
2448    
2449                    if (MotionFlags & (HALFPELREFINE16_BITS | EXTSEARCH_BITS)) { //we have to prepare for halfpixel-precision search
2450                            for(i = 0; i < 5; i++) bsad[i] = Data->iMinSAD[i];
2451                            get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16,
2452                                                    pParam->width, pParam->height, Data->iFcode - Data->qpel, 0, Data->rrv);
2453                            Data->qpel_precision = 0;
2454                            if (Data->currentQMV->x & 1 || Data->currentQMV->y & 1)
2455                                    CheckCandidateBits16(Data->currentMV[0].x, Data->currentMV[0].y, 255, &iDirection, Data);
2456                    }
2457    
2458            } else { // not qpel
2459    
2460                    CheckCandidateBits16(Data->currentMV[0].x, Data->currentMV[0].y, 255, &iDirection, Data);
2461                    //checking if this vector is perfect. if it is, we stop.
2462                    if (Data->temp[0] == 0 && Data->temp[1] == 0 && Data->temp[2] == 0 && Data->temp[3] == 0) {
2463                            return 0; //inter
2464                    }
2465            }
2466    
2467            if (MotionFlags&EXTSEARCH_BITS) SquareSearch(Data->currentMV->x, Data->currentMV->y, Data, iDirection);
2468    
2469            if (MotionFlags&HALFPELREFINE16_BITS) SubpelRefine(Data);
2470    
2471            if (Data->qpel) {
2472                    if (MotionFlags&(EXTSEARCH_BITS | HALFPELREFINE16_BITS)) { // there was halfpel-precision search
2473                            for(i = 0; i < 5; i++) if (bsad[i] > Data->iMinSAD[i]) {
2474                                    Data->currentQMV[i].x = 2 * Data->currentMV[i].x; // we have found a better match
2475                                    Data->currentQMV[i].y = 2 * Data->currentMV[i].y;
2476                            }
2477    
2478                            // preparing for qpel-precision search
2479                            Data->qpel_precision = 1;
2480                            get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16,
2481                                            pParam->width, pParam->height, Data->iFcode, 1, 0);
2482                    }
2483                    if (MotionFlags&QUARTERPELREFINE16_BITS) SubpelRefine(Data);
2484            }
2485    
2486            if (MotionFlags&CHECKPREDICTION_BITS) { //let's check vector equal to prediction
2487                    VECTOR * v = Data->qpel ? Data->currentQMV : Data->currentMV;
2488                    if (!(Data->predMV.x == v->x && Data->predMV.y == v->y))
2489                            CheckCandidateBits16(Data->predMV.x, Data->predMV.y, 255, &iDirection, Data);
2490            }
2491            return Data->iMinSAD[0];
2492    }
2493    
2494    
2495    static int
2496    CountMBBitsInter4v(const SearchData * const Data,
2497                                            MACROBLOCK * const pMB, const MACROBLOCK * const pMBs,
2498                                            const int x, const int y,
2499                                            const MBParam * const pParam, const uint32_t MotionFlags,
2500                                            const VECTOR * const backup)
2501    {
2502    
2503            int cbp = 0, bits = 0, t = 0, i, iDirection;
2504            SearchData Data2, *Data8 = &Data2;
2505            int sumx = 0, sumy = 0;
2506            int16_t in[64], coeff[64];
2507    
2508            memcpy(Data8, Data, sizeof(SearchData));
2509            CheckCandidate = CheckCandidateBits8;
2510    
2511            for (i = 0; i < 4; i++) {
2512                    Data8->iMinSAD = Data->iMinSAD + i + 1;
2513                    Data8->currentMV = Data->currentMV + i + 1;
2514                    Data8->currentQMV = Data->currentQMV + i + 1;
2515                    Data8->Cur = Data->Cur + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2516                    Data8->Ref = Data->Ref + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2517                    Data8->RefH = Data->RefH + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2518                    Data8->RefV = Data->RefV + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2519                    Data8->RefHV = Data->RefHV + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2520    
2521                    if(Data->qpel) {
2522                            Data8->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x, y, i);
2523                            if (i != 0)     t = d_mv_bits(  Data8->currentQMV->x, Data8->currentQMV->y,
2524                                                                                    Data8->predMV, Data8->iFcode, 0, 0);
2525                    } else {
2526                            Data8->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, i);
2527                            if (i != 0)     t = d_mv_bits(  Data8->currentMV->x, Data8->currentMV->y,
2528                                                                                    Data8->predMV, Data8->iFcode, 0, 0);
2529                    }
2530    
2531                    get_range(&Data8->min_dx, &Data8->max_dx, &Data8->min_dy, &Data8->max_dy, 2*x + (i&1), 2*y + (i>>1), 8,
2532                                            pParam->width, pParam->height, Data8->iFcode, Data8->qpel, 0);
2533    
2534                    *Data8->iMinSAD += t;
2535    
2536                    Data8->qpel_precision = Data8->qpel;
2537                    // checking the vector which has been found by SAD-based 8x8 search (if it's different than the one found so far)
2538                    if (Data8->qpel) {
2539                            if (!(Data8->currentQMV->x == backup[i+1].x && Data8->currentQMV->y == backup[i+1].y))
2540                                    CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8);
2541                    } else {
2542                            if (!(Data8->currentMV->x == backup[i+1].x && Data8->currentMV->y == backup[i+1].y))
2543                                    CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8);
2544                    }
2545    
2546                    if (Data8->qpel) {
2547                            if (MotionFlags&HALFPELREFINE8_BITS || (MotionFlags&PMV_EXTSEARCH8 && MotionFlags&EXTSEARCH_BITS)) { // halfpixel motion search follows
2548                                    int32_t s = *Data8->iMinSAD;
2549                                    Data8->currentMV->x = Data8->currentQMV->x/2;
2550                                    Data8->currentMV->y = Data8->currentQMV->y/2;
2551                                    Data8->qpel_precision = 0;
2552                                    get_range(&Data8->min_dx, &Data8->max_dx, &Data8->min_dy, &Data8->max_dy, 2*x + (i&1), 2*y + (i>>1), 8,
2553                                                            pParam->width, pParam->height, Data8->iFcode - 1, 0, 0);
2554    
2555                                    if (Data8->currentQMV->x & 1 || Data8->currentQMV->y & 1)
2556                                            CheckCandidateBits8(Data8->currentMV->x, Data8->currentMV->y, 255, &iDirection, Data8);
2557    
2558                                    if (MotionFlags & PMV_EXTSEARCH8 && MotionFlags & EXTSEARCH_BITS)
2559                                            SquareSearch(Data8->currentMV->x, Data8->currentMV->x, Data8, 255);
2560    
2561                                    if (MotionFlags & HALFPELREFINE8_BITS) SubpelRefine(Data8);
2562    
2563                                    if(s > *Data8->iMinSAD) { //we have found a better match
2564                                            Data8->currentQMV->x = 2*Data8->currentMV->x;
2565                                            Data8->currentQMV->y = 2*Data8->currentMV->y;
2566                                    }
2567    
2568                                    Data8->qpel_precision = 1;
2569                                    get_range(&Data8->min_dx, &Data8->max_dx, &Data8->min_dy, &Data8->max_dy, 2*x + (i&1), 2*y + (i>>1), 8,
2570                                                            pParam->width, pParam->height, Data8->iFcode, 1, 0);
2571    
2572                            }
2573                            if (MotionFlags & QUARTERPELREFINE8_BITS) SubpelRefine(Data8);
2574    
2575                    } else // not qpel
2576                            if (MotionFlags & HALFPELREFINE8_BITS) SubpelRefine(Data8); //halfpel mode, halfpel refinement
2577    
2578                    //checking vector equal to predicion
2579                    if (i != 0 && MotionFlags & CHECKPREDICTION_BITS) {
2580                            const VECTOR * v = Data->qpel ? Data8->currentQMV : Data8->currentMV;
2581                            if (!(Data8->predMV.x == v->x && Data8->predMV.y == v->y))
2582                                    CheckCandidateBits8(Data8->predMV.x, Data8->predMV.y, 255, &iDirection, Data8);
2583                    }
2584    
2585                    bits += *Data8->iMinSAD;
2586                    if (bits >= Data->iMinSAD[0]) break; // no chances for INTER4V
2587    
2588                    // MB structures for INTER4V mode; we have to set them here, we don't have predictor anywhere else
2589                    if(Data->qpel) {
2590                            pMB->pmvs[i].x = Data8->currentQMV->x - Data8->predMV.x;
2591                            pMB->pmvs[i].y = Data8->currentQMV->y - Data8->predMV.y;
2592                            pMB->qmvs[i] = *Data8->currentQMV;
2593                            sumx += Data8->currentQMV->x/2;
2594                            sumy += Data8->currentQMV->y/2;
2595                    } else {
2596                            pMB->pmvs[i].x = Data8->currentMV->x - Data8->predMV.x;
2597                            pMB->pmvs[i].y = Data8->currentMV->y - Data8->predMV.y;
2598                            sumx += Data8->currentMV->x;
2599                            sumy += Data8->currentMV->y;
2600                    }
2601                    pMB->mvs[i] = *Data8->currentMV;
2602                    pMB->sad8[i] = 4 * *Data8->iMinSAD;
2603                    if (Data8->temp[0]) cbp |= 1 << (5 - i);
2604            }
2605    
2606            if (bits < *Data->iMinSAD) { // there is still a chance for inter4v mode. let's check chroma
2607                    const uint8_t * ptr;
2608                    sumx = (sumx >> 3) + roundtab_76[sumx & 0xf];
2609                    sumy = (sumy >> 3) + roundtab_76[sumy & 0xf];
2610    
2611                    //chroma U
2612                    ptr = interpolate8x8_switch2(Data->RefQ + 64, Data->RefCU, 0, 0, sumx, sumy, Data->iEdgedWidth/2, Data->rounding);
2613                    transfer_8to16subro(in, Data->CurU, ptr, Data->iEdgedWidth/2);
2614                    fdct(in);
2615                    if (Data->lambda8 == 0) i = quant_inter(coeff, in, Data->lambda16);
2616                    else i = quant4_inter(coeff, in, Data->lambda16);
2617                    if (i > 0) {
2618                            bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);
2619                            cbp |= 1 << (5 - 4);
2620                    }
2621    
2622                    if (bits < *Data->iMinSAD) { // still possible
2623                            //chroma V
2624                            ptr = interpolate8x8_switch2(Data->RefQ + 64, Data->RefCV, 0, 0, sumx, sumy, Data->iEdgedWidth/2, Data->rounding);
2625                            transfer_8to16subro(in, Data->CurV, ptr, Data->iEdgedWidth/2);
2626                            fdct(in);
2627                            if (Data->lambda8 == 0) i = quant_inter(coeff, in, Data->lambda16);
2628                            else i = quant4_inter(coeff, in, Data->lambda16);
2629                            if (i > 0) {
2630                                    bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);
2631                                    cbp |= 1 << (5 - 5);
2632                            }
2633                            bits += cbpy_tab[15-(cbp>>2)].len;
2634                            bits += mcbpc_inter_tab[(MODE_INTER4V & 7) | ((cbp & 3) << 3)].len;
2635                    }
2636            }
2637    
2638            return bits;
2639    }
2640    
2641    
2642    static int
2643    CountMBBitsIntra(const SearchData * const Data)
2644    {
2645            int bits = 1; //this one is ac/dc prediction flag. always 1.
2646            int cbp = 0, i, t, dc = 0, b_dc = 1024;
2647            const uint32_t iQuant = Data->lambda16;
2648            int16_t in[64], coeff[64];
2649    
2650            for(i = 0; i < 4; i++) {
2651                    uint32_t iDcScaler = get_dc_scaler(iQuant, 1);
2652    
2653                    int s = 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2654                    transfer_8to16copy(in, Data->Cur + s, Data->iEdgedWidth);
2655                    fdct(in);
2656                    b_dc = dc;
2657                    dc = in[0];
2658                    in[0] -= b_dc;
2659                    if (Data->lambda8 == 0) quant_intra_c(coeff, in, iQuant, iDcScaler);
2660                    else quant4_intra_c(coeff, in, iQuant, iDcScaler);
2661    
2662                    b_dc = dc;
2663                    dc = coeff[0];
2664                    if (i != 0) coeff[0] -= b_dc;
2665    
2666                    bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcy_tab[coeff[0] + 255].len;;
2667                    Data->temp[i] = t;
2668                    if (t != 0)  cbp |= 1 << (5 - i);
2669                    if (bits >= Data->iMinSAD[0]) break;
2670            }
2671    
2672            if (bits < Data->iMinSAD[0]) { // INTRA still looks good, let's add chroma
2673                    uint32_t iDcScaler = get_dc_scaler(iQuant, 0);
2674                    //chroma U
2675                    transfer_8to16copy(in, Data->CurU, Data->iEdgedWidth/2);
2676                    fdct(in);
2677                    in[0] -= 1024;
2678                    if (Data->lambda8 == 0) quant_intra(coeff, in, iQuant, iDcScaler);
2679                    else quant4_intra(coeff, in, iQuant, iDcScaler);
2680    
2681                    bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcc_tab[coeff[0] + 255].len;
2682                    if (t != 0) cbp |= 1 << (5 - 4);
2683                    Data->temp[4] = t;
2684    
2685                    if (bits < Data->iMinSAD[0]) {
2686                            //chroma V
2687                            transfer_8to16copy(in, Data->CurV, Data->iEdgedWidth/2);
2688                            fdct(in);
2689                            in[0] -= 1024;
2690                            if (Data->lambda8 == 0) quant_intra(coeff, in, iQuant, iDcScaler);
2691                            else quant4_intra(coeff, in, iQuant, iDcScaler);
2692    
2693                            bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcc_tab[coeff[0] + 255].len;
2694                            if (t != 0) cbp |= 1 << (5 - 5);
2695    
2696                            Data->temp[5] = t;
2697    
2698                            bits += t = cbpy_tab[cbp>>2].len;
2699                            Data->temp[6] = t;
2700    
2701                            bits += t = mcbpc_inter_tab[(MODE_INTRA & 7) | ((cbp & 3) << 3)].len;
2702                            Data->temp[7] = t;
2703    
2704                    }
2705            }
2706    
2707            return bits;
2708    }

Legend:
Removed from v.835  
changed lines
  Added in v.836

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4