[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 117, Thu Apr 11 15:04:05 2002 UTC revision 152, Wed May 1 13:00:02 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 343  Line 290 
290          if (sadInit)          if (sadInit)
291                  (*sadInit)();                  (*sadInit)();
292    
293    
294            /* eventhough we have a seperate prevMBs,
295               pmvfast/epsz does something "funny" with the previous frames data */
296    
297    /*      for (i = 0; i < iHcount; i++)
298                    for (j = 0; j < iWcount; j++)
299                    {
300                            pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];
301                            pMBs[j + i * iWcount].mvs[1] = prevMBs[j + i * iWcount].mvs[1];
302                            pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];
303                            pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];
304                    }
305    */
306            /*dprintf("*** BEFORE ***");
307            for (i = 0; i < iHcount; i++)
308                    for (j = 0; j < iWcount; j++)
309                    {
310                            dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,
311                                    pMBs[j + i * iWcount].mode,
312                                    pMBs[j + i * iWcount].dquant,
313                                    pMBs[j + i * iWcount].mvs[0],
314                                    pMBs[j + i * iWcount].mvs[1],
315                                    pMBs[j + i * iWcount].mvs[2],
316                                    pMBs[j + i * iWcount].mvs[3],
317                                    prevMBs[j + i * iWcount].sad8[0],
318                                    prevMBs[j + i * iWcount].sad8[1],
319                                    prevMBs[j + i * iWcount].sad8[2],
320                                    prevMBs[j + i * iWcount].sad8[3],
321                                    prevMBs[j + i * iWcount].sad16);
322                    }
323            */
324    
325          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
326          for (i = 0; i < iHcount; i++)          for (i = 0; i < iHcount; i++)
327                  for (j = 0; j < iWcount; j++)                  for (j = 0; j < iWcount; j++)
328                  {                  {
329                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];
330                            MACROBLOCK *prevMB = &prevMBs[j + i * iWcount];
331    
332                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
333                                           j, i, pParam->motion_flags,                                           j, i, current->motion_flags, current->quant, current->fcode,
334                                           pParam, pMBs, &mv16, &pmv16);                                           pParam, pMBs, prevMBs, &mv16, &pmv16);
335                          pMB->sad16=sad16;                          pMB->sad16=sad16;
336    
337    
# Line 367  Line 347 
347                                  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;
348                                  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;
349    
350                                    pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
351    
352                                  iIntra++;                                  iIntra++;
353                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
354                                          return 1;                                          return 1;
# Line 374  Line 356 
356                                  continue;                                  continue;
357                          }                          }
358    
359                          if (pParam->global_flags & XVID_INTER4V)                          if (current->global_flags & XVID_INTER4V)
360                          {                          {
361                                  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,
362                                                         2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i, mv16.x, mv16.y,
363                                                         pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                             current->motion_flags, current->quant, current->fcode,
364                                                           pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
365    
366                                  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,
367                                                         2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i, mv16.x, mv16.y,
368                                                         pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                                             current->motion_flags, current->quant, current->fcode,
369                                                           pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
370    
371                                  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,
372                                                         2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i + 1, mv16.x, mv16.y,
373                                                         pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                             current->motion_flags, current->quant, current->fcode,
374                                                           pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
375    
376                                  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,
377                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y,
378                                                         pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                                             current->motion_flags, current->quant, current->fcode,
379                                                           pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
380    
381                                  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];
382                          }                          }
# Line 400  Line 386 
386                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v
387                          */                          */
388    
389                          if (pMB->dquant == NO_CHANGE) {                          if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE)
390                                  if (((pParam->global_flags & XVID_INTER4V)==0) ||                          {
391                                      (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) {                                  if (((current->global_flags & XVID_INTER4V)==0) ||
392                                        (sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant))))
393                                    {
394    
395                                          sad8 = sad16;                                          sad8 = sad16;
396                                          pMB->mode = MODE_INTER;                                          pMB->mode = MODE_INTER;
# Line 425  Line 413 
413                          }                          }
414                  }                  }
415    
416    /*      dprintf("*** AFTER ***", pMBs[0].b_mvs[0].x);
417            for (i = 0; i < iHcount; i++)
418                    for (j = 0; j < iWcount; j++)
419                    {
420                            dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,
421                                    pMBs[j + i * iWcount].mode,
422                                    pMBs[j + i * iWcount].dquant,
423                                    pMBs[j + i * iWcount].mvs[0],
424                                    pMBs[j + i * iWcount].mvs[1],
425                                    pMBs[j + i * iWcount].mvs[2],
426                                    pMBs[j + i * iWcount].mvs[3],
427                                    pMBs[j + i * iWcount].sad8[0],
428                                    pMBs[j + i * iWcount].sad8[1],
429                                    pMBs[j + i * iWcount].sad8[2],
430                                    pMBs[j + i * iWcount].sad8[3],
431                                    pMBs[j + i * iWcount].sad16);
432                    }
433            */
434    
435          return 0;          return 0;
436  }  }
437    
# Line 438  Line 445 
445      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
446    { \    { \
447      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); \
448      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; \  
449      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
450      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
451  }  }
452    
453  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
454      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); \
455      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);\
456      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
457      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
458  }  }
# Line 457  Line 462 
462      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
463    { \    { \
464      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); \
465      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);\
466      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
467      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
468  }  }
# Line 467  Line 472 
472      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
473    { \    { \
474      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); \
475      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);\
476      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
477      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
478  }  }
# Line 477  Line 482 
482      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
483    { \    { \
484      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); \
485      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);\
486      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
487      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
488  }  }
# Line 485  Line 490 
490    
491  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
492    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); \
493    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);\
494    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
495    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
496  }  }
# Line 493  Line 498 
498  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
499    { \    { \
500      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); \
501      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);\
502      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
503      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
504  }  }
# Line 503  Line 508 
508      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
509    { \    { \
510      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); \
511      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);\
512      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
513      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
514  }  }
# Line 513  Line 518 
518      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
519    { \    { \
520      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); \
521      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);\
522      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
523      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
524  }  }
# Line 523  Line 528 
528      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
529    { \    { \
530      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); \
531      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);\
532      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
533      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
534  }  }
# Line 538  Line 543 
543                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
544                                          const int x, const int y,                                          const int x, const int y,
545                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
546                                            const uint32_t iQuant,
547                                            const uint32_t iFcode,
548                                          MBParam * const pParam,                                          MBParam * const pParam,
549                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
550                                            const MACROBLOCK * const prevMBs,
551                                          VECTOR * const currMV,                                          VECTOR * const currMV,
552                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
553  {  {
554          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
555          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
556          int32_t iSAD;          int32_t iSAD;
557          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 866  Line 873 
873                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
874                                          const int x, const int y,                                          const int x, const int y,
875                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
876                                            const uint32_t iQuant,
877                                            const uint32_t iFcode,
878                                          const MBParam * const pParam,                                          const MBParam * const pParam,
879                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
880                                            const MACROBLOCK * const prevMBs,
881                                          VECTOR * const currMV,                                          VECTOR * const currMV,
882                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
883  {  {
884          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;  
885          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
886          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
887          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 895  Line 903 
903          VECTOR pmv[4];          VECTOR pmv[4];
904          int32_t psad[4];          int32_t psad[4];
905    
906          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
907            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
908    
909          static int32_t threshA,threshB;          static int32_t threshA,threshB;
910          int32_t bPredEq;          int32_t bPredEq;
# Line 939  Line 948 
948     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
949  */  */
950    
951          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
952                  iFound=2;                  iFound=2;
953    
954  /* 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 1000 
1000          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1001                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1002                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
1003          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);
1004    
1005          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1006          {          {
1007    
1008                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
# Line 1006  Line 1015 
1015     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.
1016     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1017     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1018     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1019  */  */
1020    
1021  // (0,0) is always possible  // (0,0) is always possible
# Line 1014  Line 1023 
1023          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1024    
1025  // previous frame MV is always possible  // previous frame MV is always possible
1026          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1027    
1028  // left neighbour, if allowed  // left neighbour, if allowed
1029          if (x != 0)          if (x != 0)
# Line 1036  Line 1045 
1045                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1046    
1047  // top right neighbour, if allowed  // top right neighbour, if allowed
1048                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1049                  {                  {
1050                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1051                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1046  Line 1055 
1055                  }                  }
1056          }          }
1057    
1058            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1059                    iMinSAD -= MV16_00_BIAS;
1060    
1061    
1062  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1063     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.
1064  */  */
1065    
1066          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1067          {          {
1068                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1069                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1236  Line 1249 
1249                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1250                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1251                                          const int x, const int y,                                          const int x, const int y,
1252                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1253                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1254                                            const uint32_t iQuant,
1255                                            const uint32_t iFcode,
1256                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1257                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1258                                            const MACROBLOCK * const prevMBs,
1259                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1260                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1261  {  {
1262          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;  
1263          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1264          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1265          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1265  Line 1278 
1278          VECTOR newMV;          VECTOR newMV;
1279          VECTOR backupMV;          VECTOR backupMV;
1280    
1281          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1282            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1283    
1284          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1285          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
# Line 1277  Line 1291 
1291          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1292                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1293    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1294          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1295          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1296          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1311  Line 1323 
1323     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1324  */  */
1325    
1326          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1327                  iFound=2;                  iFound=2;
1328    
1329  /* 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 1354 
1354          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1355                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1356                          iEdgedWidth);                          iEdgedWidth);
1357          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);
1358    
1359          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]) ) )
1360          {          {
1361                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1362                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1357  Line 1369 
1369     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.
1370     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1371     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1372     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1373  */  */
1374    
1375  // the prediction might be even better than mv16  // the prediction might be even better than mv16
# Line 1367  Line 1379 
1379          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1380    
1381  // previous frame MV is always possible  // previous frame MV is always possible
1382          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1383    
1384  // left neighbour, if allowed  // left neighbour, if allowed
1385          if (psad[1] != MV_MAX_ERROR)          if (psad[1] != MV_MAX_ERROR)
# Line 1399  Line 1411 
1411                  }                  }
1412          }          }
1413    
1414            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1415                    iMinSAD -= MV8_00_BIAS;
1416    
1417    
1418  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1419     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.
1420  */  */
1421    
1422          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]) ) )
1423          {          {
1424                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1425                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1493  Line 1509 
1509                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1510                                          const int x, const int y,                                          const int x, const int y,
1511                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1512                                            const uint32_t iQuant,
1513                                            const uint32_t iFcode,
1514                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1515                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1516                                            const MACROBLOCK * const prevMBs,
1517                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1518                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1519  {  {
1520          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
1521          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;  
1522    
1523          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1524          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1521  Line 1538 
1538          int32_t psad[8];          int32_t psad[8];
1539    
1540          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1541          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1542            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1543          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1544    
1545          static int32_t thresh2;          static int32_t thresh2;
# Line 1531  Line 1549 
1549          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1550    
1551          if (oldMBs == NULL)          if (oldMBs == NULL)
1552          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1553                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1554          }          }
1555          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1556    
# Line 1540  Line 1558 
1558          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1559                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1560    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1561          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1562          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1563            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1581  Line 1597 
1597          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1598                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1599                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1600          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);
1601    
1602  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1603          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1604                  {                  {
1605                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1606                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1595  Line 1611 
1611  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1612    
1613  // previous frame MV  // previous frame MV
1614          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1615    
1616  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1617  // 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 1652 
1652                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1653    
1654  // top right neighbour, if allowed  // top right neighbour, if allowed
1655                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1656                  {                  {
1657                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1658                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1651  Line 1667 
1667  */  */
1668    
1669          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1670                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1671                  {                  {
1672                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1673                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1661  Line 1677 
1677    
1678  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1679    
1680          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1681          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1682          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1683    
1684          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1685    
1686  // left neighbour  // left neighbour
1687          if (x != 0)          if (x != 0)
1688                  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);
1689    
1690  // top neighbour  // top neighbour
1691          if (y != 0)          if (y != 0)
1692                  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);
1693    
1694  // 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
1695    
1696          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1697                  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);
1698    
1699  // bottom neighbour, dito  // bottom neighbour, dito
1700          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1701                  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);
1702    
1703  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1704          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1739  Line 1755 
1755                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1756                                  x, y,                                  x, y,
1757                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1758                          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);
1759    
1760                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1761                          {                          {
# Line 1760  Line 1776 
1776    
1777  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1778    
1779          *oldMB = *pMB;          *oldMB = *prevMB;
1780    
1781          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1782          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1777  Line 1793 
1793                                          const int x, const int y,                                          const int x, const int y,
1794                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1795                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1796                                            const uint32_t iQuant,
1797                                            const uint32_t iFcode,
1798                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1799                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1800                                            const MACROBLOCK * const prevMBs,
1801                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1802                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1803  {  {
1804          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;  
1805    
1806            const uint32_t iWcount = pParam->mb_width;
1807          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1808          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1809          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1807  Line 1825 
1825    
1826          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1827    
1828          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1829            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1830    
1831          int32_t bPredEq;          int32_t bPredEq;
1832          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1861  Line 1880 
1880          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1881                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1882                  iEdgedWidth);                  iEdgedWidth);
1883          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);
1884    
1885    
1886  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1894 
1894    
1895  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1896    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1897    
1898  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1899          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1900    
1901    // previous frame MV
1902            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1903    
1904    // left neighbour, if allowed
1905            if (psad[1] != MV_MAX_ERROR)
1906            {
1907                    if (!(MotionFlags & PMV_HALFPEL8 ))
1908                    {       pmv[1].x = EVEN(pmv[1].x);
1909                            pmv[1].y = EVEN(pmv[1].y);
1910                    }
1911                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1912            }
1913    
1914    // top neighbour, if allowed
1915            if (psad[2] != MV_MAX_ERROR)
1916            {
1917                    if (!(MotionFlags & PMV_HALFPEL8 ))
1918                    {       pmv[2].x = EVEN(pmv[2].x);
1919                            pmv[2].y = EVEN(pmv[2].y);
1920                    }
1921                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1922    
1923    // top right neighbour, if allowed
1924                    if (psad[3] != MV_MAX_ERROR)
1925                    {
1926                            if (!(MotionFlags & PMV_HALFPEL8 ))
1927                            {       pmv[3].x = EVEN(pmv[3].x);
1928                                    pmv[3].y = EVEN(pmv[3].y);
1929                            }
1930                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1931                    }
1932            }
1933    
1934    /*  // this bias is zero anyway, at the moment!
1935    
1936            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1937                    iMinSAD -= MV8_00_BIAS;
1938    
1939    */
1940    
1941  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1942     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]
1943  */  */
# Line 1894  Line 1950 
1950                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1951                  }                  }
1952    
1953  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1954    
1955          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1956    
1957          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1958                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1959    
1960  /* 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 */
1961    
1962    /* // there is no EPZS^2 for inter4v at the moment
1963    
1964            if (MotionFlags & PMV_USESQUARES8)
1965                    EPZSMainSearchPtr = Square8_MainSearch;
1966            else
1967    */
1968    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1969                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1970    
1971          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1972                  x, y,                  x, y,
1973                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
1974                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1975                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
1976    
1977    
1978          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1970  Line 2030 
2030          return iMinSAD;          return iMinSAD;
2031  }  }
2032    
2033    
2034    
2035    
2036    
2037    /* ***********************************************************
2038            bvop motion estimation
2039    // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2040    ***************************************************************/
2041    
2042    
2043    void MotionEstimationBVOP(
2044                            MBParam * const pParam,
2045                            FRAMEINFO * const frame,
2046    
2047                            // forward (past) reference
2048                            const MACROBLOCK * const f_mbs,
2049                        const IMAGE * const f_ref,
2050                            const IMAGE * const f_refH,
2051                        const IMAGE * const f_refV,
2052                            const IMAGE * const f_refHV,
2053                            // backward (future) reference
2054                            const MACROBLOCK * const b_mbs,
2055                        const IMAGE * const b_ref,
2056                            const IMAGE * const b_refH,
2057                        const IMAGE * const b_refV,
2058                            const IMAGE * const b_refHV)
2059    {
2060        const uint32_t mb_width = pParam->mb_width;
2061        const uint32_t mb_height = pParam->mb_height;
2062            const int32_t edged_width = pParam->edged_width;
2063    
2064            uint32_t i,j;
2065    
2066            int32_t f_sad16;
2067            int32_t b_sad16;
2068            int32_t i_sad16;
2069            int32_t d_sad16;
2070            int32_t best_sad;
2071    
2072            VECTOR pmv_dontcare;
2073    
2074            // note: i==horizontal, j==vertical
2075        for (j = 0; j < mb_height; j++)
2076            {
2077                    for (i = 0; i < mb_width; i++)
2078                    {
2079                            MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2080                            const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2081                            const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2082    
2083                            if (b_mb->mode == MODE_INTER
2084                                    && b_mb->cbp == 0
2085                                    && b_mb->mvs[0].x == 0
2086                                    && b_mb->mvs[0].y == 0)
2087                            {
2088                                    mb->mode = MODE_NOT_CODED;
2089                                    mb->mvs[0].x = 0;
2090                                    mb->mvs[0].y = 0;
2091                                    mb->b_mvs[0].x = 0;
2092                                    mb->b_mvs[0].y = 0;
2093                                    continue;
2094                            }
2095    
2096    
2097                            // forward search
2098                            f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2099                                                    &frame->image,
2100                                                    i, j,
2101                                                    frame->motion_flags,  frame->quant, frame->fcode,
2102                                                    pParam,
2103                                                    f_mbs, f_mbs /* todo */,
2104                                                    &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2105    
2106                            // backward search
2107                            b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2108                                                    &frame->image,
2109                                                    i, j,
2110                                                    frame->motion_flags,  frame->quant, frame->bcode,
2111                                                    pParam,
2112                                                    b_mbs, b_mbs, /* todo */
2113                                                    &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2114    
2115                            // interpolate search (simple, but effective)
2116                            i_sad16 = sad16bi_c(
2117                                            frame->image.y + i*16 + j*16*edged_width,
2118                                            get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2119                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),
2120                                            get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2121                                                    i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),
2122                                            edged_width);
2123    
2124                            // TODO: direct search
2125                            // predictor + range of [-32,32]
2126                            d_sad16 = 65535;
2127    
2128    
2129                            if (f_sad16 < b_sad16)
2130                            {
2131                                    best_sad = f_sad16;
2132                                    mb->mode = MODE_FORWARD;
2133                            }
2134                            else
2135                            {
2136                                    best_sad = b_sad16;
2137                                    mb->mode = MODE_BACKWARD;
2138                            }
2139    
2140                            if (i_sad16 < best_sad)
2141                            {
2142                                    best_sad = i_sad16;
2143                                    mb->mode = MODE_INTERPOLATE;
2144                            }
2145    
2146                            if (d_sad16 < best_sad)
2147                            {
2148                                    best_sad = d_sad16;
2149                                    mb->mode = MODE_DIRECT;
2150                            }
2151    
2152                    }
2153            }
2154    }

Legend:
Removed from v.117  
changed lines
  Added in v.152

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