[svn] / trunk / xvidcore / src / motion / motion_est.c Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/motion/motion_est.c

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

revision 973, Sat Apr 5 15:54:59 2003 UTC revision 1072, Thu Jun 19 10:06:40 2003 UTC
# Line 105  Line 105 
105          return bits;          return bits;
106  }  }
107    
108  static int32_t ChromaSAD2(int fx, int fy, int bx, int by, const SearchData * const data)  static int32_t ChromaSAD2(const int fx, const int fy, const int bx, const int by,
109                                                            const SearchData * const data)
110  {  {
111          int sad;          int sad;
112          const uint32_t stride = data->iEdgedWidth/2;          const uint32_t stride = data->iEdgedWidth/2;
# Line 113  Line 114 
114                  * f_refv = data->RefQ + 8,                  * f_refv = data->RefQ + 8,
115                  * b_refu = data->RefQ + 16,                  * b_refu = data->RefQ + 16,
116                  * b_refv = data->RefQ + 24;                  * b_refv = data->RefQ + 24;
117            int offset = (fx>>1) + (fy>>1)*stride;
118    
119          switch (((fx & 1) << 1) | (fy & 1))     {          switch (((fx & 1) << 1) | (fy & 1))     {
120                  case 0:                  case 0:
121                          fx = fx / 2; fy = fy / 2;                          f_refu = (uint8_t*)data->RefP[4] + offset;
122                          f_refu = (uint8_t*)data->RefCU + fy * stride + fx, stride;                          f_refv = (uint8_t*)data->RefP[5] + offset;
                         f_refv = (uint8_t*)data->RefCV + fy * stride + fx, stride;  
123                          break;                          break;
124                  case 1:                  case 1:
125                          fx = fx / 2; fy = (fy - 1) / 2;                          interpolate8x8_halfpel_v(f_refu, data->RefP[4] + offset, stride, data->rounding);
126                          interpolate8x8_halfpel_v(f_refu, data->RefCU + fy * stride + fx, stride, data->rounding);                          interpolate8x8_halfpel_v(f_refv, data->RefP[5] + offset, stride, data->rounding);
                         interpolate8x8_halfpel_v(f_refv, data->RefCV + fy * stride + fx, stride, data->rounding);  
127                          break;                          break;
128                  case 2:                  case 2:
129                          fx = (fx - 1) / 2; fy = fy / 2;                          interpolate8x8_halfpel_h(f_refu, data->RefP[4] + offset, stride, data->rounding);
130                          interpolate8x8_halfpel_h(f_refu, data->RefCU + fy * stride + fx, stride, data->rounding);                          interpolate8x8_halfpel_h(f_refv, data->RefP[5] + offset, stride, data->rounding);
                         interpolate8x8_halfpel_h(f_refv, data->RefCV + fy * stride + fx, stride, data->rounding);  
131                          break;                          break;
132                  default:                  default:
133                          fx = (fx - 1) / 2; fy = (fy - 1) / 2;                          interpolate8x8_halfpel_hv(f_refu, data->RefP[4] + offset, stride, data->rounding);
134                          interpolate8x8_halfpel_hv(f_refu, data->RefCU + fy * stride + fx, stride, data->rounding);                          interpolate8x8_halfpel_hv(f_refv, data->RefP[5] + offset, stride, data->rounding);
                         interpolate8x8_halfpel_hv(f_refv, data->RefCV + fy * stride + fx, stride, data->rounding);  
135                          break;                          break;
136          }          }
137    
138            offset = (bx>>1) + (by>>1)*stride;
139          switch (((bx & 1) << 1) | (by & 1))     {          switch (((bx & 1) << 1) | (by & 1))     {
140                  case 0:                  case 0:
141                          bx = bx / 2; by = by / 2;                          b_refu = (uint8_t*)data->b_RefP[4] + offset;
142                          b_refu = (uint8_t*)data->b_RefCU + by * stride + bx, stride;                          b_refv = (uint8_t*)data->b_RefP[5] + offset;
                         b_refv = (uint8_t*)data->b_RefCV + by * stride + bx, stride;  
143                          break;                          break;
144                  case 1:                  case 1:
145                          bx = bx / 2; by = (by - 1) / 2;                          interpolate8x8_halfpel_v(b_refu, data->b_RefP[4] + offset, stride, data->rounding);
146                          interpolate8x8_halfpel_v(b_refu, data->b_RefCU + by * stride + bx, stride, data->rounding);                          interpolate8x8_halfpel_v(b_refv, data->b_RefP[5] + offset, stride, data->rounding);
                         interpolate8x8_halfpel_v(b_refv, data->b_RefCV + by * stride + bx, stride, data->rounding);  
147                          break;                          break;
148                  case 2:                  case 2:
149                          bx = (bx - 1) / 2; by = by / 2;                          interpolate8x8_halfpel_h(b_refu, data->b_RefP[4] + offset, stride, data->rounding);
150                          interpolate8x8_halfpel_h(b_refu, data->b_RefCU + by * stride + bx, stride, data->rounding);                          interpolate8x8_halfpel_h(b_refv, data->b_RefP[5] + offset, stride, data->rounding);
                         interpolate8x8_halfpel_h(b_refv, data->b_RefCV + by * stride + bx, stride, data->rounding);  
151                          break;                          break;
152                  default:                  default:
153                          bx = (bx - 1) / 2; by = (by - 1) / 2;                          interpolate8x8_halfpel_hv(b_refu, data->b_RefP[4] + offset, stride, data->rounding);
154                          interpolate8x8_halfpel_hv(b_refu, data->b_RefCU + by * stride + bx, stride, data->rounding);                          interpolate8x8_halfpel_hv(b_refv, data->b_RefP[5] + offset, stride, data->rounding);
                         interpolate8x8_halfpel_hv(b_refv, data->b_RefCV + by * stride + bx, stride, data->rounding);  
155                          break;                          break;
156          }          }
157    
# Line 166  Line 161 
161          return sad;          return sad;
162  }  }
163    
   
164  static int32_t  static int32_t
165  ChromaSAD(int dx, int dy, const SearchData * const data)  ChromaSAD(const int dx, const int dy, const SearchData * const data)
166  {  {
167          int sad;          int sad;
168          const uint32_t stride = data->iEdgedWidth/2;          const uint32_t stride = data->iEdgedWidth/2;
169            int offset = (dx>>1) + (dy>>1)*stride;
170    
171          if (dx == data->temp[5] && dy == data->temp[6]) return data->temp[7]; //it has been checked recently          if (dx == data->temp[5] && dy == data->temp[6]) return data->temp[7]; //it has been checked recently
172          data->temp[5] = dx; data->temp[6] = dy; // backup          data->temp[5] = dx; data->temp[6] = dy; // backup
173    
174          switch (((dx & 1) << 1) | (dy & 1))     {          switch (((dx & 1) << 1) | (dy & 1))     {
175                  case 0:                  case 0:
176                          dx = dx / 2; dy = dy / 2;                          sad = sad8(data->CurU, data->RefP[4] + offset, stride);
177                          sad = sad8(data->CurU, data->RefCU + dy * stride + dx, stride);                          sad += sad8(data->CurV, data->RefP[5] + offset, stride);
                         sad += sad8(data->CurV, data->RefCV + dy * stride + dx, stride);  
178                          break;                          break;
179                  case 1:                  case 1:
180                          dx = dx / 2; dy = (dy - 1) / 2;                          sad = sad8bi(data->CurU, data->RefP[4] + offset, data->RefP[4] + offset + stride, stride);
181                          sad = sad8bi(data->CurU, data->RefCU + dy * stride + dx, data->RefCU + (dy+1) * stride + dx, stride);                          sad += sad8bi(data->CurV, data->RefP[5] + offset, data->RefP[5] + offset + stride, stride);
                         sad += sad8bi(data->CurV, data->RefCV + dy * stride + dx, data->RefCV + (dy+1) * stride + dx, stride);  
182                          break;                          break;
183                  case 2:                  case 2:
184                          dx = (dx - 1) / 2; dy = dy / 2;                          sad = sad8bi(data->CurU, data->RefP[4] + offset, data->RefP[4] + offset + 1, stride);
185                          sad = sad8bi(data->CurU, data->RefCU + dy * stride + dx, data->RefCU + dy * stride + dx+1, stride);                          sad += sad8bi(data->CurV, data->RefP[5] + offset, data->RefP[5] + offset + 1, stride);
                         sad += sad8bi(data->CurV, data->RefCV + dy * stride + dx, data->RefCV + dy * stride + dx+1, stride);  
186                          break;                          break;
187                  default:                  default:
188                          dx = (dx - 1) / 2; dy = (dy - 1) / 2;                          interpolate8x8_halfpel_hv(data->RefQ, data->RefP[4] + offset, stride, data->rounding);
                         interpolate8x8_halfpel_hv(data->RefQ, data->RefCU + dy * stride + dx, stride, data->rounding);  
189                          sad = sad8(data->CurU, data->RefQ, stride);                          sad = sad8(data->CurU, data->RefQ, stride);
190    
191                          interpolate8x8_halfpel_hv(data->RefQ, data->RefCV + dy * stride + dx, stride, data->rounding);                          interpolate8x8_halfpel_hv(data->RefQ, data->RefP[5] + offset, stride, data->rounding);
192                          sad += sad8(data->CurV, data->RefQ, stride);                          sad += sad8(data->CurV, data->RefQ, stride);
193                          break;                          break;
194          }          }
# Line 209  Line 200 
200  GetReferenceB(const int x, const int y, const uint32_t dir, const SearchData * const data)  GetReferenceB(const int x, const int y, const uint32_t dir, const SearchData * const data)
201  {  {
202  //      dir : 0 = forward, 1 = backward  //      dir : 0 = forward, 1 = backward
203          switch ( (dir << 2) | ((x&1)<<1) | (y&1) ) {          const uint8_t *const *const direction = ( dir == 0 ? data->RefP : data->b_RefP );
204                  case 0 : return data->Ref + x/2 + (y/2)*(data->iEdgedWidth);          const int picture = ((x&1)<<1) | (y&1);
205                  case 1 : return data->RefV + x/2 + ((y-1)/2)*(data->iEdgedWidth);          const int offset = (x>>1) + (y>>1)*data->iEdgedWidth;
206                  case 2 : return data->RefH + (x-1)/2 + (y/2)*(data->iEdgedWidth);          return direction[picture] + offset;
                 case 3 : return data->RefHV + (x-1)/2 + ((y-1)/2)*(data->iEdgedWidth);  
                 case 4 : return data->bRef + x/2 + (y/2)*(data->iEdgedWidth);  
                 case 5 : return data->bRefV + x/2 + ((y-1)/2)*(data->iEdgedWidth);  
                 case 6 : return data->bRefH + (x-1)/2 + (y/2)*(data->iEdgedWidth);  
                 default : return data->bRefHV + (x-1)/2 + ((y-1)/2)*(data->iEdgedWidth);  
         }  
207  }  }
208    
209  // this is a simpler copy of GetReferenceB, but as it's __inline anyway, we can keep the two separate  // this is a simpler copy of GetReferenceB, but as it's __inline anyway, we can keep the two separate
210  static __inline const uint8_t *  static __inline const uint8_t *
211  GetReference(const int x, const int y, const SearchData * const data)  GetReference(const int x, const int y, const SearchData * const data)
212  {  {
213          switch ( ((x&1)<<1) | (y&1) ) {          const int picture = ((x&1)<<1) | (y&1);
214                  case 0 : return data->Ref + x/2 + (y/2)*(data->iEdgedWidth);          const int offset = (x>>1) + (y>>1)*data->iEdgedWidth;
215                  case 3 : return data->RefHV + (x-1)/2 + ((y-1)/2)*(data->iEdgedWidth);          return data->RefP[picture] + offset;
                 case 1 : return data->RefV + x/2 + ((y-1)/2)*(data->iEdgedWidth);  
                 default : return data->RefH + (x-1)/2 + (y/2)*(data->iEdgedWidth);      //case 2  
         }  
216  }  }
217    
218  static uint8_t *  static uint8_t *
# Line 369  Line 351 
351                  data->iMinSAD[3] = data->temp[3]; current[3].x = x; current[3].y = y; }                  data->iMinSAD[3] = data->temp[3]; current[3].x = x; current[3].y = y; }
352          if (data->temp[4] < data->iMinSAD[4]) {          if (data->temp[4] < data->iMinSAD[4]) {
353                  data->iMinSAD[4] = data->temp[4]; current[4].x = x; current[4].y = y; }                  data->iMinSAD[4] = data->temp[4]; current[4].x = x; current[4].y = y; }
   
