[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 740, Thu Dec 26 12:10:11 2002 UTC revision 767, Wed Jan 8 14:37:52 2003 UTC
# Line 58  Line 58 
58          int xb, yb;          int xb, yb;
59          if (qpel) { x *= 2; y *= 2;}          if (qpel) { x *= 2; y *= 2;}
60          else if (rrv) { x = RRV_MV_SCALEDOWN(x); y = RRV_MV_SCALEDOWN(y); }          else if (rrv) { x = RRV_MV_SCALEDOWN(x); y = RRV_MV_SCALEDOWN(y); }
61          x = pred.x - x;          x -= pred.x;
62          y = pred.y - y;          y -= pred.y;
63    
64          if (x == 0) xb = 1;          if (x) {
         else {  
65                  if (x < 0) x = -x;                  if (x < 0) x = -x;
66                  x += (1 << (iFcode - 1)) - 1;                  x += (1 << (iFcode - 1)) - 1;
67                  x >>= (iFcode - 1);                  x >>= (iFcode - 1);
68                  if (x > 32) x = 32;                  if (x > 32) x = 32;
69                  xb = mvtab[x] + iFcode;                  xb = mvtab[x] + iFcode;
70          }          } else xb = 1;
71    
72          if (y == 0) yb = 1;          if (y) {
         else {  
73                  if (y < 0) y = -y;                  if (y < 0) y = -y;
74                  y += (1 << (iFcode - 1)) - 1;                  y += (1 << (iFcode - 1)) - 1;
75                  y >>= (iFcode - 1);                  y >>= (iFcode - 1);
76                  if (y > 32) y = 32;                  if (y > 32) y = 32;
77                  yb = mvtab[y] + iFcode;                  yb = mvtab[y] + iFcode;
78          }          } else yb = 1;
79          return xb + yb;          return xb + yb;
80  }  }
81    
# Line 85  Line 83 
83  ChromaSAD(int dx, int dy, const SearchData * const data)  ChromaSAD(int dx, int dy, const SearchData * const data)
84  {  {
85          int sad;          int sad;
86          dx = (dx >> 1) + roundtab_79[dx & 0x3];          const uint32_t stride = data->iEdgedWidth/2;
         dy = (dy >> 1) + roundtab_79[dy & 0x3];  
87    
88          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
89            data->temp[5]  = dx; data->temp[6] = dy; // backup
90    
91          switch (((dx & 1) << 1) | (dy & 1))     {          switch (((dx & 1) << 1) | (dy & 1))     {
92                  case 0:                  case 0:
93                          sad = sad8(data->CurU, data->RefCU + (dy/2) * (data->iEdgedWidth/2) + dx/2, data->iEdgedWidth/2);                          dx = dx / 2; dy = dy / 2;
94                          sad += sad8(data->CurV, data->RefCV + (dy/2) * (data->iEdgedWidth/2) + dx/2, data->iEdgedWidth/2);                          sad = sad8(data->CurU, data->RefCU + dy * stride + dx, stride);
95                            sad += sad8(data->CurV, data->RefCV + dy * stride + dx, stride);
96                          break;                          break;
97                  case 1:                  case 1:
98                          dx = dx / 2; dy = (dy - 1) / 2;                          dx = dx / 2; dy = (dy - 1) / 2;
99                          sad = sad8bi(data->CurU, data->RefCU + dy * (data->iEdgedWidth/2) + dx, data->RefCU + (dy+1) * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2);                          sad = sad8bi(data->CurU, data->RefCU + dy * stride + dx, data->RefCU + (dy+1) * stride + dx, stride);
100                          sad += sad8bi(data->CurV, data->RefCV + dy * (data->iEdgedWidth/2) + dx, data->RefCV + (dy+1) * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2);                          sad += sad8bi(data->CurV, data->RefCV + dy * stride + dx, data->RefCV + (dy+1) * stride + dx, stride);
101                          break;                          break;
102                  case 2:                  case 2:
103                          dx = (dx - 1) / 2; dy = dy / 2;                          dx = (dx - 1) / 2; dy = dy / 2;
104                          sad = sad8bi(data->CurU, data->RefCU + dy * (data->iEdgedWidth/2) + dx, data->RefCU + dy * (data->iEdgedWidth/2) + dx+1, data->iEdgedWidth/2);                          sad = sad8bi(data->CurU, data->RefCU + dy * stride + dx, data->RefCU + dy * stride + dx+1, stride);
105                          sad += sad8bi(data->CurV, data->RefCV + dy * (data->iEdgedWidth/2) + dx, data->RefCV + dy * (data->iEdgedWidth/2) + dx+1, data->iEdgedWidth/2);                          sad += sad8bi(data->CurV, data->RefCV + dy * stride + dx, data->RefCV + dy * stride + dx+1, stride);
106                          break;                          break;
107                  default:                  default:
108                          dx = (dx - 1) / 2; dy = (dy - 1) / 2;                          dx = (dx - 1) / 2; dy = (dy - 1) / 2;
109                          interpolate8x8_halfpel_hv(data->RefQ,                          interpolate8x8_halfpel_hv(data->RefQ, data->RefCU + dy * stride + dx, stride, data->rounding);
110                                                                           data->RefCU + dy * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2,                          sad = sad8(data->CurU, data->RefQ, stride);
111                                                                           data->rounding);  
112                          sad = sad8(data->CurU, data->RefQ, data->iEdgedWidth/2);                          interpolate8x8_halfpel_hv(data->RefQ, data->RefCV + dy * stride + dx, stride, data->rounding);
113                          interpolate8x8_halfpel_hv(data->RefQ,                          sad += sad8(data->CurV, data->RefQ, stride);
                                                                          data->RefCV + dy * (data->iEdgedWidth/2) + dx, data->iEdgedWidth/2,  
                                                                          data->rounding);  
                         sad += sad8(data->CurV, data->RefQ, data->iEdgedWidth/2);  
114                          break;                          break;
115          }          }
116          data->temp[5]  = dx; data->temp[6] = dy; data->temp[7] = sad; //backup          data->temp[7] = sad; //backup, part 2
117          return sad;          return sad;
118  }  }
119    
120  static __inline const uint8_t *  static __inline const uint8_t *
121  GetReference(const int x, const int y, const int dir, const SearchData * const data)  GetReferenceB(const int x, const int y, const int dir, const SearchData * const data)
122  {  {
123  //      dir : 0 = forward, 1 = backward  //      dir : 0 = forward, 1 = backward
124          switch ( (dir << 2) | ((x&1)<<1) | (y&1) ) {          switch ( (dir << 2) | ((x&1)<<1) | (y&1) ) {
# Line 137  Line 133 
133          }          }
134  }  }
135    
136    // this is a simpler copy of GetReferenceB, but as it's __inline anyway, we can keep the two separate
137    static __inline const uint8_t *
138    GetReference(const int x, const int y, const SearchData * const data)
139    {
140            switch ( ((x&1)<<1) | (y&1) ) {
141                    case 0 : return data->Ref + x/2 + (y/2)*(data->iEdgedWidth);
142                    case 1 : return data->RefV + x/2 + ((y-1)/2)*(data->iEdgedWidth);
143                    case 2 : return data->RefH + (x-1)/2 + (y/2)*(data->iEdgedWidth);
144                    default : return data->RefHV + (x-1)/2 + ((y-1)/2)*(data->iEdgedWidth);
145            }
146    }
147    
148  static uint8_t *  static uint8_t *
149  Interpolate8x8qpel(const int x, const int y, const int block, const int dir, const SearchData * const data)  Interpolate8x8qpel(const int x, const int y, const int block, const int dir, const SearchData * const data)
150  {  {
# Line 148  Line 156 
156          const int halfpel_y = y/2;          const int halfpel_y = y/2;
157          const uint8_t *ref1, *ref2, *ref3, *ref4;          const uint8_t *ref1, *ref2, *ref3, *ref4;
158    
159          ref1 = GetReference(halfpel_x, halfpel_y, dir, data);          ref1 = GetReferenceB(halfpel_x, halfpel_y, dir, data);
160          ref1 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;          ref1 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;
161          switch( ((x&1)<<1) + (y&1) ) {          switch( ((x&1)<<1) + (y&1) ) {
162          case 0: // pure halfpel position          case 0: // pure halfpel position
# Line 156  Line 164 
164                  break;                  break;
165    
166          case 1: // x halfpel, y qpel - top or bottom during qpel refinement          case 1: // x halfpel, y qpel - top or bottom during qpel refinement
167                  ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data);                  ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data);
168                  ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;                  ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;
169                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);
170                  break;                  break;
171    
172          case 2: // x qpel, y halfpel - left or right during qpel refinement          case 2: // x qpel, y halfpel - left or right during qpel refinement
173                  ref2 = GetReference(x - halfpel_x, halfpel_y, dir, data);                  ref2 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data);
174                  ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;                  ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;
175                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);
176                  break;                  break;
177    
178          default: // x and y in qpel resolution - the "corners" (top left/right and          default: // x and y in qpel resolution - the "corners" (top left/right and
179                           // bottom left/right) during qpel refinement                           // bottom left/right) during qpel refinement
180                  ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data);                  ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data);
181                  ref3 = GetReference(x - halfpel_x, halfpel_y, dir, data);                  ref3 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data);
182                  ref4 = GetReference(x - halfpel_x, y - halfpel_y, dir, data);                  ref4 = GetReferenceB(x - halfpel_x, y - halfpel_y, dir, data);
183                  ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;                  ref2 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;
184                  ref3 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;                  ref3 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;
185                  ref4 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;                  ref4 += 8 * (block&1) + 8 * (block>>1) * iEdgedWidth;
# Line 192  Line 200 
200          const int halfpel_y = y/2;          const int halfpel_y = y/2;
201          const uint8_t *ref1, *ref2, *ref3, *ref4;          const uint8_t *ref1, *ref2, *ref3, *ref4;
202    
203          ref1 = GetReference(halfpel_x, halfpel_y, dir, data);          ref1 = GetReferenceB(halfpel_x, halfpel_y, dir, data);
204          switch( ((x&1)<<1) + (y&1) ) {          switch( ((x&1)<<1) + (y&1) ) {
205          case 0: // pure halfpel position          case 0: // pure halfpel position
206                  return (uint8_t *) ref1;                  return (uint8_t *) ref1;
207          case 1: // x halfpel, y qpel - top or bottom during qpel refinement          case 1: // x halfpel, y qpel - top or bottom during qpel refinement
208                  ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data);                  ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data);
209                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);
210                  interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8);
211                  interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8);
# Line 205  Line 213 
213                  break;                  break;
214    
215          case 2: // x qpel, y halfpel - left or right during qpel refinement          case 2: // x qpel, y halfpel - left or right during qpel refinement
216                  ref2 = GetReference(x - halfpel_x, halfpel_y, dir, data);                  ref2 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data);
217                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference, ref1, ref2, iEdgedWidth, rounding, 8);
218                  interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference+8, ref1+8, ref2+8, iEdgedWidth, rounding, 8);
219                  interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8);                  interpolate8x8_avg2(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, iEdgedWidth, rounding, 8);
# Line 214  Line 222 
222    
223          default: // x and y in qpel resolution - the "corners" (top left/right and          default: // x and y in qpel resolution - the "corners" (top left/right and
224                           // bottom left/right) during qpel refinement                           // bottom left/right) during qpel refinement
225                  ref2 = GetReference(halfpel_x, y - halfpel_y, dir, data);                  ref2 = GetReferenceB(halfpel_x, y - halfpel_y, dir, data);
226                  ref3 = GetReference(x - halfpel_x, halfpel_y, dir, data);                  ref3 = GetReferenceB(x - halfpel_x, halfpel_y, dir, data);
227                  ref4 = GetReference(x - halfpel_x, y - halfpel_y, dir, data);                  ref4 = GetReferenceB(x - halfpel_x, y - halfpel_y, dir, data);
228                  interpolate8x8_avg4(Reference, ref1, ref2, ref3, ref4, iEdgedWidth, rounding);                  interpolate8x8_avg4(Reference, ref1, ref2, ref3, ref4, iEdgedWidth, rounding);
229                  interpolate8x8_avg4(Reference+8, ref1+8, ref2+8, ref3+8, ref4+8, iEdgedWidth, rounding);                  interpolate8x8_avg4(Reference+8, ref1+8, ref2+8, ref3+8, ref4+8, iEdgedWidth, rounding);
230                  interpolate8x8_avg4(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, ref3+8*iEdgedWidth, ref4+8*iEdgedWidth, iEdgedWidth, rounding);                  interpolate8x8_avg4(Reference+8*iEdgedWidth, ref1+8*iEdgedWidth, ref2+8*iEdgedWidth, ref3+8*iEdgedWidth, ref4+8*iEdgedWidth, iEdgedWidth, rounding);
# Line 243  Line 251 
251                  xc = x/2; yc = y/2; //for chroma sad                  xc = x/2; yc = y/2; //for chroma sad
252                  current = data->currentQMV;                  current = data->currentQMV;
253          } else {          } else {
254                  Reference = GetReference(x, y, 0, data);                  Reference = GetReference(x, y, data);
255                  current = data->currentMV;                  current = data->currentMV;
256                  xc = x; yc = y;                  xc = x; yc = y;
257          }          }
# Line 254  Line 262 
262          data->temp[0] += (data->lambda16 * t * data->temp[0])/1000;          data->temp[0] += (data->lambda16 * t * data->temp[0])/1000;
263          data->temp[1] += (data->lambda8 * t * (data->temp[1] + NEIGH_8X8_BIAS))/100;          data->temp[1] += (data->lambda8 * t * (data->temp[1] + NEIGH_8X8_BIAS))/100;
264    
265          if (data->chroma) data->temp[0] += ChromaSAD(xc, yc, data);          if (data->chroma) data->temp[0] += ChromaSAD((xc >> 1) + roundtab_79[xc & 0x3],
266                                                                                                            (yc >> 1) + roundtab_79[yc & 0x3], data);
267    
268          if (data->temp[0] < data->iMinSAD[0]) {          if (data->temp[0] < data->iMinSAD[0]) {
269                  data->iMinSAD[0] = data->temp[0];                  data->iMinSAD[0] = data->temp[0];
# Line 282  Line 291 
291                  ( x > data->max_dx) || ( x < data->min_dx)                  ( x > data->max_dx) || ( x < data->min_dx)
292                  || ( y > data->max_dy) || (y < data->min_dy)) return;                  || ( y > data->max_dy) || (y < data->min_dy)) return;
293    
294          Reference = GetReference(x, y, 0, data);          Reference = GetReference(x, y, data);
295          t = d_mv_bits(x, y, data->predMV, data->iFcode, 0, 1);          t = d_mv_bits(x, y, data->predMV, data->iFcode, 0, 1);
296    
297          data->temp[0] = sad32v_c(data->Cur, Reference, data->iEdgedWidth, data->temp + 1);          data->temp[0] = sad32v_c(data->Cur, Reference, data->iEdgedWidth, data->temp + 1);
# Line 323  Line 332 
332                  Reference = Interpolate16x16qpel(x, y, 0, data);                  Reference = Interpolate16x16qpel(x, y, 0, data);
333                  current = data->currentQMV;                  current = data->currentQMV;
334          } else {          } else {
335                  Reference = GetReference(x, y, 0, data);                  Reference = GetReference(x, y, data);
336                  current = data->currentMV;                  current = data->currentMV;
337          }          }
338          t = d_mv_bits(x, y, data->predMV, data->iFcode,          t = d_mv_bits(x, y, data->predMV, data->iFcode,
339                                          data->qpel && !data->qpel_precision && !data->rrv, data->rrv);                                          data->qpel && !data->qpel_precision, data->rrv);
340    
341          sad = sad16(data->Cur, Reference, data->iEdgedWidth, 256*4096);          sad = sad16(data->Cur, Reference, data->iEdgedWidth, 256*4096);
342          sad += (data->lambda16 * t * sad)/1000;          sad += (data->lambda16 * t * sad)/1000;
# Line 363  Line 372 
372    
373  }  }
374    
   
