[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 115, Thu Apr 11 10:18:40 2002 UTC revision 172, Sat May 11 15:32:59 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 MV16_INTER_BIAS 512
64    
65  /* Parameters which control inter/inter4v decision */  /* Parameters which control inter/inter4v decision */
66  #define IMV16X16                        5  #define IMV16X16                        5
# Line 63  Line 69 
69  #define NEIGH_TEND_16X16        2  #define NEIGH_TEND_16X16        2
70  #define NEIGH_TEND_8X8          2  #define NEIGH_TEND_8X8          2
71    
   
72  // fast ((A)/2)*2  // fast ((A)/2)*2
73  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
74    
75    #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )
76  #define MIN(X, Y) ((X)<(Y)?(X):(Y))  #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )
 #define MAX(X, Y) ((X)>(Y)?(X):(Y))  
 #define ABS(X)    (((X)>0)?(X):-(X))  
 #define SIGN(X)   (((X)>0)?1:-1)  
77    
78  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
79                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
# Line 81  Line 83 
83                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
84                                          const int x, const int y,                                          const int x, const int y,
85                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
86                                            const uint32_t iQuant,
87                                            const uint32_t iFcode,
88                                          const MBParam * const pParam,                                          const MBParam * const pParam,
89                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
90                                            const MACROBLOCK * const prevMBs,
91                                          VECTOR * const currMV,                                          VECTOR * const currMV,
92                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
93    
# Line 94  Line 99 
99                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
100                                          const int x, const int y,                                          const int x, const int y,
101                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
102                                            const uint32_t iQuant,
103                                            const uint32_t iFcode,
104                                          const MBParam * const pParam,                                          const MBParam * const pParam,
105                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
106                                            const MACROBLOCK * const prevMBs,
107                                          VECTOR * const currMV,                                          VECTOR * const currMV,
108                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
109    
# Line 107  Line 115 
115                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
116                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
117                                          const int x, const int y,                                          const int x, const int y,
118                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
119                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
120                                            const uint32_t iQuant,
121                                            const uint32_t iFcode,
122                                          const MBParam * const pParam,                                          const MBParam * const pParam,
123                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
124                                            const MACROBLOCK * const prevMBs,
125                                          VECTOR * const currMV,                                          VECTOR * const currMV,
126                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
127    
# Line 121  Line 132 
132                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
133                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
134                                          const int x, const int y,                                          const int x, const int y,
135                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
136                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
137                                            const uint32_t iQuant,
138                                            const uint32_t iFcode,
139                                          const MBParam * const pParam,                                          const MBParam * const pParam,
140                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
141                                            const MACROBLOCK * const prevMBs,
142                                          VECTOR * const currMV,                                          VECTOR * const currMV,
143                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
144    
# Line 172  Line 186 
186    
187  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
188    
189    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
190            {     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),
191            (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),
192            (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),
193            (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),
194            (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),
195            (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),
196            (int)(36.4949+0.5)      };
197    
198    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
199    
200    
201    
202  // mv.length table  // mv.length table
203  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
204      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 207  Line 234 
234  }  }
235    
236    
237  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)
 {  
         return NEIGH_TEND_16X16 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));  
 }  
   
 static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode)  
   