354  }  }
355    
356  static void  static void
# Line 402  Line 383 
383          }          }
384  }  }
385    
   
386  static void  static void
387  CheckCandidate32(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)  CheckCandidate32(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)
388  {  {
# Line 483  Line 463 
463          if ( (x > data->max_dx) || (x < data->min_dx)          if ( (x > data->max_dx) || (x < data->min_dx)
464                  || (y > data->max_dy) || (y < data->min_dy) ) return;                  || (y > data->max_dy) || (y < data->min_dy) ) return;
465    
466          sad = sad32v_c(data->Cur, data->Ref + x/2 + (y/2)*(data->iEdgedWidth),          sad = sad32v_c(data->Cur, data->RefP[0] + (x>>1) + (y>>1)*(data->iEdgedWidth),
467                                                          data->iEdgedWidth, data->temp+1);                                                          data->iEdgedWidth, data->temp+1);
468    
469          if (sad < *(data->iMinSAD)) {          if (sad < *(data->iMinSAD)) {
# Line 666  Line 646 
646  {  {
647    
648          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;
649          int32_t bits = 0, sum;          int32_t bits = 0;
650          VECTOR * current;          VECTOR * current;
651          const uint8_t * ptr;          const uint8_t * ptr;
652          int i, cbp = 0, t, xc, yc;          int i, cbp = 0, t, xc, yc;
# Line 687  Line 667 
667          for(i = 0; i < 4; i++) {          for(i = 0; i < 4; i++) {
668                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);                  int s = 8*((i&1) + (i>>1)*data->iEdgedWidth);
669                  transfer_8to16subro(in, data->Cur + s, ptr + s, data->iEdgedWidth);                  transfer_8to16subro(in, data->Cur + s, ptr + s, data->iEdgedWidth);
670                  fdct(in);                  bits += data->temp[i] = Block_CalcBits(coeff, in, data->iQuant, data->quant_type, &cbp, i);
                 if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);  
                 else sum = quant4_inter(coeff, in, data->lambda16);  
                 if (sum > 0) {  
                         cbp |= 1 << (5 - i);  
                         bits += data->temp[i] = CodeCoeffInter_CalcBits(coeff, scan_tables[0]);  
                 } else data->temp[i] = 0;  
671          }          }
672    
673          bits += t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0);          bits += t = BITS_MULT*d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0);
674    
675            if (data->temp[0] + t < data->iMinSAD[1]) {
676                    data->iMinSAD[1] = data->temp[0] + t; current[1].x = x; current[1].y = y; }
677            if (data->temp[1] < data->iMinSAD[2]) {
678                    data->iMinSAD[2] = data->temp[1]; current[2].x = x; current[2].y = y; }
679            if (data->temp[2] < data->iMinSAD[3]) {
680                    data->iMinSAD[3] = data->temp[2]; current[3].x = x; current[3].y = y; }
681            if (data->temp[3] < data->iMinSAD[4]) {
682                    data->iMinSAD[4] = data->temp[3]; current[4].x = x; current[4].y = y; }
683    
684    
685            bits += BITS_MULT*xvid_cbpy_tab[15-(cbp>>2)].len;
686    
687            if (bits >= data->iMinSAD[0]) return;
688    
689          if (bits < data->iMinSAD[0]) { // there is still a chance, adding chroma          //chroma
690                  xc = (xc >> 1) + roundtab_79[xc & 0x3];                  xc = (xc >> 1) + roundtab_79[xc & 0x3];
691                  yc = (yc >> 1) + roundtab_79[yc & 0x3];                  yc = (yc >> 1) + roundtab_79[yc & 0x3];
692    
693                  //chroma U                  //chroma U
694                  ptr = interpolate8x8_switch2(data->RefQ + 64, data->RefCU, 0, 0, xc, yc,  data->iEdgedWidth/2, data->rounding);          ptr = interpolate8x8_switch2(data->RefQ + 64, data->RefP[4], 0, 0, xc, yc,  data->iEdgedWidth/2, data->rounding);
695                  transfer_8to16subro(in, ptr, data->CurU, data->iEdgedWidth/2);                  transfer_8to16subro(in, ptr, data->CurU, data->iEdgedWidth/2);
696                  fdct(in);          bits += Block_CalcBits(coeff, in, data->iQuant, data->quant_type, &cbp, 4);
697                  if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);          if (bits >= data->iMinSAD[0]) return;
                 else sum = quant4_inter(coeff, in, data->lambda16);  
                 if (sum > 0) {  
                         cbp |= 1 << (5 - 4);  
                         bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);  
                 }  
698    
                 if (bits < data->iMinSAD[0]) {  
699                          //chroma V                          //chroma V
700                          ptr = interpolate8x8_switch2(data->RefQ + 64, data->RefCV, 0, 0, xc, yc,  data->iEdgedWidth/2, data->rounding);          ptr = interpolate8x8_switch2(data->RefQ + 64, data->RefP[5], 0, 0, xc, yc,  data->iEdgedWidth/2, data->rounding);
701                          transfer_8to16subro(in, ptr, data->CurV, data->iEdgedWidth/2);                          transfer_8to16subro(in, ptr, data->CurV, data->iEdgedWidth/2);
702                          fdct(in);          bits += Block_CalcBits(coeff, in, data->iQuant, data->quant_type, &cbp, 5);
                         if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);  
                         else sum = quant4_inter(coeff, in, data->lambda16);  
                         if (sum > 0) {  
                                 cbp |= 1 << (5 - 5);  
                                 bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);  
                         }  
                 }  
         }  
703    
704          bits += xvid_cbpy_tab[15-(cbp>>2)].len;          bits += BITS_MULT*mcbpc_inter_tab[(MODE_INTER & 7) | ((cbp & 3) << 3)].len;
         bits += mcbpc_inter_tab[(MODE_INTER & 7) | ((cbp & 3) << 3)].len;  
705    
706          if (bits < data->iMinSAD[0]) {          if (bits < data->iMinSAD[0]) {
707                  data->iMinSAD[0] = bits;                  data->iMinSAD[0] = bits;
# Line 736  Line 709 
709                  *dir = Direction;                  *dir = Direction;
710          }          }
711    
         if (data->temp[0] + t < data->iMinSAD[1]) {  
                 data->iMinSAD[1] = data->temp[0] + t; current[1].x = x; current[1].y = y; }  
         if (data->temp[1] < data->iMinSAD[2]) {  
                 data->iMinSAD[2] = data->temp[1]; current[2].x = x; current[2].y = y; }  
         if (data->temp[2] < data->iMinSAD[3]) {  
                 data->iMinSAD[3] = data->temp[2]; current[3].x = x; current[3].y = y; }  
         if (data->temp[3] < data->iMinSAD[4]) {  
                 data->iMinSAD[4] = data->temp[3]; current[4].x = x; current[4].y = y; }  
   