375  static void  static void
376  CheckCandidateInt(const int xf, const int yf, const int Direction, int * const dir, const SearchData * const data)  CheckCandidateInt(const int xf, const int yf, const int Direction, int * const dir, const SearchData * const data)
377  {  {
# Line 381  Line 389 
389                  current = data->currentQMV;                  current = data->currentQMV;
390                  ReferenceB = Interpolate16x16qpel(xb, yb, 1, data);                  ReferenceB = Interpolate16x16qpel(xb, yb, 1, data);
391          } else {          } else {
392                  ReferenceF = GetReference(xf, yf, 0, data);                  ReferenceF = GetReference(xf, yf, data);
393                  xb = data->currentMV[1].x; yb = data->currentMV[1].y;                  xb = data->currentMV[1].x; yb = data->currentMV[1].y;
394                  ReferenceB = GetReference(xb, yb, 1, data);                  ReferenceB = GetReferenceB(xb, yb, 1, data);
395                  current = data->currentMV;                  current = data->currentMV;
396          }          }
397    
# Line 500  Line 508 
508                  || ( y > data->max_dy) || (y < data->min_dy)) return;                  || ( y > data->max_dy) || (y < data->min_dy)) return;
509    
510          if (data->qpel) Reference = Interpolate16x16qpel(x, y, 0, data);          if (data->qpel) Reference = Interpolate16x16qpel(x, y, 0, data);
511          else Reference =  GetReference(x, y, 0, data);          else Reference =  GetReference(x, y, data);
512    
513          sad = sad8(data->Cur, Reference, data->iEdgedWidth);          sad = sad8(data->Cur, Reference, data->iEdgedWidth);
514          t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel && !data->qpel_precision, 0);          t = d_mv_bits(x, y, data->predMV, data->iFcode, data->qpel && !data->qpel_precision, 0);
# Line 673  Line 681 
681                  backupMV = *(data->currentQMV);                  backupMV = *(data->currentQMV);
682          else backupMV = *(data->currentMV);          else backupMV = *(data->currentMV);
683    
684          CHECK_CANDIDATE(backupMV.x - 1, backupMV.y - 1, 0);          CHECK_CANDIDATE(backupMV.x, backupMV.y - 1, 0);
685          CHECK_CANDIDATE(backupMV.x + 1, backupMV.y - 1, 0);          CHECK_CANDIDATE(backupMV.x + 1, backupMV.y - 1, 0);
         CHECK_CANDIDATE(backupMV.x - 1, backupMV.y + 1, 0);  
         CHECK_CANDIDATE(backupMV.x + 1, backupMV.y + 1, 0);  
   
         CHECK_CANDIDATE(backupMV.x - 1, backupMV.y, 0);  
