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

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

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

revision 115, Thu Apr 11 10:18:40 2002 UTC revision 141, Thu Apr 25 23:24:59 2002 UTC
# Line 2  Line 2 
2   *   *
3   *  Modifications:   *  Modifications:
4   *   *
5     *      25.04.2002 partial prevMB conversion
6     *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>
7     *  14.04.2002 added MotionEstimationBVOP()
8   *  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
9   *             EPZS and EPZS^2   *             EPZS and EPZS^2
10   *  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 43 
43  #include "../prediction/mbprediction.h"  #include "../prediction/mbprediction.h"
44  #include "../global.h"  #include "../global.h"
45  #include "../utils/timer.h"  #include "../utils/timer.h"
46    #include "motion.h"
47  #include "sad.h"  #include "sad.h"
48    
49  // very large value  // very large value
# Line 52  Line 56 
56  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
57  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
58  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
59    #define MV8_00_BIAS     (0)
60    
61  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
62  #define INTER_BIAS      512  #define INTER_BIAS      512
# Line 68  Line 73 
73  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
74    
75    
 #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)  
   
76  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
77                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
78                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 81  Line 81 
81                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
82                                          const int x, const int y,                                          const int x, const int y,
83                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
84                                            const uint32_t iQuant,
85                                            const uint32_t iFcode,
86                                          const MBParam * const pParam,                                          const MBParam * const pParam,
87                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
88                                            const MACROBLOCK * const prevMBs,
89                                          VECTOR * const currMV,                                          VECTOR * const currMV,
90                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
91    
# Line 94  Line 97 
97                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
98                                          const int x, const int y,                                          const int x, const int y,
99                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
100                                            const uint32_t iQuant,
101                                            const uint32_t iFcode,
102                                          const MBParam * const pParam,                                          const MBParam * const pParam,
103                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
104                                            const MACROBLOCK * const prevMBs,
105                                          VECTOR * const currMV,                                          VECTOR * const currMV,
106                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
107    
# Line 107  Line 113 
113                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
114                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
115                                          const int x, const int y,                                          const int x, const int y,
116                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
117                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
118                                            const uint32_t iQuant,
119                                            const uint32_t iFcode,
120                                          const MBParam * const pParam,                                          const MBParam * const pParam,
121                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
122                                            const MACROBLOCK * const prevMBs,
123                                          VECTOR * const currMV,                                          VECTOR * const currMV,
124                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
125    
# Line 121  Line 130 
130                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
131                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
132                                          const int x, const int y,                                          const int x, const int y,
133                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
134                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
135                                            const uint32_t iQuant,
136                                            const uint32_t iFcode,
137                                          const MBParam * const pParam,                                          const MBParam * const pParam,
138                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
139                                            const MACROBLOCK * const prevMBs,
140                                          VECTOR * const currMV,                                          VECTOR * const currMV,
141                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
142    
# Line 172  Line 184 
184    
185  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
186    
187    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
188            {     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),
189            (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),
190            (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),
191            (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),
192            (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),
193            (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),
194            (int)(36.4949+0.5)      };
195    
196    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
197    
198    
199    
200  // mv.length table  // mv.length table
201  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
202      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 207  Line 232 
232  }  }
233    
234    
235  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)
236  {  {
237          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));
238  }  }
239    
240  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)
241    
242  {  {
243      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));
244  }  }
245    
246    
247    
248    
 /* 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;  
         }  
   
 }  
249    
250  #ifndef SEARCH16  #ifndef SEARCH16
251  #define SEARCH16        PMVfastSearch16  #define SEARCH16        PMVfastSearch16
# Line 318  Line 259 
259  #endif  #endif
260    
261  bool MotionEstimation(  bool MotionEstimation(
         MACROBLOCK * const pMBs,  
262          MBParam * const pParam,          MBParam * const pParam,
263          const IMAGE * const pRef,          FRAMEINFO * const current,
264            FRAMEINFO * const reference,
265          const IMAGE * const pRefH,          const IMAGE * const pRefH,
266          const IMAGE * const pRefV,          const IMAGE * const pRefV,
267          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
268          const uint32_t iLimit)          const uint32_t iLimit)
269    
270  {  {
271          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
272          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
273            MACROBLOCK * pMBs = current->mbs;
274            IMAGE * pCurrent = &current->image;
275    
276            MACROBLOCK * prevMBs = reference->mbs;  // previous frame
277            IMAGE * pRef = &reference->image;
278    
279    
280          uint32_t i, j, iIntra = 0;          uint32_t i, j, iIntra = 0;
281    
# Line 340  Line 286 
286          int32_t sad16;          int32_t sad16;
287          int32_t deviation;          int32_t deviation;
288    
289          if (sadInit);          if (sadInit)
290                  (*sadInit)();                  (*sadInit)();
291    
292    
293            /* eventhough we have a seperate prevMBs,
294               pmvfast/epsz does something "funny" with the previous frames data */
295    
296    /*      for (i = 0; i < iHcount; i++)
297                    for (j = 0; j < iWcount; j++)
298                    {
299                            pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];
300                            pMBs[j + i * iWcount].mvs[1] = prevMBs[j + i * iWcount].mvs[1];
301                            pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];
302                            pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];
303                    }
304    */
305            /*dprintf("*** BEFORE ***");
306            for (i = 0; i < iHcount; i++)
307                    for (j = 0; j < iWcount; j++)
308                    {
309                            dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,
310                                    pMBs[j + i * iWcount].mode,
311                                    pMBs[j + i * iWcount].dquant,
312                                    pMBs[j + i * iWcount].mvs[0],
313                                    pMBs[j + i * iWcount].mvs[1],
314                                    pMBs[j + i * iWcount].mvs[2],
315                                    pMBs[j + i * iWcount].mvs[3],
316                                    prevMBs[j + i * iWcount].sad8[0],
317                                    prevMBs[j + i * iWcount].sad8[1],
318                                    prevMBs[j + i * iWcount].sad8[2],
319                                    prevMBs[j + i * iWcount].sad8[3],
320                                    prevMBs[j + i * iWcount].sad16);
321                    }
322            */
323    
324          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
325          for (i = 0; i < iHcount; i++)          for (i = 0; i < iHcount; i++)
326                  for (j = 0; j < iWcount; j++)                  for (j = 0; j < iWcount; j++)
327                  {                  {
328                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];
329                            MACROBLOCK *prevMB = &prevMBs[j + i * iWcount];
330    
331                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
332                                           j, i, pParam->motion_flags,                                           j, i, current->motion_flags, current->quant, current->fcode,
333                                           pParam, pMBs, &mv16, &pmv16);                                           pParam, pMBs, prevMBs, &mv16, &pmv16);
334                          pMB->sad16=sad16;                          pMB->sad16=sad16;
335    
336    
# Line 367  Line 346 
346                                  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;
347                                  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;
348    
349                                    pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
350    
351                                  iIntra++;                                  iIntra++;
352                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
353                                          return 1;                                          return 1;
# Line 374  Line 355 
355                                  continue;                                  continue;
356                          }                          }
357    
358                          if (pParam->global_flags & XVID_INTER4V)                          if (current->global_flags & XVID_INTER4V)
359                          {                          {
360                                  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,
361                                                         2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i, mv16.x, mv16.y,
362                                                         pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                             current->motion_flags, current->quant, current->fcode,
363                                                           pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
364    
365                                  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,
366                                                         2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i, mv16.x, mv16.y,
367                                                         pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                                             current->motion_flags, current->quant, current->fcode,
368                                                           pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
369    
370                                  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,
371                                                         2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i + 1, mv16.x, mv16.y,
372                                                         pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                             current->motion_flags, current->quant, current->fcode,
373                                                           pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
374    
375                                  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,
376                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y,
377                                                         pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                                             current->motion_flags, current->quant, current->fcode,
378                                                           pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
379    
380                                  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];
381                          }                          }
# Line 400  Line 385 
385                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v
386                          */                          */
387    
388                          if (pMB->dquant == NO_CHANGE) {                          if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE)
389                                  if (((pParam->global_flags & XVID_INTER4V)==0) ||                          {
390                                      (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) {                                  if (((current->global_flags & XVID_INTER4V)==0) ||
391                                        (sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant))))
392                                    {
393    
394                                          sad8 = sad16;                                          sad8 = sad16;
395                                          pMB->mode = MODE_INTER;                                          pMB->mode = MODE_INTER;
# Line 425  Line 412 
412                          }                          }
413                  }                  }
414    
415    /*      dprintf("*** AFTER ***", pMBs[0].b_mvs[0].x);
416            for (i = 0; i < iHcount; i++)
417                    for (j = 0; j < iWcount; j++)
418                    {
419                            dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,
420                                    pMBs[j + i * iWcount].mode,
421                                    pMBs[j + i * iWcount].dquant,
422                                    pMBs[j + i * iWcount].mvs[0],
423                                    pMBs[j + i * iWcount].mvs[1],
424                                    pMBs[j + i * iWcount].mvs[2],
425                                    pMBs[j + i * iWcount].mvs[3],
426                                    pMBs[j + i * iWcount].sad8[0],
427                                    pMBs[j + i * iWcount].sad8[1],
428                                    pMBs[j + i * iWcount].sad8[2],
429                                    pMBs[j + i * iWcount].sad8[3],
430                                    pMBs[j + i * iWcount].sad16);
431                    }
432            */
433    
434          return 0;          return 0;
435  }  }
436    
# Line 438  Line 444 
444      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
445    { \    { \
446      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); \
447      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; \  
448      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
449      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
450  }  }
451    
452  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
453      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); \
454      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);\
455      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
456      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
457  }  }
# Line 457  Line 461 
461      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
462    { \    { \
463      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); \
464      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);\
465      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
466      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
467  }  }
# Line 467  Line 471 
471      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
472    { \    { \
473      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); \
474      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);\
475      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
476      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
477  }  }
# Line 477  Line 481 
481      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
482    { \    { \
483      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); \
484      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);\
485      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
486      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
487  }  }
# Line 485  Line 489 
489    
490  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
491    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); \
492    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);\
493    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
494    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
495  }  }
# Line 493  Line 497 
497  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
498    { \    { \
499      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); \
500      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);\
501      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
502      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
503  }  }
# Line 503  Line 507 
507      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
508    { \    { \
509      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); \
510      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);\
511      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
512      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
513  }  }
# Line 513  Line 517 
517      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
518    { \    { \
519      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); \
520      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);\
521      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
522      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
523  }  }
# Line 523  Line 527 
527      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
528    { \    { \
529      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); \
530      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);\
531      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
532      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
533  }  }
# Line 538  Line 542 
542                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
543                                          const int x, const int y,                                          const int x, const int y,
544                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
545                                            const uint32_t iQuant,
546                                            const uint32_t iFcode,
547                                          MBParam * const pParam,                                          MBParam * const pParam,
548                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
549                                            const MACROBLOCK * const prevMBs,
550                                          VECTOR * const currMV,                                          VECTOR * const currMV,
551                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
552  {  {
553          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
554          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
555          int32_t iSAD;          int32_t iSAD;
556          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 866  Line 872 
872                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
873                                          const int x, const int y,                                          const int x, const int y,
874                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
875                                            const uint32_t iQuant,
876                                            const uint32_t iFcode,
877                                          const MBParam * const pParam,                                          const MBParam * const pParam,
878                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
879                                            const MACROBLOCK * const prevMBs,
880                                          VECTOR * const currMV,                                          VECTOR * const currMV,
881                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
882  {  {
883          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;  
884          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
885          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
886          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 895  Line 902 
902          VECTOR pmv[4];          VECTOR pmv[4];
903          int32_t psad[4];          int32_t psad[4];
904    
905          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
906            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
907    
908          static int32_t threshA,threshB;          static int32_t threshA,threshB;
909          int32_t bPredEq;          int32_t bPredEq;
# Line 939  Line 947 
947     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
948  */  */
949    
950          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
951                  iFound=2;                  iFound=2;
952    
953  /* 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 991  Line 999 
999          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1000                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1001                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
1002          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);
1003    
1004          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1005          {          {
1006    
1007                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
# Line 1006  Line 1014 
1014     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.
1015     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1016     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1017     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1018  */  */
1019    
1020  // (0,0) is always possible  // (0,0) is always possible
# Line 1014  Line 1022 
1022          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1023    
1024  // previous frame MV is always possible  // previous frame MV is always possible
1025          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1026    
1027  // left neighbour, if allowed  // left neighbour, if allowed
1028          if (x != 0)          if (x != 0)
# Line 1036  Line 1044 
1044                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1045    
1046  // top right neighbour, if allowed  // top right neighbour, if allowed
1047                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1048                  {                  {
1049                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1050                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1046  Line 1054 
1054                  }                  }
1055          }          }
1056    
1057            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1058                    iMinSAD -= MV16_00_BIAS;
1059    
1060    
1061  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1062     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.
1063  */  */
1064    
1065          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1066          {          {
1067                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1068                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1236  Line 1248 
1248                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1249                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1250                                          const int x, const int y,                                          const int x, const int y,
1251                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1252                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1253                                            const uint32_t iQuant,
1254                                            const uint32_t iFcode,
1255                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1256                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1257                                            const MACROBLOCK * const prevMBs,
1258                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1259                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1260  {  {
1261          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;  
1262          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1263          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1264          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1265  Line 1277 
1277          VECTOR newMV;          VECTOR newMV;
1278          VECTOR backupMV;          VECTOR backupMV;
1279    
1280          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1281            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1282    
1283          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1284          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
# Line 1277  Line 1290 
1290          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1291                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1292    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1293          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1294          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1295          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1311  Line 1322 
1322     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1323  */  */
1324    
1325          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1326                  iFound=2;                  iFound=2;
1327    
1328  /* 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 1342  Line 1353 
1353          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1354                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1355                          iEdgedWidth);                          iEdgedWidth);
1356          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);
1357    
1358          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]) ) )
1359          {          {
1360                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1361                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1357  Line 1368 
1368     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.
1369     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1370     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1371     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1372  */  */
1373    
1374  // the prediction might be even better than mv16  // the prediction might be even better than mv16
# Line 1367  Line 1378 
1378          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1379    
1380  // previous frame MV is always possible  // previous frame MV is always possible
1381          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1382    
1383  // left neighbour, if allowed  // left neighbour, if allowed
1384          if (psad[1] != MV_MAX_ERROR)          if (psad[1] != MV_MAX_ERROR)
# Line 1399  Line 1410 
1410                  }                  }
1411          }          }
1412    
1413            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1414                    iMinSAD -= MV8_00_BIAS;
1415    
1416    
1417  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1418     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.
1419  */  */
1420    
1421          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]) ) )
1422          {          {
1423                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1424                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1493  Line 1508 
1508                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1509                                          const int x, const int y,                                          const int x, const int y,
1510                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1511                                            const uint32_t iQuant,
1512                                            const uint32_t iFcode,
1513                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1514                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1515                                            const MACROBLOCK * const prevMBs,
1516                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1517                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1518  {  {
1519          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
1520          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;  
1521    
1522          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1523          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1521  Line 1537 
1537          int32_t psad[8];          int32_t psad[8];
1538    
1539          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1540          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1541            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1542          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1543    
1544          static int32_t thresh2;          static int32_t thresh2;
# Line 1531  Line 1548 
1548          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1549    
1550          if (oldMBs == NULL)          if (oldMBs == NULL)
1551          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1552                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1553          }          }
1554          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1555    
# Line 1540  Line 1557 
1557          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1558                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1559    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1560          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1561          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1562            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1581  Line 1596 
1596          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1597                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1598                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1599          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);
1600    
1601  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1602          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1603                  {                  {
1604                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1605                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1595  Line 1610 
1610  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1611    
1612  // previous frame MV  // previous frame MV
1613          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1614    
1615  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1616  // 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 1636  Line 1651 
1651                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1652    
1653  // top right neighbour, if allowed  // top right neighbour, if allowed
1654                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1655                  {                  {
1656                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1657                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1651  Line 1666 
1666  */  */
1667    
1668          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1669                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1670                  {                  {
1671                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1672                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1661  Line 1676 
1676    
1677  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1678    
1679          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1680          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1681          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1682    
1683          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1684    
1685  // left neighbour  // left neighbour
1686          if (x != 0)          if (x != 0)
1687                  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);
1688    
1689  // top neighbour  // top neighbour
1690          if (y != 0)          if (y != 0)
1691                  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);
1692    
1693  // 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
1694    
1695          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1696                  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);
1697    
1698  // bottom neighbour, dito  // bottom neighbour, dito
1699          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1700                  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);
1701    
1702  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1703          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1739  Line 1754 
1754                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1755                                  x, y,                                  x, y,
1756                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1757                          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);
1758    
1759                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1760                          {                          {
# Line 1760  Line 1775 
1775    
1776  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1777    
1778          *oldMB = *pMB;          *oldMB = *prevMB;
1779    
1780          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1781          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1777  Line 1792 
1792                                          const int x, const int y,                                          const int x, const int y,
1793                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1794                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1795                                            const uint32_t iQuant,
1796                                            const uint32_t iFcode,
1797                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1798                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1799                                            const MACROBLOCK * const prevMBs,
1800                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1801                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1802  {  {
1803          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;  
1804    
1805            const uint32_t iWcount = pParam->mb_width;
1806          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1807          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1808          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1807  Line 1824 
1824    
1825          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1826    
1827          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1828            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1829    
1830          int32_t bPredEq;          int32_t bPredEq;
1831          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1861  Line 1879 
1879          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1880                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1881                  iEdgedWidth);                  iEdgedWidth);
1882          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);
1883    
1884    
1885  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1893 
1893    
1894  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1895    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1896    
1897  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1898          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1899    
1900    // previous frame MV
1901            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1902    
1903    // left neighbour, if allowed
1904            if (psad[1] != MV_MAX_ERROR)
1905            {
1906                    if (!(MotionFlags & PMV_HALFPEL8 ))
1907                    {       pmv[1].x = EVEN(pmv[1].x);
1908                            pmv[1].y = EVEN(pmv[1].y);
1909                    }
1910                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1911            }
1912    
1913    // top neighbour, if allowed
1914            if (psad[2] != MV_MAX_ERROR)
1915            {
1916                    if (!(MotionFlags & PMV_HALFPEL8 ))
1917                    {       pmv[2].x = EVEN(pmv[2].x);
1918                            pmv[2].y = EVEN(pmv[2].y);
1919                    }
1920                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1921    
1922    // top right neighbour, if allowed
1923                    if (psad[3] != MV_MAX_ERROR)
1924                    {
1925                            if (!(MotionFlags & PMV_HALFPEL8 ))
1926                            {       pmv[3].x = EVEN(pmv[3].x);
1927                                    pmv[3].y = EVEN(pmv[3].y);
1928                            }
1929                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1930                    }
1931            }
1932    
1933    /*  // this bias is zero anyway, at the moment!
1934    
1935            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1936                    iMinSAD -= MV8_00_BIAS;
1937    
1938    */
1939    
1940  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1941     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]
1942  */  */
# Line 1894  Line 1949 
1949                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1950                  }                  }
1951    
1952  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1953    
1954          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1955    
1956          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1957                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1958    
1959  /* 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 */
1960    
1961    /* // there is no EPZS^2 for inter4v at the moment
1962    
1963            if (MotionFlags & PMV_USESQUARES8)
1964                    EPZSMainSearchPtr = Square8_MainSearch;
1965            else
1966    */
1967    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1968                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1969    
1970          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1971                  x, y,                  x, y,
1972                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
1973                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1974                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
1975    
1976    
1977          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1970  Line 2029 
2029          return iMinSAD;          return iMinSAD;
2030  }  }
2031    
2032    
2033    
2034    
2035    
2036    /* ***********************************************************
2037            bvop motion estimation
2038    // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2039    ***************************************************************/
2040    
2041    /*
2042    void MotionEstimationBVOP(
2043                            MBParam * const pParam,
2044                            FRAMEINFO * const frame,
2045    
2046                            // forward (past) reference
2047                            const MACROBLOCK * const f_mbs,
2048                        const IMAGE * const f_ref,
2049                            const IMAGE * const f_refH,
2050                        const IMAGE * const f_refV,
2051                            const IMAGE * const f_refHV,
2052                            // backward (future) reference
2053                            const MACROBLOCK * const b_mbs,
2054                        const IMAGE * const b_ref,
2055                            const IMAGE * const b_refH,
2056                        const IMAGE * const b_refV,
2057                            const IMAGE * const b_refHV)
2058    {
2059        const uint32_t mb_width = pParam->mb_width;
2060        const uint32_t mb_height = pParam->mb_height;
2061            const int32_t edged_width = pParam->edged_width;
2062    
2063            int32_t i,j;
2064    
2065            int32_t f_sad16;
2066            int32_t b_sad16;
2067            int32_t i_sad16;
2068            int32_t d_sad16;
2069            int32_t best_sad;
2070    
2071            VECTOR pmv_dontcare;
2072    
2073            // note: i==horizontal, j==vertical
2074        for (j = 0; j < mb_height; j++)
2075            {
2076                    for (i = 0; i < mb_width; i++)
2077                    {
2078                            MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2079                            const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2080                            const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2081    
2082                            if (b_mb->mode == MODE_INTER
2083                                    && b_mb->cbp == 0
2084                                    && b_mb->mvs[0].x == 0
2085                                    && b_mb->mvs[0].y == 0)
2086                            {
2087                                    mb->mode = MB_IGNORE;
2088                                    mb->mvs[0].x = 0;
2089                                    mb->mvs[0].y = 0;
2090                                    mb->b_mvs[0].x = 0;
2091                                    mb->b_mvs[0].y = 0;
2092                                    continue;
2093                            }
2094    
2095    
2096                            // forward search
2097                            f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2098                                                    &frame->image,
2099                                                    i, j,
2100                                                    frame->motion_flags,  frame->quant, frame->fcode,
2101                                                    pParam,
2102                                                    f_mbs,
2103                                                    &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2104    
2105                            // backward search
2106                            b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2107                                                    &frame->image,
2108                                                    i, j,
2109                                                    frame->motion_flags,  frame->quant, frame->bcode,
2110                                                    pParam,
2111                                                    b_mbs,
2112                                                    &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2113    
2114                            // interpolate search (simple, but effective)
2115                            i_sad16 = sad16bi_c(
2116                                            frame->image.y + i*16 + j*16*edged_width,
2117                                            get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2118                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),
2119                                            get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2120                                                    i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),
2121                                            edged_width);
2122    
2123                            // TODO: direct search
2124                            // predictor + range of [-32,32]
2125                            d_sad16 = 65535;
2126    
2127    
2128                            if (f_sad16 < b_sad16)
2129                            {
2130                                    best_sad = f_sad16;
2131                                    mb->mode = MB_FORWARD;
2132                            }
2133                            else
2134                            {
2135                                    best_sad = b_sad16;
2136                                    mb->mode = MB_BACKWARD;
2137                            }
2138    
2139                            if (i_sad16 < best_sad)
2140                            {
2141                                    best_sad = i_sad16;
2142                                    mb->mode = MB_INTERPOLATE;
2143                            }
2144    
2145                            if (d_sad16 < best_sad)
2146                            {
2147                                    best_sad = d_sad16;
2148                                    mb->mode = MB_DIRECT;
2149                            }
2150    
2151                    }
2152            }
2153    }
2154    
2155    */

Legend:
Removed from v.115  
changed lines
  Added in v.141

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