[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 96, Mon Apr 1 22:47:58 2002 UTC revision 167, Tue May 7 20:03:18 2002 UTC
# Line 2  Line 2 
2   *   *
3   *  Modifications:   *  Modifications:
4   *   *
5     *      01.05.2002      updated MotionEstimationBVOP
6     *      25.04.2002 partial prevMB conversion
7     *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>
8     *  14.04.2002 added MotionEstimationBVOP()
9   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between
10   *             EPZS and EPZS^2   *             EPZS and EPZS^2
11   *  08.02.2002 split up PMVfast into three routines: PMVFast, PMVFast_MainLoop   *  08.02.2002 split up PMVfast into three routines: PMVFast, PMVFast_MainLoop
# Line 40  Line 44 
44  #include "../prediction/mbprediction.h"  #include "../prediction/mbprediction.h"
45  #include "../global.h"  #include "../global.h"
46  #include "../utils/timer.h"  #include "../utils/timer.h"
47    #include "motion.h"
48  #include "sad.h"  #include "sad.h"
49    
50  // very large value  // very large value
# Line 52  Line 57 
57  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
58  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
59  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
60    #define MV8_00_BIAS     (0)
61    
62  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
63  #define INTER_BIAS      512  #define INTER_BIAS      512
# Line 68  Line 74 
74  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
75    
76    
 #define MIN(X, Y) ((X)<(Y)?(X):(Y))  
 #define MAX(X, Y) ((X)>(Y)?(X):(Y))  
 #define ABS(X)    (((X)>0)?(X):-(X))  
 #define SIGN(X)   (((X)>0)?1:-1)  
   
77  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
78                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
79                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 81  Line 82 
82                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
83                                          const int x, const int y,                                          const int x, const int y,
84                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
85                                            const uint32_t iQuant,
86                                            const uint32_t iFcode,
87                                          const MBParam * const pParam,                                          const MBParam * const pParam,
88                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
89                                            const MACROBLOCK * const prevMBs,
90                                          VECTOR * const currMV,                                          VECTOR * const currMV,
91                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
92    
# Line 94  Line 98 
98                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
99                                          const int x, const int y,                                          const int x, const int y,
100                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
101                                            const uint32_t iQuant,
102                                            const uint32_t iFcode,
103                                          const MBParam * const pParam,                                          const MBParam * const pParam,
104                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
105                                            const MACROBLOCK * const prevMBs,
106                                          VECTOR * const currMV,                                          VECTOR * const currMV,
107                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
108    
# Line 107  Line 114 
114                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
115                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
116                                          const int x, const int y,                                          const int x, const int y,
117                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
118                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
119                                            const uint32_t iQuant,
120                                            const uint32_t iFcode,
121                                          const MBParam * const pParam,                                          const MBParam * const pParam,
122                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
123                                            const MACROBLOCK * const prevMBs,
124                                          VECTOR * const currMV,                                          VECTOR * const currMV,
125                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
126    
# Line 121  Line 131 
131                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
132                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
133                                          const int x, const int y,                                          const int x, const int y,
134                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
135                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
136                                            const uint32_t iQuant,
137                                            const uint32_t iFcode,
138                                          const MBParam * const pParam,                                          const MBParam * const pParam,
139                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
140                                            const MACROBLOCK * const prevMBs,
141                                          VECTOR * const currMV,                                          VECTOR * const currMV,
142                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
143    
# Line 172  Line 185 
185    
186  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
187    
188    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
189            {     0    ,(int)(1.00235+0.5), (int)(1.15582+0.5), (int)(1.31976+0.5), (int)(1.49591+0.5), (int)(1.68601+0.5),
190            (int)(1.89187+0.5), (int)(2.11542+0.5), (int)(2.35878+0.5), (int)(2.62429+0.5), (int)(2.91455+0.5),
191            (int)(3.23253+0.5), (int)(3.58158+0.5), (int)(3.96555+0.5), (int)(4.38887+0.5), (int)(4.85673+0.5),
192            (int)(5.37519+0.5), (int)(5.95144+0.5), (int)(6.59408+0.5), (int)(7.31349+0.5), (int)(8.12242+0.5),
193            (int)(9.03669+0.5), (int)(10.0763+0.5), (int)(11.2669+0.5), (int)(12.6426+0.5), (int)(14.2493+0.5),
194            (int)(16.1512+0.5), (int)(18.442+0.5),  (int)(21.2656+0.5), (int)(24.8580+0.5), (int)(29.6436+0.5),
195            (int)(36.4949+0.5)      };
196    
197    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
198    
199    
200    
201  // mv.length table  // mv.length table
202  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
203      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 207  Line 233 
233  }  }
234    
235    
236  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode)  static __inline uint32_t calc_delta_16(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
237  {  {
238          return NEIGH_TEND_16X16 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));          return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
239  }  }
240    
241  static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode)  static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
242    
243  {  {
244      return NEIGH_TEND_8X8 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));      return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
245  }  }
246    
247    
248    
249    
 /* calculate the min/max range (in halfpixels)  
         relative to the _MACROBLOCK_ position  
 */  
   
 static void __inline get_range(  
         int32_t * const min_dx, int32_t * const max_dx,  
         int32_t * const min_dy, int32_t * const max_dy,  
         const uint32_t x, const uint32_t y,  
         const uint32_t block_sz,                                        // block dimension, 8 or 16  
         const uint32_t width, const uint32_t height,  
         const uint32_t fcode)  
 {  
   
         const int search_range = 32 << (fcode - 1);  
         const int high = search_range - 1;  
         const int low = -search_range;  
   
         // convert full-pixel measurements to half pixel  
         const int hp_width = 2 * width;  
         const int hp_height = 2 * height;  
         const int hp_edge = 2 * block_sz;  
         const int hp_x = 2 * (x) * block_sz;            // we need _right end_ of block, not x-coordinate  
         const int hp_y = 2 * (y) * block_sz;            // same for _bottom end_  
   
         *max_dx = MIN(high,     hp_width - hp_x);  
         *max_dy = MIN(high,     hp_height - hp_y);  
         *min_dx = MAX(low,      -(hp_edge + hp_x));  
         *min_dy = MAX(low,      -(hp_edge + hp_y));  
   
 }  
   
   
 /*  
  * getref: calculate reference image pointer  
  * the decision to use interpolation h/v/hv or the normal image is  
  * based on dx & dy.  
  */  
   
 static __inline const uint8_t * get_ref(  
         const uint8_t * const refn,  
         const uint8_t * const refh,  
         const uint8_t * const refv,  
         const uint8_t * const refhv,  
         const uint32_t x, const uint32_t y,  
         const uint32_t block,                                   // block dimension, 8 or 16  
         const int32_t dx, const int32_t dy,  
         const uint32_t stride)  
 {  
   
         switch ( ((dx&1)<<1) + (dy&1) )         // ((dx%2)?2:0)+((dy%2)?1:0)  
         {  
         case 0  : return refn + (x*block+dx/2) + (y*block+dy/2)*stride;  
         case 1  : return refv + (x*block+dx/2) + (y*block+(dy-1)/2)*stride;  
         case 2  : return refh + (x*block+(dx-1)/2) + (y*block+dy/2)*stride;  
         default :  
         case 3  : return refhv + (x*block+(dx-1)/2) + (y*block+(dy-1)/2)*stride;  
         }  
   
 }  
   
   
 /* This is somehow a copy of get_ref, but with MV instead of X,Y */  
   
 static __inline const uint8_t * get_ref_mv(  
         const uint8_t * const refn,  
         const uint8_t * const refh,  
         const uint8_t * const refv,  
         const uint8_t * const refhv,  
         const uint32_t x, const uint32_t y,  
         const uint32_t block,                   // block dimension, 8 or 16  
         const VECTOR* mv,       // measured in half-pel!  
         const uint32_t stride)  
 {  
   
         switch ( (((mv->x)&1)<<1) + ((mv->y)&1) )  
         {  
         case 0  : return refn + (x*block+(mv->x)/2) + (y*block+(mv->y)/2)*stride;  
         case 1  : return refv + (x*block+(mv->x)/2) + (y*block+((mv->y)-1)/2)*stride;  
         case 2  : return refh + (x*block+((mv->x)-1)/2) + (y*block+(mv->y)/2)*stride;  
         default :  
         case 3  : return refhv + (x*block+((mv->x)-1)/2) + (y*block+((mv->y)-1)/2)*stride;  
         }  
   
 }  