686          CHECK_CANDIDATE(backupMV.x + 1, backupMV.y, 0);          CHECK_CANDIDATE(backupMV.x + 1, backupMV.y, 0);
687            CHECK_CANDIDATE(backupMV.x + 1, backupMV.y + 1, 0);
688          CHECK_CANDIDATE(backupMV.x, backupMV.y + 1, 0);          CHECK_CANDIDATE(backupMV.x, backupMV.y + 1, 0);
689          CHECK_CANDIDATE(backupMV.x, backupMV.y - 1, 0);          CHECK_CANDIDATE(backupMV.x - 1, backupMV.y + 1, 0);
690            CHECK_CANDIDATE(backupMV.x - 1, backupMV.y, 0);
691            CHECK_CANDIDATE(backupMV.x - 1, backupMV.y - 1, 0);
692  }  }
693    
694  static __inline int  static __inline int
# Line 747  Line 753 
753          uint32_t x, y;          uint32_t x, y;
754          uint32_t iIntra = 0;          uint32_t iIntra = 0;
755          int32_t InterBias, quant = current->quant, sad00;          int32_t InterBias, quant = current->quant, sad00;
         uint8_t *qimage;  
756    
757          // some pre-initialized thingies for SearchP          // some pre-initialized thingies for SearchP
758          int32_t temp[8];          int32_t temp[8];
# Line 773  Line 778 
778                  Data.qpel = Data.chroma = 0;                  Data.qpel = Data.chroma = 0;
779          }          }
780    
781          if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL)          Data.RefQ = pRefV->u; // a good place, also used in MC (for similar purpose)
                 return 1; // allocate some mem for qpel interpolated blocks  
                                   // somehow this is dirty since I think we shouldn't use malloc outside  
                                   // encoder_create() - so please fix me!  
         Data.RefQ = qimage;  