712  }  }
713    
714  static void  static void
715  CheckCandidateBits8(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)  CheckCandidateBits8(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)
716  {  {
717    
718          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;          int16_t *in = data->dctSpace, *coeff = data->dctSpace + 64;
719          int32_t sum, bits;          int32_t bits;
720          VECTOR * current;          VECTOR * current;
721          const uint8_t * ptr;          const uint8_t * ptr;
722          int cbp;          int cbp = 0;
723    
724          if ( (x > data->max_dx) || (x < data->min_dx)          if ( (x > data->max_dx) || (x < data->min_dx)
725                  || (y > data->max_dy) || (y < data->min_dy) ) return;                  || (y > data->max_dy) || (y < data->min_dy) ) return;
# Line 768  Line 733 
733          }          }
734    
735          transfer_8to16subro(in, data->Cur, ptr, data->iEdgedWidth);          transfer_8to16subro(in, data->Cur, ptr, data->iEdgedWidth);
736          fdct(in);          bits = Block_CalcBits(coeff, in, data->iQuant, data->quant_type, &cbp, 5);
737          if (data->lambda8 == 0) sum = quant_inter(coeff, in, data->lambda16);          bits += BITS_MULT*d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0);
         else sum = quant4_inter(coeff, in, data->lambda16);  
         if (sum > 0) {  
                 bits = CodeCoeffInter_CalcBits(coeff, scan_tables[0]);  
                 cbp = 1;  
         } else cbp = bits = 0;  
   
         bits += sum = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel^data->qpel_precision, 0);  
738    
739          if (bits < data->iMinSAD[0]) {          if (bits < data->iMinSAD[0]) {
740                  data->temp[0] = cbp;                  data->temp[0] = cbp;
# Line 986  Line 944 
944          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad;          pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad;
945  }  }
946    
947    static __inline void
948    ModeDecision(SearchData * const Data,
949                            MACROBLOCK * const pMB,
950                            const MACROBLOCK * const pMBs,
951                            const int x, const int y,
952                            const MBParam * const pParam,
953                            const uint32_t MotionFlags,
954                            const uint32_t GlobalFlags,
955                            const IMAGE * const pCurrent,
956                            const IMAGE * const pRef)
957    {
958            int mode = MODE_INTER;
959            int inter4v = (GlobalFlags & XVID_INTER4V) && (pMB->dquant == NO_CHANGE);
960            const uint32_t iQuant = pMB->quant;
961    
962            const int skip_possible = (!(GlobalFlags & XVID_GMC)) && (pMB->dquant == NO_CHANGE);
963    
964            if (!(GlobalFlags & XVID_MODEDECISION_BITS)) { //normal, fast, SAD-based mode decision
965                    int sad;
966                    int InterBias = MV16_INTER_BIAS;
967                    if (inter4v == 0 || Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] +
968                            Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant) {
969                            mode = MODE_INTER;
970                            sad = Data->iMinSAD[0];
971                    } else {
972                            mode = MODE_INTER4V;
973                            sad = Data->iMinSAD[1] + Data->iMinSAD[2] +
974                                                    Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant;
975                            Data->iMinSAD[0] = sad;
976                    }
977    
978                    /* final skip decision, a.k.a. "the vector you found, really that good?" */
979                    if (skip_possible && (pMB->sad16 < (int)iQuant * MAX_SAD00_FOR_SKIP))
980                            if ( (100*sad)/(pMB->sad16+1) > FINAL_SKIP_THRESH)
981                                    if (Data->chroma || SkipDecisionP(pCurrent, pRef, x, y, Data->iEdgedWidth/2, iQuant, Data->rrv)) {
982                                            mode = MODE_NOT_CODED;
983                                            sad = 0;
984                                    }
985    
986                    /* intra decision */
987    
988                    if (iQuant > 8) InterBias += 100 * (iQuant - 8); // to make high quants work
989                    if (y != 0)
990                            if ((pMB - pParam->mb_width)->mode == MODE_INTRA ) InterBias -= 80;
991                    if (x != 0)
992                            if ((pMB - 1)->mode == MODE_INTRA ) InterBias -= 80;
993    
994                    if (Data->chroma) InterBias += 50; // dev8(chroma) ???
995                    if (Data->rrv) InterBias *= 4;
996    
997                    if (InterBias < pMB->sad16) {
998                            int32_t deviation;
999                            if (!Data->rrv) deviation = dev16(Data->Cur, Data->iEdgedWidth);
1000                            else deviation = dev16(Data->Cur, Data->iEdgedWidth) +
1001                                    dev16(Data->Cur+16, Data->iEdgedWidth) +
1002                                    dev16(Data->Cur + 16*Data->iEdgedWidth, Data->iEdgedWidth) +
1003                                    dev16(Data->Cur+16+16*Data->iEdgedWidth, Data->iEdgedWidth);
1004    
1005                            if (deviation < (sad - InterBias)) mode = MODE_INTRA;
1006                    }
1007    
1008            } else { // BITS
1009    
1010                    int bits, intra, i;
1011                    VECTOR backup[5], *v;
1012                    Data->iQuant = iQuant;
1013    
1014                    v = Data->qpel ? Data->currentQMV : Data->currentMV;
1015                    for (i = 0; i < 5; i++) {
1016                            Data->iMinSAD[i] = 256*4096;
1017                            backup[i] = v[i];
1018                    }
1019    
1020                    bits = CountMBBitsInter(Data, pMBs, x, y, pParam, MotionFlags);
1021                    if (bits == 0)
1022                            mode = MODE_INTER; // quick stop
1023                    else {
1024                            if (inter4v) {
1025                                    int bits_inter4v = CountMBBitsInter4v(Data, pMB, pMBs, x, y, pParam, MotionFlags, backup);
1026                                    if (bits_inter4v < bits) { Data->iMinSAD[0] = bits = bits_inter4v; mode = MODE_INTER4V; }
1027                            }
1028    
1029                            intra = CountMBBitsIntra(Data);
1030    
1031                            if (intra < bits) { *Data->iMinSAD = bits = intra; mode = MODE_INTRA; }
1032                    }
1033            }
1034    
1035            if (Data->rrv) {
1036                            Data->currentMV[0].x = RRV_MV_SCALEDOWN(Data->currentMV[0].x);
1037                            Data->currentMV[0].y = RRV_MV_SCALEDOWN(Data->currentMV[0].y);
1038            }
1039    
1040            if (mode == MODE_INTER) {
1041                    pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0];
1042                    pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = Data->iMinSAD[0];
1043    
1044                    if(Data->qpel) {
1045                            pMB->qmvs[0] = pMB->qmvs[1]
1046                                    = pMB->qmvs[2] = pMB->qmvs[3] = Data->currentQMV[0];
1047                            pMB->pmvs[0].x = Data->currentQMV[0].x - Data->predMV.x;
1048                            pMB->pmvs[0].y = Data->currentQMV[0].y - Data->predMV.y;
1049                    } else {
1050                            pMB->pmvs[0].x = Data->currentMV[0].x - Data->predMV.x;
1051                            pMB->pmvs[0].y = Data->currentMV[0].y - Data->predMV.y;
1052                    }
1053    
1054            } else if (mode == MODE_INTER4V)
1055                    pMB->sad16 = Data->iMinSAD[0];
1056            else // INTRA, NOT_CODED
1057                    SkipMacroblockP(pMB, 0);
1058    
1059            pMB->mode = mode;
1060    }
1061    
1062  bool  bool
1063  MotionEstimation(MBParam * const pParam,  MotionEstimation(MBParam * const pParam,
1064                                   FRAMEINFO * const current,                                   FRAMEINFO * const current,
# Line 1030  Line 1103 
1103          Data.chroma = MotionFlags & PMV_CHROMA16;          Data.chroma = MotionFlags & PMV_CHROMA16;
1104          Data.rrv = current->global_flags & XVID_REDUCED;          Data.rrv = current->global_flags & XVID_REDUCED;
1105          Data.dctSpace = dct_space;          Data.dctSpace = dct_space;
1106            Data.quant_type = pParam->m_quant_type;
1107    
1108          if ((current->global_flags & XVID_REDUCED)) {          if ((current->global_flags & XVID_REDUCED)) {
1109                  mb_width = (pParam->width + 31) / 32;                  mb_width = (pParam->width + 31) / 32;
# Line 1064  Line 1138 
1138    
1139                          sad00 = pMB->sad16;                          sad00 = pMB->sad16;
1140    
1141                          if (!(current->global_flags & XVID_LUMIMASKING)) {                          if (!(current->global_flags & XVID_LUMIMASKING))
1142                                  pMB->dquant = NO_CHANGE;                                  pMB->dquant = NO_CHANGE;
1143                          } else {                          else {
1144                                  if (pMB->dquant != NO_CHANGE) {                                  if (pMB->dquant != NO_CHANGE) {
1145                                          quant += DQtab[pMB->dquant];                                          quant += DQtab[pMB->dquant];
1146                                          if (quant > 31) quant = 31;                                          if (quant > 31) quant = 31;
1147                                          else if (quant < 1) quant = 1;                                          else if (quant < 1) quant = 1;
1148                                  }                                  }
1149                          }                          }
1150                          pMB->quant = current->quant;                          pMB->quant = quant;
1151    
1152  //initial skip decision  //initial skip decision
1153  /* no early skip for GMC (global vector = skip vector is unknown!)  */  /* no early skip for GMC (global vector = skip vector is unknown!)  */
1154                          if (!(current->global_flags & XVID_GMC))        { /* no fast SKIP for S(GMC)-VOPs */                          if (!(current->global_flags & XVID_GMC))        { /* no fast SKIP for S(GMC)-VOPs */
1155                                  if (pMB->dquant == NO_CHANGE && sad00 < pMB->quant * skip_thresh)                                  if (pMB->dquant == NO_CHANGE && sad00 < quant * skip_thresh)
1156                                          if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv)) {                                          if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv)) {
1157                                                  SkipMacroblockP(pMB, sad00);                                                  SkipMacroblockP(pMB, sad00);
1158                                                  continue;                                                  continue;
# Line 1086  Line 1160 
1160                          }                          }
1161    
1162                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,                          SearchP(pRef, pRefH->y, pRefV->y, pRefHV->y, pCurrent, x,
1163                                                  y, MotionFlags, current->global_flags, pMB->quant,                                                  y, MotionFlags, current->global_flags,
1164                                                  &Data, pParam, pMBs, reference->mbs,                                                  &Data, pParam, pMBs, reference->mbs, pMB);
1165                                                  current->global_flags & XVID_INTER4V, pMB);  
1166                            ModeDecision(&Data, pMB, pMBs, x, y, pParam,
1167                                                            MotionFlags, current->global_flags,
1168                                                            pCurrent, pRef);
1169    
 /* final skip decision, a.k.a. "the vector you found, really that good?" */  
                         if (!(current->global_flags & XVID_GMC || current->global_flags & XVID_MODEDECISION_BITS)) {  
                                 if ( pMB->dquant == NO_CHANGE && sad00 < pMB->quant * MAX_SAD00_FOR_SKIP) {  
                                         if ( (100*pMB->sad16)/(sad00+1) > FINAL_SKIP_THRESH * (Data.rrv ? 4:1) )  
                                                 if (Data.chroma || SkipDecisionP(pCurrent, pRef, x, y, iEdgedWidth/2, pMB->quant, Data.rrv))  
                                                         SkipMacroblockP(pMB, sad00);  
                                 }  
                         }  
1170                          if (pMB->mode == MODE_INTRA)                          if (pMB->mode == MODE_INTRA)
1171                                  if (++iIntra > iLimit) return 1;                                  if (++iIntra > iLimit) return 1;
1172                  }                  }
# Line 1170  Line 1239 
1239          }          }
1240  }  }
1241    
 static int  
 ModeDecision(const uint32_t iQuant, SearchData * const Data,  
                 int inter4v,  
                 MACROBLOCK * const pMB,  
                 const MACROBLOCK * const pMBs,  
                 const int x, const int y,  
                 const MBParam * const pParam,  
                 const uint32_t MotionFlags,  
                 const uint32_t GlobalFlags)  
 {  
   
         int mode = MODE_INTER;  
   
         if (!(GlobalFlags & XVID_MODEDECISION_BITS)) { //normal, fast, SAD-based mode decision  
                 int sad;  
                 int InterBias = MV16_INTER_BIAS;  
                 if (inter4v == 0 || Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] +  
                         Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant) {  
                         mode = MODE_INTER;  
                         sad = Data->iMinSAD[0];  
                 } else {  
                         mode = MODE_INTER4V;  
                         sad = Data->iMinSAD[1] + Data->iMinSAD[2] +  
                                                 Data->iMinSAD[3] + Data->iMinSAD[4] + IMV16X16 * (int32_t)iQuant;  
                         Data->iMinSAD[0] = sad;  
                 }  
   
                 /* intra decision */  
   
                 if (iQuant > 8) InterBias += 100 * (iQuant - 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(Data->Cur, Data->iEdgedWidth);  
                         else deviation = dev16(Data->Cur, Data->iEdgedWidth) +  
                                 dev16(Data->Cur+8, Data->iEdgedWidth) +  
                                 dev16(Data->Cur + 8*Data->iEdgedWidth, Data->iEdgedWidth) +  
                                 dev16(Data->Cur+8+8*Data->iEdgedWidth, Data->iEdgedWidth);  
   
                         if (deviation < (sad - InterBias)) return MODE_INTRA;  
                 }  
                 return mode;  
   
         } else {  
   
                 int bits, intra, i;  
                 VECTOR backup[5], *v;  
                 Data->lambda16 = iQuant;  
                 Data->lambda8 = pParam->m_quant_type;  
   
                 v = Data->qpel ? Data->currentQMV : Data->currentMV;  
                 for (i = 0; i < 5; i++) {  
                         Data->iMinSAD[i] = 256*4096;  
                         backup[i] = v[i];  
                 }  
   
                 bits = CountMBBitsInter(Data, pMBs, x, y, pParam, MotionFlags);  
                 if (bits == 0) return MODE_INTER; // quick stop  
   
                 if (inter4v) {  
                         int bits_inter4v = CountMBBitsInter4v(Data, pMB, pMBs, x, y, pParam, MotionFlags, backup);  
                         if (bits_inter4v < bits) { Data->iMinSAD[0] = bits = bits_inter4v; mode = MODE_INTER4V; }  
                 }  
   
   
                 intra = CountMBBitsIntra(Data);  
   
                 if (intra < bits) { *Data->iMinSAD = bits = intra; return MODE_INTRA; }  
   
                 return mode;  
         }  
 }  
   