238  {  {
239      return NEIGH_TEND_8X8 * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));          return NEIGH_TEND_16X16 * lambda_vec16[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
240  }  }
241    
242    static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
243    
   
   
 /* 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)  
244  {  {
245        return NEIGH_TEND_8X8 * lambda_vec8[iQuant] * (mv_bits(dx, iFcode) + mv_bits(dy, iFcode));
         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;  
         }  
   
246  }  }
247    
248    
 /* 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)  
 {  
249    
         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    
252  #ifndef SEARCH16  #ifndef SEARCH16
253  #define SEARCH16        PMVfastSearch16  #define SEARCH16        PMVfastSearch16
# Line 318  Line 261 
261  #endif  #endif
262    
263  bool MotionEstimation(  bool MotionEstimation(
         MACROBLOCK * const pMBs,  
264          MBParam * const pParam,          MBParam * const pParam,
265          const IMAGE * const pRef,          FRAMEINFO * const current,
266            FRAMEINFO * const reference,
267          const IMAGE * const pRefH,          const IMAGE * const pRefH,
268          const IMAGE * const pRefV,          const IMAGE * const pRefV,
269          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
270          const uint32_t iLimit)          const uint32_t iLimit)
271    
272  {  {
273          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
274          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
275            MACROBLOCK * const pMBs = current->mbs;
276            MACROBLOCK * const prevMBs = reference->mbs;    // previous frame
277    
278          uint32_t i, j, iIntra = 0;          const IMAGE * const pCurrent = &current->image;
279            const IMAGE * const pRef = &reference->image;
280    
281          VECTOR mv16;          const VECTOR zeroMV = {0,0};
         VECTOR pmv16;  
282    
283          int32_t sad8 = 0;          int32_t x, y;
284          int32_t sad16;          int32_t iIntra = 0;
285          int32_t deviation;          VECTOR pmv;
286    
287          if (sadInit);          if (sadInit)
288                  (*sadInit)();                  (*sadInit)();
289    
290          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
291          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++)
                 for (j = 0; j < iWcount; j++)  
292                  {                  {
293                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
   
                         sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                          j, i, pParam->motion_flags,  
                                          pParam, pMBs, &mv16, &pmv16);  
                         pMB->sad16=sad16;  
294    
295                            pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
296                                             x, y, current->motion_flags, current->quant, current->fcode,
297                                             pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
298                    }
299    
300                          /* decide: MODE_INTER or MODE_INTRA          for (y = 0; y < iHcount; y++)
301                             if (dev_intra < sad_inter - 2 * nb) use_intra                  for (x = 0; x < iWcount; x++)
302                          */                  {
303                            MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
304    
305                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
306                            {
307                                    int32_t deviation;
308                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
309                                                             pParam->edged_width);
310    
311                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
312                          {                          {
313                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
314                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;                                          pMB->mv16 = pMB->mvs[0] = pMB->mvs[1]
315                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                                   = pMB->mvs[2] = pMB->mvs[3] = zeroMV;
316                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1]
317                                                                 = pMB->sad8[2] = pMB->sad8[3] = 0;
318    
319                                  iIntra++;                                  iIntra++;
320                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 373  Line 322 
322    
323                                  continue;                                  continue;
324                          }                          }
   
                         if (pParam->global_flags & XVID_INTER4V)  
                         {  
                                 pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);  
   
                                 pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]);  
   
                                 pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]);  
   
                                 pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,  
                                                        2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);  
   
                                 sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];  
325                          }                          }
326    
327                            if ( (current->global_flags & XVID_INTER4V)
328                                    && (!(current->global_flags & XVID_LUMIMASKING)
329                                            || pMB->dquant == NO_CHANGE) )
330                            {
331                                    int32_t sad8 = 129; //IMV16X16 * current->quant;
332    
333                                    if (sad8 < pMB->sad16)
334                                    sad8 += pMB->sad8[0]
335                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
336                                                           2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
337                                                               current->motion_flags, current->quant, current->fcode,
338                                                           pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
339    
340                                    if (sad8 < pMB->sad16)
341                                    sad8 += pMB->sad8[1]
342                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
343                                   2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
344                                                    current->motion_flags, current->quant, current->fcode,
345                                                    pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
346    
347                                    if (sad8 < pMB->sad16)
348                                    sad8 += pMB->sad8[2]
349                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
350                                                    2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
351                                                    current->motion_flags, current->quant, current->fcode,
352                                                    pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
353    
354                                    if (sad8 < pMB->sad16)
355                                    sad8 += pMB->sad8[3]
356                                            = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
357                                                    2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
358                                                    current->motion_flags, current->quant, current->fcode,
359                                                    pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
360    
361                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
362                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
363                          */                          */
364    
365                          if (pMB->dquant == NO_CHANGE) {                                  if (sad8 < pMB->sad16)
366                                  if (((pParam->global_flags & XVID_INTER4V)==0) ||                                  {
                                     (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) {  
   
                                         sad8 = sad16;  
                                         pMB->mode = MODE_INTER;  
                                         pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;  
                                         pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;  
                                         pMB->pmvs[0].x = pmv16.x;  
                                         pMB->pmvs[0].y = pmv16.y;  
                                 }  
                                 else  
367                                          pMB->mode = MODE_INTER4V;                                          pMB->mode = MODE_INTER4V;
368                   pMB->sad8[0] *= 4;
369                                            pMB->sad8[1] *= 4;
370                                            pMB->sad8[2] *= 4;
371                                            pMB->sad8[3] *= 4;
372                                            continue;
373                          }                          }
374                          else                          }
375                          {  
                                 sad8 = sad16;  
376                                  pMB->mode = MODE_INTER;                                  pMB->mode = MODE_INTER;
377                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                          pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
378                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;           pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
379                                  pMB->pmvs[0].x = pmv16.x;  
380                                  pMB->pmvs[0].y = pmv16.y;                          if (current->global_flags & XVID_INTER4V)
381                            {       pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0);
382                                    // get_pmv has to be called again. inter4v changes predictors
383    
384                                    pMB->pmvs[0].x = pMB->mv16.x - pmv.x;
385                                    pMB->pmvs[0].y = pMB->mv16.y - pmv.y;
386                          }                          }
387                  }                  }
   