782          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
783    
784          for (y = 0; y < mb_height; y++) {          for (y = 0; y < mb_height; y++) {
# Line 869  Line 870 
870                                                    pParam->edged_width);                                                    pParam->edged_width);
871    
872                                          if (deviation < (pMB->sad16 - InterBias)) {                                          if (deviation < (pMB->sad16 - InterBias)) {
873                                          if (++iIntra >= iLimit) { free(qimage); return 1; }                                          if (++iIntra >= iLimit) return 1;
874                                          pMB->mode = MODE_INTRA;                                          pMB->mode = MODE_INTRA;
875                                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] =                                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] =
876                                                          pMB->mvs[3] = zeroMV;                                                          pMB->mvs[3] = zeroMV;
# Line 881  Line 882 
882                          }                          }
883                  }                  }
884          }          }
         free(qimage);  
885    
886          if (current->coding_type == S_VOP)      /* first GMC step only for S(GMC)-VOPs */          if (current->coding_type == S_VOP)      /* first GMC step only for S(GMC)-VOPs */
887                  current->GMC_MV = GlobalMotionEst( pMBs, pParam, current->fcode );                  current->GMC_MV = GlobalMotionEst( pMBs, pParam, current->fcode );
# Line 932  Line 932 
932      else pmv[4].x = pmv[4].y = 0;      else pmv[4].x = pmv[4].y = 0;
933    
934          // [1] median prediction          // [1] median prediction
935          if (rrv) { //median is in halfzero-precision          pmv[1].x = EVEN(pmv[0].x); pmv[1].y = EVEN(pmv[0].y);
                 pmv[1].x = RRV_MV_SCALEUP(pmv[0].x);  
                 pmv[1].y = RRV_MV_SCALEUP(pmv[0].y);  
         } else { pmv[1].x = EVEN(pmv[0].x); pmv[1].y = EVEN(pmv[0].y); }  