1242  static void  static void
1243  SearchP(const IMAGE * const pRef,  SearchP(const IMAGE * const pRef,
1244                  const uint8_t * const pRefH,                  const uint8_t * const pRefH,
# Line 1260  Line 1249 
1249                  const int y,                  const int y,
1250                  const uint32_t MotionFlags,                  const uint32_t MotionFlags,
1251                  const uint32_t GlobalFlags,                  const uint32_t GlobalFlags,
                 const uint32_t iQuant,  
1252                  SearchData * const Data,                  SearchData * const Data,
1253                  const MBParam * const pParam,                  const MBParam * const pParam,
1254                  const MACROBLOCK * const pMBs,                  const MACROBLOCK * const pMBs,
1255                  const MACROBLOCK * const prevMBs,                  const MACROBLOCK * const prevMBs,
                 int inter4v,  
1256                  MACROBLOCK * const pMB)                  MACROBLOCK * const pMB)
1257  {  {
1258    
1259          int i, iDirection = 255, mask, threshA;          int i, iDirection = 255, mask, threshA;
1260          VECTOR pmv[7];          VECTOR pmv[7];
1261            int inter4v = (GlobalFlags & XVID_INTER4V) && (pMB->dquant == NO_CHANGE);
1262    
1263          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,
1264                                                  pParam->width, pParam->height, Data->iFcode - Data->qpel, 0, Data->rrv);                                                  pParam->width, pParam->height, Data->iFcode - Data->qpel, 0, Data->rrv);
# Line 1283  Line 1271 
1271          Data->CurV = pCur->v + (x + y * (Data->iEdgedWidth/2)) * 8*i;          Data->CurV = pCur->v + (x + y * (Data->iEdgedWidth/2)) * 8*i;
1272          Data->CurU = pCur->u + (x + y * (Data->iEdgedWidth/2)) * 8*i;          Data->CurU = pCur->u + (x + y * (Data->iEdgedWidth/2)) * 8*i;
1273    
1274          Data->Ref = pRef->y + (x + Data->iEdgedWidth*y) * 16*i;          Data->RefP[0] = pRef->y + (x + Data->iEdgedWidth*y) * 16*i;
1275          Data->RefH = pRefH + (x + Data->iEdgedWidth*y) * 16*i;          Data->RefP[2] = pRefH + (x + Data->iEdgedWidth*y) * 16*i;
1276          Data->RefV = pRefV + (x + Data->iEdgedWidth*y) * 16*i;          Data->RefP[1] = pRefV + (x + Data->iEdgedWidth*y) * 16*i;
1277          Data->RefHV = pRefHV + (x + Data->iEdgedWidth*y) * 16*i;          Data->RefP[3] = pRefHV + (x + Data->iEdgedWidth*y) * 16*i;
1278          Data->RefCV = pRef->v + (x + y * (Data->iEdgedWidth/2)) * 8*i;          Data->RefP[4] = pRef->u + (x + y * (Data->iEdgedWidth/2)) * 8*i;
1279          Data->RefCU = pRef->u + (x + y * (Data->iEdgedWidth/2)) * 8*i;          Data->RefP[5] = pRef->v + (x + y * (Data->iEdgedWidth/2)) * 8*i;
1280    
1281          Data->lambda16 = lambda_vec16[iQuant];          Data->lambda16 = lambda_vec16[pMB->quant];
1282          Data->lambda8 = lambda_vec8[iQuant];          Data->lambda8 = lambda_vec8[pMB->quant];
1283          Data->qpel_precision = 0;          Data->qpel_precision = 0;
1284    
         if (pMB->dquant != NO_CHANGE) inter4v = 0;  
   
1285          memset(Data->currentMV, 0, 5*sizeof(VECTOR));          memset(Data->currentMV, 0, 5*sizeof(VECTOR));
1286    
1287          if (Data->qpel) Data->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x, y, 0);          if (Data->qpel) Data->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x, y, 0);
# Line 1308  Line 1294 
1294          Data->iMinSAD[3] = pMB->sad8[2];          Data->iMinSAD[3] = pMB->sad8[2];
1295          Data->iMinSAD[4] = pMB->sad8[3];          Data->iMinSAD[4] = pMB->sad8[3];
1296    
1297          if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) || (x | y)) {          if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) && (x | y)) {
1298                  threshA = Data->temp[0]; // that's where we keep this SAD atm                  threshA = Data->temp[0]; // that's where we keep this SAD atm
1299                  if (threshA < 512) threshA = 512;                  if (threshA < 512) threshA = 512;
1300                  else if (threshA > 1024) threshA = 1024;                  else if (threshA > 1024) threshA = 1024;
# Line 1333  Line 1319 
1319    
1320          if ((Data->iMinSAD[0] <= threshA) ||          if ((Data->iMinSAD[0] <= threshA) ||
1321                          (MVequal(Data->currentMV[0], (prevMBs+x+y*pParam->mb_width)->mvs[0]) &&                          (MVequal(Data->currentMV[0], (prevMBs+x+y*pParam->mb_width)->mvs[0]) &&
1322                          (Data->iMinSAD[0] < (prevMBs+x+y*pParam->mb_width)->sad16))) {                          (Data->iMinSAD[0] < (prevMBs+x+y*pParam->mb_width)->sad16)))
1323                  if (!(GlobalFlags & XVID_MODEDECISION_BITS)) inter4v = 0;       }                  inter4v = 0;
1324          else {          else {
1325    
1326                  MainSearchFunc * MainSearchPtr;                  MainSearchFunc * MainSearchPtr;
# Line 1380  Line 1366 
1366          }          }
1367    
1368          if (MotionFlags & PMV_HALFPELREFINE16)          if (MotionFlags & PMV_HALFPELREFINE16)
                 if ((!(MotionFlags & HALFPELREFINE16_BITS)) || Data->iMinSAD[0] < 200*(int)iQuant)  
1369                          SubpelRefine(Data);                          SubpelRefine(Data);
1370    
1371          for(i = 0; i < 5; i++) {          for(i = 0; i < 5; i++) {
# Line 1388  Line 1373 
1373                  Data->currentQMV[i].y = 2 * Data->currentMV[i].y;                  Data->currentQMV[i].y = 2 * Data->currentMV[i].y;
1374          }          }
1375    
1376          if (MotionFlags & PMV_QUARTERPELREFINE16) {          if (Data->qpel) {
   
1377                  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,
1378                                  pParam->width, pParam->height, Data->iFcode, 1, 0);                                  pParam->width, pParam->height, Data->iFcode, 1, 0);
   
                 if ((!(MotionFlags & QUARTERPELREFINE16_BITS)) || (Data->iMinSAD[0] < 200*(int)iQuant)) {  
1379                          Data->qpel_precision = 1;                          Data->qpel_precision = 1;
1380                    if (MotionFlags & PMV_QUARTERPELREFINE16)
1381                          SubpelRefine(Data);                          SubpelRefine(Data);
1382                  }                  }
         }  