250    
251  #ifndef SEARCH16  #ifndef SEARCH16
252  #define SEARCH16        PMVfastSearch16  #define SEARCH16        PMVfastSearch16
# Line 318  Line 260 
260  #endif  #endif
261    
262  bool MotionEstimation(  bool MotionEstimation(
         MACROBLOCK * const pMBs,  
263          MBParam * const pParam,          MBParam * const pParam,
264          const IMAGE * const pRef,          FRAMEINFO * const current,
265            FRAMEINFO * const reference,
266          const IMAGE * const pRefH,          const IMAGE * const pRefH,
267          const IMAGE * const pRefV,          const IMAGE * const pRefV,
268          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
269          const uint32_t iLimit)          const uint32_t iLimit)
270    
271  {  {
272          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
273          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
274            MACROBLOCK * pMBs = current->mbs;
275            IMAGE * pCurrent = &current->image;
276    
277            MACROBLOCK * prevMBs = reference->mbs;  // previous frame
278            IMAGE * pRef = &reference->image;
279    
280    
281          uint32_t i, j, iIntra = 0;          uint32_t i, j, iIntra = 0;
282    
# Line 340  Line 287 
287          int32_t sad16;          int32_t sad16;
288          int32_t deviation;          int32_t deviation;
289    
290            if (sadInit)
291                    (*sadInit)();
292    
293          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
294          for (i = 0; i < iHcount; i++)          for (i = 0; i < iHcount; i++)
295                  for (j = 0; j < iWcount; j++)                  for (j = 0; j < iWcount; j++)
296                  {                  {
297                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];
298                            MACROBLOCK *prevMB = &prevMBs[j + i * iWcount];
299    
300                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
301                                           j, i, pParam->motion_flags,                                           j, i, current->motion_flags, current->quant, current->fcode,
302                                           pParam, pMBs, &mv16, &pmv16);                                           pParam, pMBs, prevMBs, &mv16, &pmv16);
303                          pMB->sad16=sad16;                          pMB->sad16=sad16;
304    
305    
# Line 364  Line 315 
315                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
316                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
317    
318                                    pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
319    
320                                  iIntra++;                                  iIntra++;
321                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
322                                          return 1;                                          return 1;
# Line 371  Line 324 
324                                  continue;                                  continue;
325                          }                          }
326    
327                          if (pParam->global_flags & XVID_INTER4V)                          if (current->global_flags & XVID_INTER4V)
328                          {                          {
329                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
330                                                         2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i, mv16.x, mv16.y,
331                                                         pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                             current->motion_flags, current->quant, current->fcode,
332                                                           pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
333    
334                                  pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
335                                                         2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i, mv16.x, mv16.y,
336                                                         pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                                             current->motion_flags, current->quant, current->fcode,
337                                                           pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
338    
339                                  pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
340                                                         2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i + 1, mv16.x, mv16.y,
341                                                         pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                             current->motion_flags, current->quant, current->fcode,
342                                                           pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
343    
344                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
345                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y,
346                                                         pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                                             current->motion_flags, current->quant, current->fcode,
347                                                           pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
348    
349                                  sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];                                  sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];
350                          }                          }
# Line 397  Line 354 
354                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v
355                          */                          */
356    
357                          if (pMB->dquant == NO_CHANGE) {                          if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE)
358                                  if (((pParam->global_flags & XVID_INTER4V)==0) ||                          {
359                                      (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) {                                  if (((current->global_flags & XVID_INTER4V)==0) ||
360                                        (sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant))))
361                                    {
362    
363                                          sad8 = sad16;                                          sad8 = sad16;
364                                          pMB->mode = MODE_INTER;                                          pMB->mode = MODE_INTER;
365                                          pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                                          pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;
366                                          pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;                                          pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;
367                                            pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad16;
368                                          pMB->pmvs[0].x = pmv16.x;                                          pMB->pmvs[0].x = pmv16.x;
369                                          pMB->pmvs[0].y = pmv16.y;                                          pMB->pmvs[0].y = pmv16.y;
370                                  }                                  }
371                                  else                                  else
372                                    {
373                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
374                                            pMB->sad8[0] *= 4;
375                                            pMB->sad8[1] *= 4;
376                                            pMB->sad8[2] *= 4;
377                                            pMB->sad8[3] *= 4;
378                                    }
379                          }                          }
380                          else                          else
381                          {                          {
# Line 417  Line 383 
383                                  pMB->mode = MODE_INTER;                                  pMB->mode = MODE_INTER;
384                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;
385                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;
386                                    pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = sad16;
387    
388                                  pMB->pmvs[0].x = pmv16.x;                                  pMB->pmvs[0].x = pmv16.x;
389                                  pMB->pmvs[0].y = pmv16.y;                                  pMB->pmvs[0].y = pmv16.y;
390                          }                          }
# Line 435  Line 403 
403      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
404    { \    { \
405      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, 0, 0 , iEdgedWidth), iEdgedWidth, MV_MAX_ERROR); \
406      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
     if (iSAD <= iQuant * 96)    \  
         iSAD -= MV16_00_BIAS; \  