936    
937          pmv[0].x = pmv[0].y = 0; // [0] is zero; not used in the loop (checked before) but needed here for make_mask          pmv[0].x = pmv[0].y = 0; // [0] is zero; not used in the loop (checked before) but needed here for make_mask
938    
# Line 950  Line 947 
947          if (rrv) {          if (rrv) {
948                  int i;                  int i;
949                  for (i = 0; i < 7; i++) {                  for (i = 0; i < 7; i++) {
950                          pmv[i].x = RRV_MV_SCALEDOWN(pmv[i].x);                          pmv[i].x = RRV_MV_SCALEUP(pmv[i].x); // halfzero->halfpel
951                          pmv[i].x = RRV_MV_SCALEUP(pmv[i].x); // a trick                          pmv[i].y = RRV_MV_SCALEUP(pmv[i].y);
952                  }                  }
953          }          }
954  }  }
# Line 1093  Line 1090 
1090                  Data->currentQMV[i].y = 2 * Data->currentMV[i].y;                  Data->currentQMV[i].y = 2 * Data->currentMV[i].y;
1091          }          }
1092    
1093          if((!Data->rrv) && (pParam->m_quarterpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) {          if((Data->qpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) {
1094    
1095                  Data->qpel_precision = 1;                  Data->qpel_precision = 1;
1096                  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 1117  Line 1114 
1114                  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);
1115    
1116                  if (Data->chroma) {                  if (Data->chroma) {
1117                          int sumx, sumy, dx, dy;                          int sumx, sumy;
1118    
1119                          if(pParam->m_quarterpel) {                          if(pParam->m_quarterpel) {
1120                                  sumx= pMB->qmvs[0].x/2 + pMB->qmvs[1].x/2 + pMB->qmvs[2].x/2 + pMB->qmvs[3].x/2;                                  sumx= pMB->qmvs[0].x/2 + pMB->qmvs[1].x/2 + pMB->qmvs[2].x/2 + pMB->qmvs[3].x/2;
# Line 1126  Line 1123 
1123                                  sumx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;                                  sumx = pMB->mvs[0].x + pMB->mvs[1].x + pMB->mvs[2].x + pMB->mvs[3].x;
1124                                  sumy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;                                  sumy = pMB->mvs[0].y + pMB->mvs[1].y + pMB->mvs[2].y + pMB->mvs[3].y;
1125                          }                          }
                         dx = (sumx >> 3) + roundtab_76[sumx & 0xf];  
                         dy = (sumy >> 3) + roundtab_76[sumy & 0xf];  
1126    
1127                          Data->iMinSAD[1] += ChromaSAD(dx, dy, Data);                          Data->iMinSAD[1] += ChromaSAD(  (sumx >> 3) + roundtab_76[sumx & 0xf],
1128                                                                                            (sumy >> 3) + roundtab_76[sumy & 0xf], Data);
1129                  }                  }
1130          }          }
1131    
# Line 1240  Line 1236 
1236                          }                          }
1237                  }                  }
1238    
1239                  if(!Data->rrv && Data->qpel) {                  if(Data->qpel) {
1240                          if((!(Data->currentQMV->x & 1)) && (!(Data->currentQMV->y & 1)) &&                          if((!(Data->currentQMV->x & 1)) && (!(Data->currentQMV->y & 1)) &&
1241                                  (MotionFlags & PMV_QUARTERPELREFINE8)) {                                  (MotionFlags & PMV_QUARTERPELREFINE8)) {
1242                          Data->qpel_precision = 1;                          Data->qpel_precision = 1;
# Line 1311  Line 1307 
1307    
1308          if ((x != 0)&&(y != 0)) {          if ((x != 0)&&(y != 0)) {
1309                  pmv[6] = ChoosePred(pMB-1-iWcount, mode_curr);                  pmv[6] = ChoosePred(pMB-1-iWcount, mode_curr);
1310                  pmv[6].x = EVEN(pmv[5].x); pmv[5].y = EVEN(pmv[5].y);                  pmv[6].x = EVEN(pmv[6].x); pmv[6].y = EVEN(pmv[6].y);
1311          } else pmv[6].x = pmv[6].y = 0;          } else pmv[6].x = pmv[6].y = 0;
1312    
1313  // more?  // more?
# Line 1419  Line 1415 
1415                            const IMAGE * const f_Ref,                            const IMAGE * const f_Ref,
1416                            const IMAGE * const b_Ref,                            const IMAGE * const b_Ref,
1417                            MACROBLOCK * const pMB,                            MACROBLOCK * const pMB,
                           const uint32_t quant,  
1418                            const uint32_t x, const uint32_t y,                            const uint32_t x, const uint32_t y,
1419                            const SearchData * const Data)                            const SearchData * const Data)
1420  {  {
1421          int dx, dy, b_dx, b_dy;          int dx = 0, dy = 0, b_dx = 0, b_dy = 0;
1422          uint32_t sum;          uint32_t sum;
1423            const int div = 1 + Data->qpel;
1424            int k;
1425            const uint32_t quant = pMB->quant;
1426  //this is not full chroma compensation, only it's fullpel approximation. should work though  //this is not full chroma compensation, only it's fullpel approximation. should work though
         if (Data->qpel) {  
                 dy = Data->directmvF[0].y/2 + Data->directmvF[1].y/2 +  
                                 Data->directmvF[2].y/2 + Data->directmvF[3].y/2;  
   
                 dx = Data->directmvF[0].x/2 + Data->directmvF[1].x/2 +  
                                 Data->directmvF[2].x/2 + Data->directmvF[3].x/2;  
   
                 b_dy = Data->directmvB[0].y/2 + Data->directmvB[1].y/2 +  
                                 Data->directmvB[2].y/2 + Data->directmvB[3].y/2;  
   
                 b_dx = Data->directmvB[0].x/2 + Data->directmvB[1].x/2 +  
                                 Data->directmvB[2].x/2 + Data->directmvB[3].x/2;  
1427    
1428          } else {          for (k = 0; k < 4; k++) {
1429                  dy = Data->directmvF[0].y + Data->directmvF[1].y +                  dy += Data->directmvF[k].y / div;
1430                                  Data->directmvF[2].y + Data->directmvF[3].y;                  dx += Data->directmvF[0].x / div;
1431                    b_dy += Data->directmvB[0].y / div;
1432                  dx = Data->directmvF[0].x + Data->directmvF[1].x +                  b_dx += Data->directmvB[0].x / div;
                                 Data->directmvF[2].x + Data->directmvF[3].x;  
   
                 b_dy = Data->directmvB[0].y + Data->directmvB[1].y +  
                                 Data->directmvB[2].y + Data->directmvB[3].y;  
   
                 b_dx = Data->directmvB[0].x + Data->directmvB[1].x +  
                                 Data->directmvB[2].x + Data->directmvB[3].x;  
1433          }          }
1434    
   
1435          dy = (dy >> 3) + roundtab_76[dy & 0xf];          dy = (dy >> 3) + roundtab_76[dy & 0xf];
1436          dx = (dx >> 3) + roundtab_76[dx & 0xf];          dx = (dx >> 3) + roundtab_76[dx & 0xf];
1437          b_dy = (b_dy >> 3) + roundtab_76[b_dy & 0xf];          b_dy = (b_dy >> 3) + roundtab_76[b_dy & 0xf];
# Line 1463  Line 1441 
1441                                          f_Ref->u + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2,                                          f_Ref->u + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2,
1442                                          b_Ref->u + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2,                                          b_Ref->u + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2,
1443                                          Data->iEdgedWidth/2);                                          Data->iEdgedWidth/2);
1444    
1445            if (sum >= 2 * MAX_CHROMA_SAD_FOR_SKIP * quant) return; //no skip
1446    
1447          sum += sad8bi(pCur->v + 8*x + 8*y*(Data->iEdgedWidth/2),          sum += sad8bi(pCur->v + 8*x + 8*y*(Data->iEdgedWidth/2),
1448                                          f_Ref->v + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2,                                          f_Ref->v + (y*8 + dy/2) * (Data->iEdgedWidth/2) + x*8 + dx/2,
1449                                          b_Ref->v + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2,                                          b_Ref->v + (y*8 + b_dy/2) * (Data->iEdgedWidth/2) + x*8 + b_dx/2,
# Line 1552  Line 1533 
1533    
1534  // initial (fast) skip decision  // initial (fast) skip decision
1535          if (*Data->iMinSAD < pMB->quant * INITIAL_SKIP_THRESH*2) {          if (*Data->iMinSAD < pMB->quant * INITIAL_SKIP_THRESH*2) {
1536                  SkipDecisionB(pCur, f_Ref, b_Ref, pMB, x, y, Data->chroma, Data); //possible skip - checking chroma                  SkipDecisionB(pCur, f_Ref, b_Ref, pMB, x, y, Data); //possible skip - checking chroma
1537                  if (pMB->mode == MODE_DIRECT_NONE_MV) return *Data->iMinSAD; // skip.                  if (pMB->mode == MODE_DIRECT_NONE_MV) return *Data->iMinSAD; // skip.
1538          }          }
1539    
# Line 1571  Line 1552 
1552    
1553          *best_sad = *Data->iMinSAD;          *best_sad = *Data->iMinSAD;
1554    
1555          if (b_mb->mode == MODE_INTER4V) pMB->mode = MODE_DIRECT;          if (b_mb->mode == MODE_INTER4V || Data->qpel) pMB->mode = MODE_DIRECT;
1556          else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation          else pMB->mode = MODE_DIRECT_NO4V; //for faster compensation
1557    
1558          pMB->pmvs[3] = *Data->currentMV;          pMB->pmvs[3] = *Data->currentMV;
# Line 1755  Line 1736 
1736    
1737          const int32_t TRB = time_pp - time_bp;          const int32_t TRB = time_pp - time_bp;
1738          const int32_t TRD = time_pp;          const int32_t TRD = time_pp;
         uint8_t * qimage;  
1739    
1740  // some pre-inintialized data for the rest of the search  // some pre-inintialized data for the rest of the search
1741    
# Line 1772  Line 1752 
1752          Data.qpel = pParam->m_quarterpel;          Data.qpel = pParam->m_quarterpel;
1753          Data.rounding = 0;          Data.rounding = 0;
1754    
1755          if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL)          Data.RefQ = f_refV->u; // a good place, also used in MC (for similar purpose)
                 return; // allocate some mem for qpel interpolated blocks  
                                   // somehow this is dirty since I think we shouldn't use malloc outside  
                                   // encoder_create() - so please fix me!  
         Data.RefQ = qimage;  
   
1756          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
1757          for (j = 0; j < pParam->mb_height; j++) {          for (j = 0; j < pParam->mb_height; j++) {
1758    
# Line 1843  Line 1818 
1818  // final skip decision  // final skip decision
1819                          if ( (skip_sad < frame->quant * MAX_SAD00_FOR_SKIP*2)                          if ( (skip_sad < frame->quant * MAX_SAD00_FOR_SKIP*2)
1820                                          && ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) )                                          && ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) )
1821                                  SkipDecisionB(&frame->image, f_ref, b_ref, pMB,frame->quant, i, j, &Data);                                  SkipDecisionB(&frame->image, f_ref, b_ref, pMB, i, j, &Data);
1822    
1823                          switch (pMB->mode) {                          switch (pMB->mode) {
1824                                  case MODE_FORWARD:                                  case MODE_FORWARD:
# Line 1874  Line 1849 
1849                          }                          }
1850                  }                  }
1851          }          }
         free(qimage);  