1383    
1384          if ((!(GlobalFlags & XVID_MODEDECISION_BITS)) && (Data->iMinSAD[0] < (int32_t)iQuant * 30)) inter4v = 0;          if (Data->iMinSAD[0] < (int32_t)pMB->quant * 30)
1385                    inter4v = 0;
         if (inter4v && (!(GlobalFlags & XVID_MODEDECISION_BITS) ||  
                         (!(MotionFlags & QUARTERPELREFINE8_BITS)) || (!(MotionFlags & HALFPELREFINE8_BITS)) ||  
                         ((!(MotionFlags & EXTSEARCH_BITS)) && (!(MotionFlags&PMV_EXTSEARCH8)) ))) {  
                 // if decision is BITS-based and all refinement steps will be done in BITS domain, there is no reason to call this loop  
1386    
1387            if (inter4v) {
1388                  SearchData Data8;                  SearchData Data8;
1389                  memcpy(&Data8, Data, sizeof(SearchData)); //quick copy of common data                  memcpy(&Data8, Data, sizeof(SearchData)); //quick copy of common data
1390    
# Line 1415  Line 1394 
1394                  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);
1395    
1396                  if ((Data->chroma) && (!(GlobalFlags & XVID_MODEDECISION_BITS))) {                  if ((Data->chroma) && (!(GlobalFlags & XVID_MODEDECISION_BITS))) {
1397                          // chroma is only used for comparsion to INTER. if the comparsion will be done in BITS domain, there is no reason to compute it                          // chroma is only used for comparsion to INTER. if the comparsion will be done in BITS domain, it will not be used
1398                          int sumx = 0, sumy = 0;                          int sumx = 0, sumy = 0;
                         const int div = 1 + Data->qpel;  
                         const VECTOR * const mv = Data->qpel ? pMB->qmvs : pMB->mvs;  
1399    
1400                          for (i = 0; i < 4; i++) {                          if (Data->qpel)
1401                                  sumx += mv[i].x / div;                                  for (i = 1; i < 5; i++) {
1402                                  sumy += mv[i].y / div;                                          sumx += Data->currentQMV[i].x/2;
1403                                            sumy += Data->currentQMV[i].y/2;
1404                                    }
1405                            else
1406                                    for (i = 1; i < 5; i++) {
1407                                            sumx += Data->currentMV[i].x;
1408                                            sumy += Data->currentMV[i].y;
1409                          }                          }
1410    
1411                          Data->iMinSAD[1] += ChromaSAD(  (sumx >> 3) + roundtab_76[sumx & 0xf],                          Data->iMinSAD[1] += ChromaSAD(  (sumx >> 3) + roundtab_76[sumx & 0xf],
1412                                                                                          (sumy >> 3) + roundtab_76[sumy & 0xf], Data);                                                                                          (sumy >> 3) + roundtab_76[sumy & 0xf], Data);
1413                  }                  }
1414          }          } else Data->iMinSAD[1] = 4096*256;
   
         inter4v = ModeDecision(iQuant, Data, inter4v, pMB, pMBs, x, y, pParam, MotionFlags, GlobalFlags);  
   
         if (Data->rrv) {  
                         Data->currentMV[0].x = RRV_MV_SCALEDOWN(Data->currentMV[0].x);  
                         Data->currentMV[0].y = RRV_MV_SCALEDOWN(Data->currentMV[0].y);  
         }  
   
         if (inter4v == MODE_INTER) {  
                 pMB->mode = MODE_INTER;  
                 pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = Data->currentMV[0];  
                 pMB->sad16 = pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = Data->iMinSAD[0];  
   
                 if(Data->qpel) {  
                         pMB->qmvs[0] = pMB->qmvs[1]  
                                 = pMB->qmvs[2] = pMB->qmvs[3] = Data->currentQMV[0];  
                         pMB->pmvs[0].x = Data->currentQMV[0].x - Data->predMV.x;  
                         pMB->pmvs[0].y = Data->currentQMV[0].y - Data->predMV.y;  
                 } else {  
                         pMB->pmvs[0].x = Data->currentMV[0].x - Data->predMV.x;  
                         pMB->pmvs[0].y = Data->currentMV[0].y - Data->predMV.y;  
                 }  
   
         } else if (inter4v == MODE_INTER4V) {  
                 pMB->mode = MODE_INTER4V;  
                 pMB->sad16 = Data->iMinSAD[0];  
         } else { // INTRA mode  
                 SkipMacroblockP(pMB, 0); // not skip, but similar enough  
                 pMB->mode = MODE_INTRA;  
         }  
   