388          return 0;          return 0;
389  }  }
390    
 #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )  
   
 #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )  
   
   
391  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
392    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
393      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
394    { \    { \
395      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); \
396      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; \  
397      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
398      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
399  }  }
400    
401  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
402      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); \
403      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);\
404      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
405      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
406  }  }
# Line 457  Line 410 
410      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
411    { \    { \
412      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
413      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
414      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
415      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
416  }  }
# Line 467  Line 420 
420      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
421    { \    { \
422      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
423      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
424      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
425      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
426  }  }
# Line 477  Line 430 
430      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
431    { \    { \
432      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \      iSAD = sad16( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 16, X, Y, iEdgedWidth),iEdgedWidth, iMinSAD); \
433      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_16((X) - pmv[0].x, (Y) - pmv[0].y, (uint8_t)iFcode, iQuant);\
434      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
435      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
436  }  }
# Line 485  Line 438 
438    
439  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
440    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); \
441    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);\
442    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
443    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
444  }  }
# Line 493  Line 446 
446  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
447    { \    { \
448      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); \
449      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);\
450      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
451      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
452  }  }
# Line 503  Line 456 
456      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
457    { \    { \
458      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
459      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
460      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
461      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
462  }  }
# Line 513  Line 466 
466      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
467    { \    { \
468      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
469      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
470      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
471      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
472  }  }
# Line 523  Line 476 
476      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
477    { \    { \
478      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \      iSAD = sad8( cur, get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, (X), (Y), iEdgedWidth),iEdgedWidth); \
479      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode) * iQuant;\      iSAD += calc_delta_8((X)-pmv[0].x, (Y)-pmv[0].y, (uint8_t)iFcode, iQuant);\
480      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
481      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
482  }  }
# Line 538  Line 491 
491                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
492                                          const int x, const int y,                                          const int x, const int y,
493                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
494                                            const uint32_t iQuant,
495                                            const uint32_t iFcode,
496                                          MBParam * const pParam,                                          MBParam * const pParam,
497                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
498                                            const MACROBLOCK * const prevMBs,
499                                          VECTOR * const currMV,                                          VECTOR * const currMV,
500                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
501  {  {
502          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
503          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
504          int32_t iSAD;          int32_t iSAD;
505          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 866  Line 821 
821                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
822                                          const int x, const int y,                                          const int x, const int y,
823                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
824                                            const uint32_t iQuant,
825                                            const uint32_t iFcode,
826                                          const MBParam * const pParam,                                          const MBParam * const pParam,
827                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
828                                            const MACROBLOCK * const prevMBs,
829                                          VECTOR * const currMV,                                          VECTOR * const currMV,
830                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
831  {  {
832          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;  
833          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
834          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
835          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 895  Line 851 
851          VECTOR pmv[4];          VECTOR pmv[4];
852          int32_t psad[4];          int32_t psad[4];
853    
854          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
855            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
856    
857          static int32_t threshA,threshB;          static int32_t threshA,threshB;
858          int32_t bPredEq;          int32_t bPredEq;
# Line 934  Line 891 
891    
892          iFound=0;          iFound=0;
893    
 /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion  
    vector of the median.  
    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  
 */  
   
         if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )  
                 iFound=2;  
   
 /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  
    Otherwise select large Diamond Search.  
 */  
   
         if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536) || (bPredEq) )  
                 iDiamondSize=1; // halfpel!  
         else  
                 iDiamondSize=2; // halfpel!  
   
         if (!(MotionFlags & PMV_HALFPELDIAMOND16) )  
                 iDiamondSize*=2;  
   
894  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
895     MinSAD=SAD     MinSAD=SAD
896     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 961  Line 898 
898     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
899  */  */
900    
   
 // Prepare for main loop  
   
901          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
902          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
903          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 991  Line 925 
925          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
926                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
927                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
928          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);
929    
930          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
931            {
932                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
933                    {
934                            if (!MVzero(*currMV))
935          {          {
936                                    iMinSAD += MV16_00_BIAS;
937                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
938                                    iMinSAD -= MV16_00_BIAS;
939                            }
940                    }
941    
942                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
943                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1002  Line 945 
945                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
946          }          }
947    
948    
949    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
950       vector of the median.
951       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
952    */
953    
954            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
955                    iFound=2;
956    
957    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
958       Otherwise select large Diamond Search.
959    */
960    
961            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
962                    iDiamondSize=1; // halfpel!
963            else
964                    iDiamondSize=2; // halfpel!
965    
966            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
967                    iDiamondSize*=2;
968    
969  /*  /*
970     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.
971     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
972     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
973     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
974  */  */
975    
976  // (0,0) is always possible  // (0,0) is always possible
977    
978            if (!MVzero(pmv[0]))
979          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
980    
981  // previous frame MV is always possible  // previous frame MV is always possible
982          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
983            if (!MVzero(prevMB->mvs[0]))
984            if (!MVequal(prevMB->mvs[0],pmv[0]))
985                    CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
986    
987  // left neighbour, if allowed  // left neighbour, if allowed
988          if (x != 0)  
989            if (!MVzero(pmv[1]))
990            if (!MVequal(pmv[1],prevMB->mvs[0]))
991            if (!MVequal(pmv[1],pmv[0]))
992          {          {
993                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
994                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
995                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
996                  }                  }
997    
998                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
999          }          }
1000    
1001  // top neighbour, if allowed  // top neighbour, if allowed
1002          if (y != 0)          if (!MVzero(pmv[2]))
1003            if (!MVequal(pmv[2],prevMB->mvs[0]))
1004            if (!MVequal(pmv[2],pmv[0]))
1005            if (!MVequal(pmv[2],pmv[1]))
1006          {          {
1007                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1008                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1036  Line 1011 
1011                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1012    
1013  // top right neighbour, if allowed  // top right neighbour, if allowed
1014                  if (x != (iWcount-1))                  if (!MVzero(pmv[3]))
1015                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1016                    if (!MVequal(pmv[3],pmv[0]))
1017                    if (!MVequal(pmv[3],pmv[1]))
1018                    if (!MVequal(pmv[3],pmv[2]))
1019                  {                  {
1020                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1021                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1046  Line 1025 
1025                  }                  }
1026          }          }
1027    
1028            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1029                    iMinSAD -= MV16_00_BIAS;
1030    
1031    
1032  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1033     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.
1034  */  */
1035    
1036          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1037          {          {
1038                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1039                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1236  Line 1219 
1219                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1220                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1221                                          const int x, const int y,                                          const int x, const int y,
1222                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1223                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1224                                            const uint32_t iQuant,
1225                                            const uint32_t iFcode,
1226                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1227                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1228                                            const MACROBLOCK * const prevMBs,
1229                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1230                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1231  {  {
1232          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;  
1233          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1234          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1235          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1264  Line 1247 
1247          int32_t psad[4];          int32_t psad[4];
1248          VECTOR newMV;          VECTOR newMV;
1249          VECTOR backupMV;          VECTOR backupMV;
1250            VECTOR startMV;
1251    
1252          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1253            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1254    
1255          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1256          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1257          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1258    
1259          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1260    
1261            /* Init variables */
1262            startMV.x = start_x;
1263            startMV.y = start_y;
1264    
1265  /* Get maximum range */  /* Get maximum range */
1266          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1267                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1268    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1269          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1270          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1271          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1306  Line 1293 
1293    
1294          iFound=0;          iFound=0;
1295    
 /* Step 2: Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion  
    vector of the median.  
    If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2  
 */  
   
         if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )  
                 iFound=2;  
   
 /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  
    Otherwise select large Diamond Search.  
 */  
   
         if ( (pmv[0].x != 0) || (pmv[0].y != 0) || (threshB<1536/4) || (bPredEq) )  
                 iDiamondSize=1; // 1 halfpel!  
         else  
                 iDiamondSize=2; // 2 halfpel = 1 full pixel!  
   
         if (!(MotionFlags & PMV_HALFPELDIAMOND8) )  
                 iDiamondSize*=2;  
   
1296  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1297     MinSAD=SAD     MinSAD=SAD
1298     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1336  Line 1303 
1303    
1304  // Prepare for main loop  // Prepare for main loop
1305    
1306          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1307    
1308          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1309                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1310                          iEdgedWidth);                          iEdgedWidth);
1311          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);
1312    
1313          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1314                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1315          {          {
1316                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1317                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1352  Line 1319 
1319                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1320          }          }
1321    
1322    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1323       vector of the median.
1324       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1325    */
1326    
1327            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1328                    iFound=2;
1329    
1330    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1331       Otherwise select large Diamond Search.
1332    */
1333    
1334            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1335                    iDiamondSize=1; // 1 halfpel!
1336            else
1337                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1338    
1339            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1340                    iDiamondSize*=2;
1341    
1342    
1343  /*  /*
1344     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.
1345     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1346     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1347     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1348  */  */
1349    
1350  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1351    
1352            if (!MVequal(pmv[0],startMV))
1353          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1354    
1355  // (0,0) is always possible  // (0,0) if needed
1356            if (!MVzero(pmv[0]))
1357            if (!MVzero(startMV))
1358          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1359    
1360  // previous frame MV is always possible  // previous frame MV if needed
1361          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1362            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1363            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1364            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1365    
1366  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1367          if (psad[1] != MV_MAX_ERROR)          {
1368                    if (MotionFlags & PMV_QUICKSTOP16)
1369                            goto PMVfast8_Terminate_without_Refine;
1370                    if (MotionFlags & PMV_EARLYSTOP16)
1371                            goto PMVfast8_Terminate_with_Refine;
1372            }
1373    
1374    
1375    // left neighbour, if allowed and needed
1376            if (!MVzero(pmv[1]))
1377            if (!MVequal(pmv[1],startMV))
1378            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1379            if (!MVequal(pmv[1],pmv[0]))
1380          {          {
1381                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1382                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1379  Line 1385 
1385                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1386          }          }
1387    
1388  // top neighbour, if allowed  // top neighbour, if allowed and needed
1389          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1390            if (!MVequal(pmv[2],startMV))
1391            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1392            if (!MVequal(pmv[2],pmv[0]))
1393            if (!MVequal(pmv[2],pmv[1]))
1394          {          {
1395                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1396                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1388  Line 1398 
1398                  }                  }
1399                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1400    
1401  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1402                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1403            if (!MVequal(pmv[3],startMV))
1404            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1405            if (!MVequal(pmv[3],pmv[0]))
1406            if (!MVequal(pmv[3],pmv[1]))
1407            if (!MVequal(pmv[3],pmv[2]))
1408                  {                  {
1409                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1410                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1399  Line 1414 
1414                  }                  }
1415          }          }
1416    
1417            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1418                    iMinSAD -= MV8_00_BIAS;
1419    
1420    
1421  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1422     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.
1423  */  */
1424    
1425          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]) ) )
1426          {          {
1427                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1428                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1493  Line 1512 
1512                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1513                                          const int x, const int y,                                          const int x, const int y,
1514                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1515                                            const uint32_t iQuant,
1516                                            const uint32_t iFcode,
1517                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1518                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1519                                            const MACROBLOCK * const prevMBs,
1520                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1521                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1522  {  {
1523          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
1524          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;  
1525    
1526          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1527          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1521  Line 1541 
1541          int32_t psad[8];          int32_t psad[8];
1542    
1543          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1544          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1545            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1546          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1547    
1548          static int32_t thresh2;          static int32_t thresh2;
# Line 1531  Line 1552 
1552          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1553    
1554          if (oldMBs == NULL)          if (oldMBs == NULL)
1555          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1556                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1557          }          }
1558          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1559    
# Line 1540  Line 1561 
1561          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1562                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1563    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1564          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1565          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1566            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1581  Line 1600 
1600          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1601                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1602                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1603          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);
1604    
1605  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1606          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1607                  {                  {
1608                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1609                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1595  Line 1614 
1614  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1615    
1616  // previous frame MV  // previous frame MV
1617          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1618    
1619  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1620  // 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 1655 
1655                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1656    
1657  // top right neighbour, if allowed  // top right neighbour, if allowed
1658                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1659                  {                  {
1660                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1661                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1651  Line 1670 
1670  */  */
1671    
1672          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1673                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1674                  {                  {
1675                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1676                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1661  Line 1680 
1680    
1681  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1682    
1683          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1684          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1685          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1686    
1687          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1688    
1689  // left neighbour  // left neighbour
1690          if (x != 0)          if (x != 0)
1691                  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);
1692    
1693  // top neighbour  // top neighbour
1694          if (y != 0)          if (y != 0)
1695                  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);
1696    
1697  // 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
1698    
1699          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1700                  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);
1701    
1702  // bottom neighbour, dito  // bottom neighbour, dito
1703          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1704                  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);
1705    
1706  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1707          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1739  Line 1758 
1758                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1759                                  x, y,                                  x, y,
1760                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1761                          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);
1762    
1763                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1764                          {                          {
# Line 1760  Line 1779 
1779    
1780  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1781    
1782          *oldMB = *pMB;          *oldMB = *prevMB;
1783    
1784          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1785          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1777  Line 1796 
1796                                          const int x, const int y,                                          const int x, const int y,
1797                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1798                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1799                                            const uint32_t iQuant,
1800                                            const uint32_t iFcode,
1801                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1802                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1803                                            const MACROBLOCK * const prevMBs,
1804                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1805                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1806  {  {
1807          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;  
1808    
1809            const uint32_t iWcount = pParam->mb_width;
1810          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1811          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1812          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1807  Line 1828 
1828    
1829          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1830    
1831          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1832            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1833    
1834          int32_t bPredEq;          int32_t bPredEq;
1835          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1861  Line 1883 
1883          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1884                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1885                  iEdgedWidth);                  iEdgedWidth);
1886          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);
1887    
1888    
1889  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1897 
1897    
1898  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1899    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1900    
1901  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1902          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1903    
1904    // previous frame MV
1905            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1906    
1907    // left neighbour, if allowed
1908            if (psad[1] != MV_MAX_ERROR)
1909            {
1910                    if (!(MotionFlags & PMV_HALFPEL8 ))
1911                    {       pmv[1].x = EVEN(pmv[1].x);
1912                            pmv[1].y = EVEN(pmv[1].y);
1913                    }
1914                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1915            }
1916    
1917    // top neighbour, if allowed
1918            if (psad[2] != MV_MAX_ERROR)
1919            {
1920                    if (!(MotionFlags & PMV_HALFPEL8 ))
1921                    {       pmv[2].x = EVEN(pmv[2].x);
1922                            pmv[2].y = EVEN(pmv[2].y);
1923                    }
1924                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1925    
1926    // top right neighbour, if allowed
1927                    if (psad[3] != MV_MAX_ERROR)
1928                    {
1929                            if (!(MotionFlags & PMV_HALFPEL8 ))
1930                            {       pmv[3].x = EVEN(pmv[3].x);
1931                                    pmv[3].y = EVEN(pmv[3].y);
1932                            }
1933                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1934                    }
1935            }
1936    
1937    /*  // this bias is zero anyway, at the moment!
1938    
1939            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1940                    iMinSAD -= MV8_00_BIAS;
1941    
1942    */
1943    
1944  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1945     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]
1946  */  */
# Line 1894  Line 1953 
1953                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1954                  }                  }
1955    
1956  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1957    
1958          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1959    
1960          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1961                  iDiamondSize *= 2;                  iDiamondSize *= 2;
1962    
1963  /* 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 */
1964    
1965    /* // there is no EPZS^2 for inter4v at the moment
1966    
1967            if (MotionFlags & PMV_USESQUARES8)
1968                    EPZSMainSearchPtr = Square8_MainSearch;
1969            else
1970    */
1971    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
1972                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
1973    
1974          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1975                  x, y,                  x, y,
1976                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
1977                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
1978                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
1979    
1980    
1981          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1970  Line 2033 
2033          return iMinSAD;          return iMinSAD;
2034  }  }
2035    
2036    
2037    
2038    
2039    
2040    /* ***********************************************************
2041            bvop motion estimation
2042    // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2043    ***************************************************************/
2044    
2045    
2046    void MotionEstimationBVOP(
2047                            MBParam * const pParam,
2048                            FRAMEINFO * const frame,
2049    
2050                            // forward (past) reference
2051                            const MACROBLOCK * const f_mbs,
2052                        const IMAGE * const f_ref,
2053                            const IMAGE * const f_refH,
2054                        const IMAGE * const f_refV,
2055                            const IMAGE * const f_refHV,
2056                            // backward (future) reference
2057                            const MACROBLOCK * const b_mbs,
2058                        const IMAGE * const b_ref,
2059                            const IMAGE * const b_refH,
2060                        const IMAGE * const b_refV,
2061                            const IMAGE * const b_refHV)
2062    {
2063        const uint32_t mb_width = pParam->mb_width;
2064        const uint32_t mb_height = pParam->mb_height;
2065            const int32_t edged_width = pParam->edged_width;
2066    
2067            uint32_t i,j;
2068    
2069            int32_t f_sad16;
2070            int32_t b_sad16;
2071            int32_t i_sad16;
2072            int32_t d_sad16;
2073            int32_t best_sad;
2074    
2075            VECTOR pmv_dontcare;
2076    
2077            // note: i==horizontal, j==vertical
2078        for (j = 0; j < mb_height; j++)
2079            {
2080                    for (i = 0; i < mb_width; i++)
2081                    {
2082                            MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2083                            const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2084                            const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2085    
2086                            if (b_mb->mode == MODE_INTER
2087                                    && b_mb->cbp == 0
2088                                    && b_mb->mvs[0].x == 0
2089                                    && b_mb->mvs[0].y == 0)
2090                            {
2091                                    mb->mode = MODE_NOT_CODED;
2092                                    mb->mvs[0].x = 0;
2093                                    mb->mvs[0].y = 0;
2094                                    mb->b_mvs[0].x = 0;
2095                                    mb->b_mvs[0].y = 0;
2096                                    continue;
2097                            }
2098    
2099    
2100                            // forward search
2101                            f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2102                                                    &frame->image,
2103                                                    i, j,
2104                                                    frame->motion_flags,  frame->quant, frame->fcode,
2105                                                    pParam,
2106                                                    f_mbs, f_mbs /* todo */,
2107                                                    &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2108    
2109                            // backward search
2110                            b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2111                                                    &frame->image,
2112                                                    i, j,
2113                                                    frame->motion_flags,  frame->quant, frame->bcode,
2114                                                    pParam,
2115                                                    b_mbs, b_mbs, /* todo */
2116                                                    &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2117    
2118                            // interpolate search (simple, but effective)
2119                            i_sad16 = sad16bi_c(
2120                                            frame->image.y + i*16 + j*16*edged_width,
2121                                            get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2122                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),
2123                                            get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2124                                                    i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),
2125                                            edged_width);
2126    
2127                            // TODO: direct search
2128                            // predictor + range of [-32,32]
2129                            d_sad16 = 65535;
2130    
2131    
2132                            if (f_sad16 < b_sad16)
2133                            {
2134                                    best_sad = f_sad16;
2135                                    mb->mode = MODE_FORWARD;
2136                            }
2137                            else
2138                            {
2139                                    best_sad = b_sad16;
2140                                    mb->mode = MODE_BACKWARD;
2141                            }
2142    
2143                            if (i_sad16 < best_sad)
2144                            {
2145                                    best_sad = i_sad16;
2146                                    mb->mode = MODE_INTERPOLATE;
2147                            }
2148    
2149                            if (d_sad16 < best_sad)
2150                            {
2151                                    best_sad = d_sad16;
2152                                    mb->mode = MODE_DIRECT;
2153                            }
2154    
2155                    }
2156            }
2157    }

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

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