1852  }  }
1853    
1854  static __inline void  static __inline void
# Line 2072  Line 2046 
2046                  max_x = gmc.x + step;                  max_x = gmc.x + step;
2047                  min_y = gmc.y - step;                  min_y = gmc.y - step;
2048                  max_y = gmc.y + step;                  max_y = gmc.y + step;
   
2049          }          }
2050    
2051          if (bestcount < (pParam->mb_height-2)*(pParam->mb_width-2)/10)          if (bestcount < (pParam->mb_height-2)*(pParam->mb_width-2)/10)
2052                  gmc.x = gmc.y = 0; //no camara pan, no GMC                  gmc.x = gmc.y = 0; //no camara pan, no GMC
2053    
2054  // step2: let's refine camera panning using gradiend-descent approach.  // step2: let's refine camera panning using gradiend-descent approach
2055  // TODO: more warping points may be evaluated here (like in interpolate mode search - two vectors in one diamond)  // TODO: more warping points may be evaluated here (like in interpolate mode search - two vectors in one diamond)
2056          bestcount = 0;          bestcount = 0;
2057          CheckGMC(gmc.x, gmc.y, 255, &iDirection, pMBs, &bestcount, &gmc, pParam);          CheckGMC(gmc.x, gmc.y, 255, &iDirection, pMBs, &bestcount, &gmc, pParam);

Legend:
Removed from v.740  
changed lines
  Added in v.767

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