1415  }  }
1416    
1417  static void  static void
# Line 1490  Line 1442 
1442          *(Data->iMinSAD) += (Data->lambda8 * i * (*Data->iMinSAD + NEIGH_8X8_BIAS))>>10;          *(Data->iMinSAD) += (Data->lambda8 * i * (*Data->iMinSAD + NEIGH_8X8_BIAS))>>10;
1443    
1444          if (MotionFlags & (PMV_EXTSEARCH8|PMV_HALFPELREFINE8|PMV_QUARTERPELREFINE8)) {          if (MotionFlags & (PMV_EXTSEARCH8|PMV_HALFPELREFINE8|PMV_QUARTERPELREFINE8)) {
                 if (Data->rrv) i = 2; else i = 1;  
1445    
1446                  Data->Ref = OldData->Ref + i * 8 * ((block&1) + Data->iEdgedWidth*(block>>1));                  if (Data->rrv) i = 16; else i = 8;
                 Data->RefH = OldData->RefH + i * 8 * ((block&1) + Data->iEdgedWidth*(block>>1));  
                 Data->RefV = OldData->RefV + i * 8 * ((block&1) + Data->iEdgedWidth*(block>>1));  
                 Data->RefHV = OldData->RefHV + i * 8 * ((block&1) + Data->iEdgedWidth*(block>>1));  
1447    
1448                  Data->Cur = OldData->Cur + i * 8 * ((block&1) + Data->iEdgedWidth*(block>>1));                  Data->RefP[0] = OldData->RefP[0] + i * ((block&1) + Data->iEdgedWidth*(block>>1));
1449                    Data->RefP[1] = OldData->RefP[1] + i * ((block&1) + Data->iEdgedWidth*(block>>1));
1450                    Data->RefP[2] = OldData->RefP[2] + i * ((block&1) + Data->iEdgedWidth*(block>>1));
1451                    Data->RefP[3] = OldData->RefP[3] + i * ((block&1) + Data->iEdgedWidth*(block>>1));
1452    
1453                    Data->Cur = OldData->Cur + i * ((block&1) + Data->iEdgedWidth*(block>>1));
1454                  Data->qpel_precision = 0;                  Data->qpel_precision = 0;
1455    
1456                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8,                  get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8,
# Line 1631  Line 1584 
1584          Data->qpel_precision = 0;          Data->qpel_precision = 0;
1585          Data->temp[5] = Data->temp[6] = Data->temp[7] = 256*4096; // reset chroma-sad cache          Data->temp[5] = Data->temp[6] = Data->temp[7] = 256*4096; // reset chroma-sad cache
1586    
1587          Data->Ref = pRef->y + (x + y * Data->iEdgedWidth) * 16;          Data->RefP[0] = pRef->y + (x + Data->iEdgedWidth*y) * 16;
1588          Data->RefH = pRefH + (x + y * Data->iEdgedWidth) * 16;          Data->RefP[2] = pRefH + (x + Data->iEdgedWidth*y) * 16;
1589          Data->RefV = pRefV + (x + y * Data->iEdgedWidth) * 16;          Data->RefP[1] = pRefV + (x + Data->iEdgedWidth*y) * 16;
1590          Data->RefHV = pRefHV + (x + y * Data->iEdgedWidth) * 16;          Data->RefP[3] = pRefHV + (x + Data->iEdgedWidth*y) * 16;
1591          Data->RefCU = pRef->u + (x + y * Data->iEdgedWidth/2) * 8;          Data->RefP[4] = pRef->u + (x + y * (Data->iEdgedWidth/2)) * 8;
1592          Data->RefCV = pRef->v + (x + y * Data->iEdgedWidth/2) * 8;          Data->RefP[5] = pRef->v + (x + y * (Data->iEdgedWidth/2)) * 8;
1593    
1594          Data->predMV = *predMV;          Data->predMV = *predMV;
1595    
# Line 1774  Line 1727 
1727          MainSearchFunc *MainSearchPtr;          MainSearchFunc *MainSearchPtr;
1728    
1729          *Data->iMinSAD = 256*4096;          *Data->iMinSAD = 256*4096;
1730          Data->Ref = f_Ref->y + k;          Data->RefP[0] = f_Ref->y + k;
1731          Data->RefH = f_RefH + k;          Data->RefP[2] = f_RefH + k;
1732          Data->RefV = f_RefV + k;          Data->RefP[1] = f_RefV + k;
1733          Data->RefHV = f_RefHV + k;          Data->RefP[3] = f_RefHV + k;
1734          Data->bRef = b_Ref->y + k;          Data->b_RefP[0] = b_Ref->y + k;
1735          Data->bRefH = b_RefH + k;          Data->b_RefP[2] = b_RefH + k;
1736          Data->bRefV = b_RefV + k;          Data->b_RefP[1] = b_RefV + k;
1737          Data->bRefHV = b_RefHV + k;          Data->b_RefP[3] = b_RefHV + k;
1738          Data->RefCU = f_Ref->u + (x + (Data->iEdgedWidth/2) * y) * 8;          Data->RefP[4] = f_Ref->u + (x + (Data->iEdgedWidth/2) * y) * 8;
1739          Data->RefCV = f_Ref->v + (x + (Data->iEdgedWidth/2) * y) * 8;          Data->RefP[5] = f_Ref->v + (x + (Data->iEdgedWidth/2) * y) * 8;
1740          Data->b_RefCU = b_Ref->u + (x + (Data->iEdgedWidth/2) * y) * 8;          Data->b_RefP[4] = b_Ref->u + (x + (Data->iEdgedWidth/2) * y) * 8;
1741          Data->b_RefCV = b_Ref->v + (x + (Data->iEdgedWidth/2) * y) * 8;          Data->b_RefP[5] = b_Ref->v + (x + (Data->iEdgedWidth/2) * y) * 8;
1742    
1743          k = Data->qpel ? 4 : 2;          k = Data->qpel ? 4 : 2;
1744          Data->max_dx = k * (pParam->width - x * 16);          Data->max_dx = k * (pParam->width - x * 16);
# Line 1824  Line 1777 
1777          CheckCandidate(0, 0, 255, &k, Data);          CheckCandidate(0, 0, 255, &k, Data);
1778    
1779  // initial (fast) skip decision  // initial (fast) skip decision
1780          if (*Data->iMinSAD < pMB->quant * INITIAL_SKIP_THRESH * (2 + Data->chroma?1:0)) {          if (*Data->iMinSAD < pMB->quant * INITIAL_SKIP_THRESH * (Data->chroma?3:2)) {
1781                  //possible skip                  //possible skip
1782                  if (Data->chroma) {                  if (Data->chroma) {
1783                          pMB->mode = MODE_DIRECT_NONE_MV;                          pMB->mode = MODE_DIRECT_NONE_MV;
# Line 1916  Line 1869 
1869          fData->iFcode = bData.bFcode = fcode; fData->bFcode = bData.iFcode = bcode;          fData->iFcode = bData.bFcode = fcode; fData->bFcode = bData.iFcode = bcode;
1870    
1871          i = (x + y * fData->iEdgedWidth) * 16;          i = (x + y * fData->iEdgedWidth) * 16;
         bData.bRef = fData->Ref = f_Ref->y + i;  
         bData.bRefH = fData->RefH = f_RefH + i;  
         bData.bRefV = fData->RefV = f_RefV + i;  
         bData.bRefHV = fData->RefHV = f_RefHV + i;  
         bData.Ref = fData->bRef = b_Ref->y + i;  
         bData.RefH = fData->bRefH = b_RefH + i;  
         bData.RefV = fData->bRefV = b_RefV + i;  
         bData.RefHV = fData->bRefHV = b_RefHV + i;  
         bData.b_RefCU = fData->RefCU = f_Ref->u + (x + (fData->iEdgedWidth/2) * y) * 8;  
         bData.b_RefCV = fData->RefCV = f_Ref->v + (x + (fData->iEdgedWidth/2) * y) * 8;  
         bData.RefCU = fData->b_RefCU = b_Ref->u + (x + (fData->iEdgedWidth/2) * y) * 8;  
         bData.RefCV = fData->b_RefCV = b_Ref->v + (x + (fData->iEdgedWidth/2) * y) * 8;  
1872    
1873            bData.b_RefP[0] = fData->RefP[0] = f_Ref->y + i;
1874            bData.b_RefP[2] = fData->RefP[2] = f_RefH + i;
1875            bData.b_RefP[1] = fData->RefP[1] = f_RefV + i;
1876            bData.b_RefP[3] = fData->RefP[3] = f_RefHV + i;
1877            bData.RefP[0] = fData->b_RefP[0] = b_Ref->y + i;
1878            bData.RefP[2] = fData->b_RefP[2] = b_RefH + i;
1879            bData.RefP[1] = fData->b_RefP[1] = b_RefV + i;
1880            bData.RefP[3] = fData->b_RefP[3] = b_RefHV + i;
1881            bData.b_RefP[4] = fData->RefP[4] = f_Ref->u + (x + (fData->iEdgedWidth/2) * y) * 8;
1882            bData.b_RefP[5] = fData->RefP[5] = f_Ref->v + (x + (fData->iEdgedWidth/2) * y) * 8;
1883            bData.RefP[4] = fData->b_RefP[4] = b_Ref->u + (x + (fData->iEdgedWidth/2) * y) * 8;
1884            bData.RefP[5] = fData->b_RefP[5] = b_Ref->v + (x + (fData->iEdgedWidth/2) * y) * 8;
1885    
1886          bData.bpredMV = fData->predMV = *f_predMV;          bData.bpredMV = fData->predMV = *f_predMV;
1887          fData->bpredMV = bData.predMV = *b_predMV;          fData->bpredMV = bData.predMV = *b_predMV;
# Line 2179  Line 2132 
2132                                  pParam->width, pParam->height, Data->iFcode - pParam->m_quarterpel, 0, 0);                                  pParam->width, pParam->height, Data->iFcode - pParam->m_quarterpel, 0, 0);
2133    
2134          Data->Cur = pCur + (x + y * pParam->edged_width) * 16;          Data->Cur = pCur + (x + y * pParam->edged_width) * 16;
2135          Data->Ref = pRef + (x + y * pParam->edged_width) * 16;          Data->RefP[0] = pRef + (x + y * pParam->edged_width) * 16;
2136    
2137          pmv[1].x = EVEN(pMB->mvs[0].x);          pmv[1].x = EVEN(pMB->mvs[0].x);
2138          pmv[1].y = EVEN(pMB->mvs[0].y);          pmv[1].y = EVEN(pMB->mvs[0].y);
# Line 2188  Line 2141 
2141          pmv[0].x = pmv[0].y = 0;          pmv[0].x = pmv[0].y = 0;
2142    
2143          CheckCandidate32I(0, 0, 255, &i, Data);          CheckCandidate32I(0, 0, 255, &i, Data);
         Data->iMinSAD[1] -= 50;  
         Data->iMinSAD[2] -= 50;  
         Data->iMinSAD[3] -= 50;  
         Data->iMinSAD[4] -= 50;  
2144    
2145          if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP) {          if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP) {
2146    
# Line 2212  Line 2161 
2161          }          }
2162  }  }
2163    
2164  #define INTRA_THRESH    2400  #define INTRA_THRESH    1700
2165  #define INTER_THRESH    1100  #define INTER_THRESH    1200
2166    
2167  int  int
2168  MEanalysis(     const IMAGE * const pRef,  MEanalysis(     const IMAGE * const pRef,
# Line 2241  Line 2190 
2190          Data.temp = temp;          Data.temp = temp;
2191          CheckCandidate = CheckCandidate32I;          CheckCandidate = CheckCandidate32I;
2192    
2193          if (intraCount != 0 && intraCount < 10) // we're right after an I frame          if (intraCount != 0) {
2194                  IntraThresh += 8 * (intraCount - 10) * (intraCount - 10);                  if (intraCount < 10) // we're right after an I frame
2195                            IntraThresh += 15* (intraCount - 10) * (intraCount - 10);
2196          else          else
2197                  if ( 5*(maxIntra - intraCount) < maxIntra) // we're close to maximum. 2 sec when max is 10 sec                  if ( 5*(maxIntra - intraCount) < maxIntra) // we're close to maximum. 2 sec when max is 10 sec
2198                          IntraThresh -= (IntraThresh * (maxIntra - 5*(maxIntra - intraCount)))/maxIntra;                                  IntraThresh -= (IntraThresh * (maxIntra - 8*(maxIntra - intraCount)))/maxIntra;
2199            }
2200    
2201          InterThresh -= (350 - 8*b_thresh) * bCount;          InterThresh -= (350 - 8*b_thresh) * bCount;
2202          if (InterThresh < 300 + 5*b_thresh) InterThresh = 300 + 5*b_thresh;          if (InterThresh < 300 + 5*b_thresh) InterThresh = 300 + 5*b_thresh;
# Line 2286  Line 2237 
2237          }          }
2238    
2239          sSAD /= blocks;          sSAD /= blocks;
         s = (10*s) / blocks;  