407      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
408      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
409  }  }
410    
411  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
412      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
413      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
414      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
415      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
416  }  }
# Line 454  Line 420 
420      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
421    { \    { \
422      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
423      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
424      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
425      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
426  }  }
# Line 464  Line 430 
430      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
431    { \    { \
432      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
433      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
434      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
435      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
436  }  }
# Line 474  Line 440 
440      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
441    { \    { \
442      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
443      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
444      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
445      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
446  }  }
# Line 482  Line 448 
448    
449  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
450    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \    iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, 0, 0 , iEdgedWidth), iEdgedWidth); \
451    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode) * iQuant;\    iSAD += calc_delta_8(-pmv[0].x, -pmv[0].y, (uint8_t)iFcode, iQuant);\
452    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
453    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
454  }  }
# Line 490  Line 456 
456  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
457    { \    { \
458      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
459      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
460      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
461      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
462  }  }
# Line 500  Line 466 
466      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
467    { \    { \
468      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
469      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
470      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
471      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
472  }  }
# Line 510  Line 476 
476      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
477    { \    { \
478      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
479      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
480      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
481      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
482  }  }
# Line 520  Line 486 
486      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
487    { \    { \
488      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
489      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
490      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
491      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
492  }  }
# Line 535  Line 501 
501                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
502                                          const int x, const int y,                                          const int x, const int y,
503                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
504                                            const uint32_t iQuant,
505                                            const uint32_t iFcode,
506                                          MBParam * const pParam,                                          MBParam * const pParam,
507                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
508                                            const MACROBLOCK * const prevMBs,
509                                          VECTOR * const currMV,                                          VECTOR * const currMV,
510                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
511  {  {
512          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
513          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
514          int32_t iSAD;          int32_t iSAD;
515          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 863  Line 831 
831                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
832                                          const int x, const int y,                                          const int x, const int y,
833                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
834                                            const uint32_t iQuant,
835                                            const uint32_t iFcode,
836                                          const MBParam * const pParam,                                          const MBParam * const pParam,
837                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
838                                            const MACROBLOCK * const prevMBs,
839                                          VECTOR * const currMV,                                          VECTOR * const currMV,
840                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
841  {  {
842          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
843          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
844          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
845          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 892  Line 861 
861          VECTOR pmv[4];          VECTOR pmv[4];
862          int32_t psad[4];          int32_t psad[4];
863    
864          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
865            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
866    
867          static int32_t threshA,threshB;          static int32_t threshA,threshB;
868          int32_t bPredEq;          int32_t bPredEq;
# Line 936  Line 906 
906     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
907  */  */
908    
909          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
910                  iFound=2;                  iFound=2;
911    
912  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
# Line 988  Line 958 
958          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
959                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
960                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
961          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
962    
963          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
964          {          {
965    
966                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
# Line 1003  Line 973 
973     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
974     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
975     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
976     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
977  */  */
978    
979  // (0,0) is always possible  // (0,0) is always possible
# Line 1011  Line 981 
981          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
982    
983  // previous frame MV is always possible  // previous frame MV is always possible
984          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
985    
986  // left neighbour, if allowed  // left neighbour, if allowed
987          if (x != 0)          if (x != 0)
# Line 1033  Line 1003 
1003                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1004    
1005  // top right neighbour, if allowed  // top right neighbour, if allowed
1006                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1007                  {                  {
1008                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1009                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1043  Line 1013 
1013                  }                  }
1014          }          }
1015    
1016            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1017                    iMinSAD -= MV16_00_BIAS;
1018    
1019    
1020  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1021     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
1022  */  */
1023    
1024          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1025          {          {
1026                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1027                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1233  Line 1207 
1207                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1208                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1209                                          const int x, const int y,                                          const int x, const int y,
1210                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1211                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1212                                            const uint32_t iQuant,
1213                                            const uint32_t iFcode,
1214                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1215                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1216                                            const MACROBLOCK * const prevMBs,
1217                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1218                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1219  {  {
1220          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
   
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1221          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1222          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1223          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1262  Line 1236 
1236          VECTOR newMV;          VECTOR newMV;
1237          VECTOR backupMV;          VECTOR backupMV;
1238    
1239          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1240            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1241    
1242          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1243          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
# Line 1274  Line 1249 
1249          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1250                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1251    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1252          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1253          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1254          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1308  Line 1281 
1281     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1282  */  */
1283    
1284          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1285                  iFound=2;                  iFound=2;
1286    
1287  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
# Line 1339  Line 1312 
1312          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1313                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1314                          iEdgedWidth);                          iEdgedWidth);
1315          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_8(currMV->x - pmv[0].x, currMV->y - pmv[0].y, (uint8_t)iFcode, iQuant);
1316    
1317          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1318          {          {
1319                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1320                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1354  Line 1327 
1327     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.     Step 5: Calculate SAD for motion vectors taken from left block, top, top-right, and Previous frame block.
1328     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1329     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1330     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1331  */  */
1332    
1333  // the prediction might be even better than mv16  // the prediction might be even better than mv16
# Line 1364  Line 1337 
1337          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1338    
1339  // previous frame MV is always possible  // previous frame MV is always possible
1340          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1341    
1342  // left neighbour, if allowed  // left neighbour, if allowed
1343          if (psad[1] != MV_MAX_ERROR)          if (psad[1] != MV_MAX_ERROR)
# Line 1396  Line 1369 
1369                  }                  }
1370          }          }
1371    
1372            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1373                    iMinSAD -= MV8_00_BIAS;
1374    
1375    
1376  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1377     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.     If Motion Vector equal to Previous frame motion vector and MinSAD<PrevFrmSAD goto Step 10.
1378  */  */
1379    
1380          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1381          {          {
1382                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1383                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1490  Line 1467 
1467                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1468                                          const int x, const int y,                                          const int x, const int y,
1469                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1470                                            const uint32_t iQuant,
1471                                            const uint32_t iFcode,
1472                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1473                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1474                                            const MACROBLOCK * const prevMBs,
1475                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1476                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1477  {  {
1478          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
1479          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1480    
1481          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1482          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1518  Line 1496 
1496          int32_t psad[8];          int32_t psad[8];
1497    
1498          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1499          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1500            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1501          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1502    
1503          static int32_t thresh2;          static int32_t thresh2;
# Line 1528  Line 1507 
1507          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1508    
1509          if (oldMBs == NULL)          if (oldMBs == NULL)
1510          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1511                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1512          }          }
1513          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1514    
# Line 1537  Line 1516 
1516          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1517                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1518    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1519          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1520          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1521            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1578  Line 1555 
1555          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1556                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1557                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1558          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_16(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
1559    
1560  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1561          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1562                  {                  {
1563                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1564                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1592  Line 1569 
1569  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1570    
1571  // previous frame MV  // previous frame MV
1572          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1573    
1574  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1575  // CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want  // CHECK_MV16 always uses iSAD for the SAD of last vector to check, so now iSAD is what we want
# Line 1633  Line 1610 
1610                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1611    
1612  // top right neighbour, if allowed  // top right neighbour, if allowed
1613                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1614                  {                  {
1615                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1616                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1648  Line 1625 
1625  */  */
1626    
1627          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1628                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1629                  {                  {
1630                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1631                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1658  Line 1635 
1635    
1636  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1637    
1638          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1639          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1640          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1641    
1642          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1643    
1644  // left neighbour  // left neighbour
1645          if (x != 0)          if (x != 0)
1646                  CHECK_MV16_CANDIDATE((oldMB-1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB-1)->mvs[0].x,(prevMB-1)->mvs[0].y);
1647    
1648  // top neighbour  // top neighbour
1649          if (y != 0)          if (y != 0)
1650                  CHECK_MV16_CANDIDATE((oldMB-iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB-iWcount)->mvs[0].x,(prevMB-iWcount)->mvs[0].y);
1651    
1652  // right neighbour, if allowed (this value is not written yet, so take it from   pMB->mvs  // right neighbour, if allowed (this value is not written yet, so take it from   pMB->mvs
1653    
1654          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1655                  CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB+1)->mvs[0].x,(prevMB+1)->mvs[0].y);
1656    
1657  // bottom neighbour, dito  // bottom neighbour, dito
1658          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1659                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((prevMB+iWcount)->mvs[0].x,(prevMB+iWcount)->mvs[0].y);
1660    
1661  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1662          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1736  Line 1713 
1713                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1714                                  x, y,                                  x, y,
1715                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1716                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, /*iDiamondSize*/ 2, iFcode, iQuant, 0);                          pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth, 2, iFcode, iQuant, 0);
1717    
1718                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1719                          {                          {
# Line 1757  Line 1734 
1734    
1735  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1736    
1737          *oldMB = *pMB;          *oldMB = *prevMB;
1738    
1739          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1740          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1774  Line 1751 
1751                                          const int x, const int y,                                          const int x, const int y,
1752                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1753                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1754                                            const uint32_t iQuant,
1755                                            const uint32_t iFcode,
1756                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1757                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1758                                            const MACROBLOCK * const prevMBs,
1759                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1760                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1761  {  {
1762          const uint32_t iWcount = pParam->mb_width;  /* Please not that EPZS might not be a good choice for 8x8-block motion search ! */
         const int32_t iFcode = pParam->fixed_code;  
         const int32_t iQuant = pParam->quant;  
1763    
1764            const uint32_t iWcount = pParam->mb_width;
1765          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1766          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1767          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1804  Line 1783 
1783    
1784          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1785    
1786          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1787            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1788    
1789          int32_t bPredEq;          int32_t bPredEq;
1790          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1858  Line 1838 
1838          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1839                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1840                  iEdgedWidth);                  iEdgedWidth);
1841          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode) * iQuant;          iMinSAD += calc_delta_8(currMV->x-pmv[0].x, currMV->y-pmv[0].y, (uint8_t)iFcode, iQuant);
1842    
1843    
1844  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1872  Line 1852 
1852    
1853  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1854    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1855    
1856  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1857          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1858    
1859    // previous frame MV
1860            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1861    
1862    // left neighbour, if allowed
1863            if (psad[1] != MV_MAX_ERROR)
1864            {
1865                    if (!(MotionFlags & PMV_HALFPEL8 ))
1866                    {       pmv[1].x = EVEN(pmv[1].x);
1867                            pmv[1].y = EVEN(pmv[1].y);
1868                    }
1869                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1870            }
1871    
1872    // top neighbour, if allowed
1873            if (psad[2] != MV_MAX_ERROR)
1874            {
1875                    if (!(MotionFlags & PMV_HALFPEL8 ))
1876                    {       pmv[2].x = EVEN(pmv[2].x);
1877                            pmv[2].y = EVEN(pmv[2].y);
1878                    }
1879                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1880    
1881    // top right neighbour, if allowed
1882                    if (psad[3] != MV_MAX_ERROR)
1883                    {
1884                            if (!(MotionFlags & PMV_HALFPEL8 ))
1885                            {       pmv[3].x = EVEN(pmv[3].x);
1886                                    pmv[3].y = EVEN(pmv[3].y);
1887                            }
1888                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1889                    }
1890            }
1891    
1892    /*  // this bias is zero anyway, at the moment!
1893    
1894            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1895                    iMinSAD -= MV8_00_BIAS;
1896    
1897    */
1898    
1899  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1900     Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1]     Terminate if MV[t] == MV[t-1] and MinSAD[t] <= MinSAD[t-1]
1901  */  */
# Line 1891  Line 1908 
1908                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1909                  }                  }
1910    
1911  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1912    
1913          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1914    
1915          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1916                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1917    
1918  /* default: use best prediction as starting point for one call of PMVfast_MainSearch */  /* default: use best prediction as starting point for one call of EPZS_MainSearch */
1919    
1920    /* // there is no EPZS^2 for inter4v at the moment
1921    
1922            if (MotionFlags & PMV_USESQUARES8)
1923                    EPZSMainSearchPtr = Square8_MainSearch;
1924            else
1925    */
1926    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1927                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1928    
1929          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1930                  x, y,                  x, y,
1931                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
1932                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1933                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
1934    
1935    
1936          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1967  Line 1988 
1988          return iMinSAD;          return iMinSAD;
1989  }  }
1990    
1991    
1992    
1993    
1994    
1995    /* ***********************************************************
1996            bvop motion estimation
1997    // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
1998    ***************************************************************/
1999    
2000    
2001    void MotionEstimationBVOP(
2002                            MBParam * const pParam,
2003                            FRAMEINFO * const frame,
2004    
2005                            // forward (past) reference
2006                            const MACROBLOCK * const f_mbs,
2007                        const IMAGE * const f_ref,
2008                            const IMAGE * const f_refH,
2009                        const IMAGE * const f_refV,
2010                            const IMAGE * const f_refHV,
2011                            // backward (future) reference
2012                            const MACROBLOCK * const b_mbs,
2013                        const IMAGE * const b_ref,
2014                            const IMAGE * const b_refH,
2015                        const IMAGE * const b_refV,
2016                            const IMAGE * const b_refHV)
2017    {
2018        const uint32_t mb_width = pParam->mb_width;
2019        const uint32_t mb_height = pParam->mb_height;
2020            const int32_t edged_width = pParam->edged_width;
2021    
2022            uint32_t i,j;
2023    
2024            int32_t f_sad16;
2025            int32_t b_sad16;
2026            int32_t i_sad16;
2027            int32_t d_sad16;
2028            int32_t best_sad;
2029    
2030            VECTOR pmv_dontcare;
2031    
2032            // note: i==horizontal, j==vertical
2033        for (j = 0; j < mb_height; j++)
2034            {
2035                    for (i = 0; i < mb_width; i++)
2036                    {
2037                            MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2038                            const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2039                            const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2040    
2041                            if (b_mb->mode == MODE_INTER
2042                                    && b_mb->cbp == 0
2043                                    && b_mb->mvs[0].x == 0
2044                                    && b_mb->mvs[0].y == 0)
2045                            {
2046                                    mb->mode = MODE_NOT_CODED;
2047                                    mb->mvs[0].x = 0;
2048                                    mb->mvs[0].y = 0;
2049                                    mb->b_mvs[0].x = 0;
2050                                    mb->b_mvs[0].y = 0;
2051                                    continue;
2052                            }
2053    
2054    
2055                            // forward search
2056                            f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2057                                                    &frame->image,
2058                                                    i, j,
2059                                                    frame->motion_flags,  frame->quant, frame->fcode,
2060                                                    pParam,
2061                                                    f_mbs, f_mbs /* todo */,
2062                                                    &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2063    
2064                            // backward search
2065                            b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2066                                                    &frame->image,
2067                                                    i, j,
2068                                                    frame->motion_flags,  frame->quant, frame->bcode,
2069                                                    pParam,
2070                                                    b_mbs, b_mbs, /* todo */
2071                                                    &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2072    
2073                            // interpolate search (simple, but effective)
2074                            i_sad16 = sad16bi_c(
2075                                            frame->image.y + i*16 + j*16*edged_width,
2076                                            get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2077                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),
2078                                            get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2079                                                    i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),
2080                                            edged_width);
2081    
2082                            // TODO: direct search
2083                            // predictor + range of [-32,32]
2084                            d_sad16 = 65535;
2085    
2086    
2087                            if (f_sad16 < b_sad16)
2088                            {
2089                                    best_sad = f_sad16;
2090                                    mb->mode = MODE_FORWARD;
2091                            }
2092                            else
2093                            {
2094                                    best_sad = b_sad16;
2095                                    mb->mode = MODE_BACKWARD;
2096                            }
2097    
2098                            if (i_sad16 < best_sad)
2099                            {
2100                                    best_sad = i_sad16;
2101                                    mb->mode = MODE_INTERPOLATE;
2102                            }
2103    
2104                            if (d_sad16 < best_sad)
2105                            {
2106                                    best_sad = d_sad16;
2107                                    mb->mode = MODE_DIRECT;
2108                            }
2109    
2110                    }
2111            }
2112    }

Legend:
Removed from v.96  
changed lines
  Added in v.167

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