2240    
2241          if (s > 5) sSAD += (s - 4) * (180 - 2*b_thresh); //static block - looks bad when in bframe...          if (b_thresh < 20) {
2242                    s = (10*s) / blocks;
2243                    if (s > 4) sSAD += (s - 2) * (40 - 2*b_thresh); //static block - looks bad when in bframe...
2244            }
2245    
2246          if (sSAD > InterThresh ) return P_VOP;          if (sSAD > InterThresh ) return P_VOP;
2247          emms();          emms();
# Line 2342  Line 2295 
2295                  if (pMB->mode == MODE_INTRA || pMB->mode == MODE_NOT_CODED)                  if (pMB->mode == MODE_INTRA || pMB->mode == MODE_NOT_CODED)
2296                          continue;                          continue;
2297    
2298                  if ( ( (ABS(mv.x -   (pMB-1)->mvs[0].x) < deltax) && (ABS(mv.y -   (pMB-1)->mvs[0].y) < deltay) )                  if ( ( (abs(mv.x -   (pMB-1)->mvs[0].x) < deltax) && (abs(mv.y -   (pMB-1)->mvs[0].y) < deltay) )
2299                  &&   ( (ABS(mv.x -   (pMB+1)->mvs[0].x) < deltax) && (ABS(mv.y -   (pMB+1)->mvs[0].y) < deltay) )                  &&   ( (abs(mv.x -   (pMB+1)->mvs[0].x) < deltax) && (abs(mv.y -   (pMB+1)->mvs[0].y) < deltay) )
2300                  &&   ( (ABS(mv.x - (pMB-MBw)->mvs[0].x) < deltax) && (ABS(mv.y - (pMB-MBw)->mvs[0].y) < deltay) )                  &&   ( (abs(mv.x - (pMB-MBw)->mvs[0].x) < deltax) && (abs(mv.y - (pMB-MBw)->mvs[0].y) < deltay) )
2301                  &&   ( (ABS(mv.x - (pMB+MBw)->mvs[0].x) < deltax) && (ABS(mv.y - (pMB+MBw)->mvs[0].y) < deltay) ) )                  &&   ( (abs(mv.x - (pMB+MBw)->mvs[0].x) < deltax) && (abs(mv.y - (pMB+MBw)->mvs[0].y) < deltay) ) )
2302                          MBmask[mbnum]=1;                          MBmask[mbnum]=1;
2303          }          }
2304    
# Line 2420  Line 2373 
2373                                  continue;                                  continue;
2374    
2375                          oldnum++;                          oldnum++;
2376                          meanx += ABS(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x );                          meanx += fabs(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x );
2377                          meany += ABS(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y );                          meany += fabs(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y );
2378                  }                  }
2379    
2380          if (4*meanx > oldnum)   /* better fit than 0.25 is useless */          if (4*meanx > oldnum)   /* better fit than 0.25 is useless */
# Line 2448  Line 2401 
2401                          if (!MBmask[mbnum])                          if (!MBmask[mbnum])
2402                                  continue;                                  continue;
2403    
2404                          if  ( ( ABS(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x ) > meanx )                          if  ( ( fabs(( sol[0] + (16*mx+8)*sol[1] + (16*my+8)*sol[2] ) - mv.x ) > meanx )
2405                             || ( ABS(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y ) > meany ) )                                  || ( fabs(( sol[3] - (16*mx+8)*sol[2] + (16*my+8)*sol[1] ) - mv.y ) > meany ) )
2406                                  MBmask[mbnum]=0;                                  MBmask[mbnum]=0;
2407                          else                          else
2408                                  num++;                                  num++;
# Line 2499  Line 2452 
2452                  Data->qpel_precision = 1;                  Data->qpel_precision = 1;
2453                  CheckCandidateBits16(Data->currentQMV[0].x, Data->currentQMV[0].y, 255, &iDirection, Data);                  CheckCandidateBits16(Data->currentQMV[0].x, Data->currentQMV[0].y, 255, &iDirection, Data);
2454    
                 //checking if this vector is perfect. if it is, we stop.  
                 if (Data->temp[0] == 0 && Data->temp[1] == 0 && Data->temp[2] == 0 && Data->temp[3] == 0)  
                         return 0; //quick stop  
   
2455                  if (MotionFlags & (HALFPELREFINE16_BITS | EXTSEARCH_BITS)) { //we have to prepare for halfpixel-precision search                  if (MotionFlags & (HALFPELREFINE16_BITS | EXTSEARCH_BITS)) { //we have to prepare for halfpixel-precision search
2456                          for(i = 0; i < 5; i++) bsad[i] = Data->iMinSAD[i];                          for(i = 0; i < 5; i++) bsad[i] = Data->iMinSAD[i];
2457                          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,
# Line 2515  Line 2464 
2464          } else { // not qpel          } else { // not qpel
2465    
2466                  CheckCandidateBits16(Data->currentMV[0].x, Data->currentMV[0].y, 255, &iDirection, Data);                  CheckCandidateBits16(Data->currentMV[0].x, Data->currentMV[0].y, 255, &iDirection, Data);
                 //checking if this vector is perfect. if it is, we stop.  
                 if (Data->temp[0] == 0 && Data->temp[1] == 0 && Data->temp[2] == 0 && Data->temp[3] == 0) {  
                         return 0; //inter  
                 }  
2467          }          }
2468    
2469          if (MotionFlags&EXTSEARCH_BITS) SquareSearch(Data->currentMV->x, Data->currentMV->y, Data, iDirection);          if (MotionFlags&EXTSEARCH_BITS) SquareSearch(Data->currentMV->x, Data->currentMV->y, Data, iDirection);
# Line 2548  Line 2493 
2493          return Data->iMinSAD[0];          return Data->iMinSAD[0];
2494  }  }
2495    
   
2496  static int  static int
2497  CountMBBitsInter4v(const SearchData * const Data,  CountMBBitsInter4v(const SearchData * const Data,
2498                                          MACROBLOCK * const pMB, const MACROBLOCK * const pMBs,                                          MACROBLOCK * const pMB, const MACROBLOCK * const pMBs,
# Line 2561  Line 2505 
2505          SearchData Data2, *Data8 = &Data2;          SearchData Data2, *Data8 = &Data2;
2506          int sumx = 0, sumy = 0;          int sumx = 0, sumy = 0;
2507          int16_t *in = Data->dctSpace, *coeff = Data->dctSpace + 64;          int16_t *in = Data->dctSpace, *coeff = Data->dctSpace + 64;
2508            uint8_t * ptr;
2509    
2510          memcpy(Data8, Data, sizeof(SearchData));          memcpy(Data8, Data, sizeof(SearchData));
2511          CheckCandidate = CheckCandidateBits8;          CheckCandidate = CheckCandidateBits8;
2512    
2513          for (i = 0; i < 4; i++) {          for (i = 0; i < 4; i++) { //for all luma blocks
2514    
2515                  Data8->iMinSAD = Data->iMinSAD + i + 1;                  Data8->iMinSAD = Data->iMinSAD + i + 1;
2516                  Data8->currentMV = Data->currentMV + i + 1;                  Data8->currentMV = Data->currentMV + i + 1;
2517                  Data8->currentQMV = Data->currentQMV + i + 1;                  Data8->currentQMV = Data->currentQMV + i + 1;
2518                  Data8->Cur = Data->Cur + 8*((i&1) + (i>>1)*Data->iEdgedWidth);                  Data8->Cur = Data->Cur + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2519                  Data8->Ref = Data->Ref + 8*((i&1) + (i>>1)*Data->iEdgedWidth);                  Data8->RefP[0] = Data->RefP[0] + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2520                  Data8->RefH = Data->RefH + 8*((i&1) + (i>>1)*Data->iEdgedWidth);                  Data8->RefP[2] = Data->RefP[2] + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2521                  Data8->RefV = Data->RefV + 8*((i&1) + (i>>1)*Data->iEdgedWidth);                  Data8->RefP[1] = Data->RefP[1] + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2522                  Data8->RefHV = Data->RefHV + 8*((i&1) + (i>>1)*Data->iEdgedWidth);                  Data8->RefP[3] = Data->RefP[3] + 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2523    
2524                  if(Data->qpel) {                  if(Data->qpel) {
2525                          Data8->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x, y, i);                          Data8->predMV = get_qpmv2(pMBs, pParam->mb_width, 0, x, y, i);
# Line 2588  Line 2534 
2534                  get_range(&Data8->min_dx, &Data8->max_dx, &Data8->min_dy, &Data8->max_dy, 2*x + (i&1), 2*y + (i>>1), 8,                  get_range(&Data8->min_dx, &Data8->max_dx, &Data8->min_dy, &Data8->max_dy, 2*x + (i&1), 2*y + (i>>1), 8,
2535                                          pParam->width, pParam->height, Data8->iFcode, Data8->qpel, 0);                                          pParam->width, pParam->height, Data8->iFcode, Data8->qpel, 0);
2536    
2537                  *Data8->iMinSAD += t;                  *Data8->iMinSAD += BITS_MULT*t;
2538    
2539                  Data8->qpel_precision = Data8->qpel;                  Data8->qpel_precision = Data8->qpel;
2540                  // checking the vector which has been found by SAD-based 8x8 search (if it's different than the one found so far)                  // checking the vector which has been found by SAD-based 8x8 search (if it's different than the one found so far)
2541                  if (Data8->qpel) {                  {
2542                          if (!(Data8->currentQMV->x == backup[i+1].x && Data8->currentQMV->y == backup[i+1].y))                          VECTOR *v = Data8->qpel ? Data8->currentQMV : Data8->currentMV;
2543                                  CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8);                          if (!MVequal (*v, backup[i+1]) )
                 } else {  
                         if (!(Data8->currentMV->x == backup[i+1].x && Data8->currentMV->y == backup[i+1].y))  
2544                                  CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8);                                  CheckCandidateBits8(backup[i+1].x, backup[i+1].y, 255, &iDirection, Data8);
2545                  }                  }
2546    
# Line 2615  Line 2559 
2559                                  if (MotionFlags & PMV_EXTSEARCH8 && MotionFlags & EXTSEARCH_BITS)                                  if (MotionFlags & PMV_EXTSEARCH8 && MotionFlags & EXTSEARCH_BITS)
2560                                          SquareSearch(Data8->currentMV->x, Data8->currentMV->x, Data8, 255);                                          SquareSearch(Data8->currentMV->x, Data8->currentMV->x, Data8, 255);
2561    
2562                                  if (MotionFlags & HALFPELREFINE8_BITS) SubpelRefine(Data8);                                  if (MotionFlags & HALFPELREFINE8_BITS)
2563                                            SubpelRefine(Data8);
2564    
2565                                  if(s > *Data8->iMinSAD) { //we have found a better match                                  if(s > *Data8->iMinSAD) { //we have found a better match
2566                                          Data8->currentQMV->x = 2*Data8->currentMV->x;                                          Data8->currentQMV->x = 2*Data8->currentMV->x;
# Line 2629  Line 2574 
2574                          }                          }
2575                          if (MotionFlags & QUARTERPELREFINE8_BITS) SubpelRefine(Data8);                          if (MotionFlags & QUARTERPELREFINE8_BITS) SubpelRefine(Data8);
2576    
2577                  } else // not qpel                  } else { // not qpel
2578                          if (MotionFlags & HALFPELREFINE8_BITS) SubpelRefine(Data8); //halfpel mode, halfpel refinement  
2579                            if (MotionFlags & PMV_EXTSEARCH8 && MotionFlags & EXTSEARCH_BITS) //extsearch
2580                                    SquareSearch(Data8->currentMV->x, Data8->currentMV->x, Data8, 255);
2581    
2582                            if (MotionFlags & HALFPELREFINE8_BITS)
2583                                    SubpelRefine(Data8); //halfpel refinement
2584                    }
2585    
2586                  //checking vector equal to predicion                  //checking vector equal to predicion
2587                  if (i != 0 && MotionFlags & CHECKPREDICTION_BITS) {                  if (i != 0 && MotionFlags & CHECKPREDICTION_BITS) {
2588                          const VECTOR * v = Data->qpel ? Data8->currentQMV : Data8->currentMV;                          const VECTOR * v = Data->qpel ? Data8->currentQMV : Data8->currentMV;
2589                          if (!(Data8->predMV.x == v->x && Data8->predMV.y == v->y))                          if (!MVequal(*v, Data8->predMV))
2590                                  CheckCandidateBits8(Data8->predMV.x, Data8->predMV.y, 255, &iDirection, Data8);                                  CheckCandidateBits8(Data8->predMV.x, Data8->predMV.y, 255, &iDirection, Data8);
2591                  }                  }
2592    
2593                  bits += *Data8->iMinSAD;                  bits += *Data8->iMinSAD;
2594                  if (bits >= Data->iMinSAD[0]) break; // no chances for INTER4V                  if (bits >= Data->iMinSAD[0]) return bits; // no chances for INTER4V
2595    
2596                  // MB structures for INTER4V mode; we have to set them here, we don't have predictor anywhere else                  // MB structures for INTER4V mode; we have to set them here, we don't have predictor anywhere else
2597                  if(Data->qpel) {                  if(Data->qpel) {
# Line 2658  Line 2609 
2609                  pMB->mvs[i] = *Data8->currentMV;                  pMB->mvs[i] = *Data8->currentMV;
2610                  pMB->sad8[i] = 4 * *Data8->iMinSAD;                  pMB->sad8[i] = 4 * *Data8->iMinSAD;
2611                  if (Data8->temp[0]) cbp |= 1 << (5 - i);                  if (Data8->temp[0]) cbp |= 1 << (5 - i);
         }  
2612    
2613          if (bits < *Data->iMinSAD) { // there is still a chance for inter4v mode. let's check chroma          } // /for all luma blocks
2614                  const uint8_t * ptr;  
2615            bits += BITS_MULT*xvid_cbpy_tab[15-(cbp>>2)].len;
2616    
2617            // let's check chroma
2618                  sumx = (sumx >> 3) + roundtab_76[sumx & 0xf];                  sumx = (sumx >> 3) + roundtab_76[sumx & 0xf];
2619                  sumy = (sumy >> 3) + roundtab_76[sumy & 0xf];                  sumy = (sumy >> 3) + roundtab_76[sumy & 0xf];
2620    
2621                  //chroma U                  //chroma U
2622                  ptr = interpolate8x8_switch2(Data->RefQ + 64, Data->RefCU, 0, 0, sumx, sumy, Data->iEdgedWidth/2, Data->rounding);          ptr = interpolate8x8_switch2(Data->RefQ + 64, Data->RefP[4], 0, 0, sumx, sumy, Data->iEdgedWidth/2, Data->rounding);
2623                  transfer_8to16subro(in, Data->CurU, ptr, Data->iEdgedWidth/2);                  transfer_8to16subro(in, Data->CurU, ptr, Data->iEdgedWidth/2);
2624                  fdct(in);          bits += Block_CalcBits(coeff, in, Data->iQuant, Data->quant_type, &cbp, 4);
2625                  if (Data->lambda8 == 0) i = quant_inter(coeff, in, Data->lambda16);  
2626                  else i = quant4_inter(coeff, in, Data->lambda16);          if (bits >= *Data->iMinSAD) return bits;
                 if (i > 0) {  
                         bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);  
                         cbp |= 1 << (5 - 4);  
                 }  
2627    
                 if (bits < *Data->iMinSAD) { // still possible  
2628                          //chroma V                          //chroma V
2629                          ptr = interpolate8x8_switch2(Data->RefQ + 64, Data->RefCV, 0, 0, sumx, sumy, Data->iEdgedWidth/2, Data->rounding);          ptr = interpolate8x8_switch2(Data->RefQ + 64, Data->RefP[5], 0, 0, sumx, sumy, Data->iEdgedWidth/2, Data->rounding);
2630                          transfer_8to16subro(in, Data->CurV, ptr, Data->iEdgedWidth/2);                          transfer_8to16subro(in, Data->CurV, ptr, Data->iEdgedWidth/2);
2631                          fdct(in);          bits += Block_CalcBits(coeff, in, Data->iQuant, Data->quant_type, &cbp, 5);
2632                          if (Data->lambda8 == 0) i = quant_inter(coeff, in, Data->lambda16);  
2633                          else i = quant4_inter(coeff, in, Data->lambda16);          bits += BITS_MULT*mcbpc_inter_tab[(MODE_INTER4V & 7) | ((cbp & 3) << 3)].len;
                         if (i > 0) {  
                                 bits += CodeCoeffInter_CalcBits(coeff, scan_tables[0]);  
                                 cbp |= 1 << (5 - 5);  
                         }  
                         bits += xvid_cbpy_tab[15-(cbp>>2)].len;  
                         bits += mcbpc_inter_tab[(MODE_INTER4V & 7) | ((cbp & 3) << 3)].len;  
                 }  
         }  
2634    
2635          return bits;          return bits;
2636  }  }
2637    
   
2638  static int  static int
2639  CountMBBitsIntra(const SearchData * const Data)  CountMBBitsIntra(const SearchData * const Data)
2640  {  {
2641          int bits = 1; //this one is ac/dc prediction flag. always 1.          int bits = BITS_MULT*1; //this one is ac/dc prediction flag bit
2642          int cbp = 0, i, t, dc = 0, b_dc = 1024;          int cbp = 0, i, dc = 0;
         const uint32_t iQuant = Data->lambda16;  
2643          int16_t *in = Data->dctSpace, * coeff = Data->dctSpace + 64;          int16_t *in = Data->dctSpace, * coeff = Data->dctSpace + 64;
2644    
2645          for(i = 0; i < 4; i++) {          for(i = 0; i < 4; i++) {
                 uint32_t iDcScaler = get_dc_scaler(iQuant, 1);  
   
2646                  int s = 8*((i&1) + (i>>1)*Data->iEdgedWidth);                  int s = 8*((i&1) + (i>>1)*Data->iEdgedWidth);
2647                  transfer_8to16copy(in, Data->Cur + s, Data->iEdgedWidth);                  transfer_8to16copy(in, Data->Cur + s, Data->iEdgedWidth);
2648                  fdct(in);                  bits += Block_CalcBitsIntra(coeff, in, Data->iQuant, Data->quant_type, &cbp, i, &dc);
2649                  b_dc = dc;  
2650                  dc = in[0];                  if (bits >= Data->iMinSAD[0]) return bits;
                 in[0] -= b_dc;  
                 if (Data->lambda8 == 0) quant_intra_c(coeff, in, iQuant, iDcScaler);  
                 else quant4_intra_c(coeff, in, iQuant, iDcScaler);  
   
                 b_dc = dc;  
                 dc = coeff[0];  
                 if (i != 0) coeff[0] -= b_dc;  
   
                 bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcy_tab[coeff[0] + 255].len;;  
                 Data->temp[i] = t;  
                 if (t != 0)  cbp |= 1 << (5 - i);  
                 if (bits >= Data->iMinSAD[0]) break;  
2651          }          }
2652    
2653          if (bits < Data->iMinSAD[0]) { // INTRA still looks good, let's add chroma          bits += BITS_MULT*xvid_cbpy_tab[cbp>>2].len;
2654                  uint32_t iDcScaler = get_dc_scaler(iQuant, 0);  
2655                  //chroma U                  //chroma U
2656                  transfer_8to16copy(in, Data->CurU, Data->iEdgedWidth/2);                  transfer_8to16copy(in, Data->CurU, Data->iEdgedWidth/2);
2657                  fdct(in);          bits += Block_CalcBitsIntra(coeff, in, Data->iQuant, Data->quant_type, &cbp, 4, &dc);
                 in[0] -= 1024;  
                 if (Data->lambda8 == 0) quant_intra(coeff, in, iQuant, iDcScaler);  
                 else quant4_intra(coeff, in, iQuant, iDcScaler);  
2658    
2659                  bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcc_tab[coeff[0] + 255].len;          if (bits >= Data->iMinSAD[0]) return bits;
                 if (t != 0) cbp |= 1 << (5 - 4);  
2660    
                 if (bits < Data->iMinSAD[0]) {  
                         iDcScaler = get_dc_scaler(iQuant, 1);  
2661                          //chroma V                          //chroma V
2662                          transfer_8to16copy(in, Data->CurV, Data->iEdgedWidth/2);                          transfer_8to16copy(in, Data->CurV, Data->iEdgedWidth/2);
2663                          fdct(in);          bits += Block_CalcBitsIntra(coeff, in, Data->iQuant, Data->quant_type, &cbp, 5, &dc);
                         in[0] -= 1024;  
                         if (Data->lambda8 == 0) quant_intra(coeff, in, iQuant, iDcScaler);  
                         else quant4_intra(coeff, in, iQuant, iDcScaler);  
2664    
2665                          bits += t = CodeCoeffIntra_CalcBits(coeff, scan_tables[0]) + dcc_tab[coeff[0] + 255].len;          bits += BITS_MULT*mcbpc_inter_tab[(MODE_INTRA & 7) | ((cbp & 3) << 3)].len;
                         if (t != 0) cbp |= 1 << (5 - 5);  
2666    
                         bits += xvid_cbpy_tab[cbp>>2].len;  
                         bits += mcbpc_inter_tab[(MODE_INTRA & 7) | ((cbp & 3) << 3)].len;  
                 }  
         }  
2667          return bits;          return bits;
2668  }  }

Legend:
Removed from v.973  
changed lines
  Added in v.1072

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