[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 175, Sun May 12 17:21:30 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 49  Line 54 
54  #define MV16_THRESHOLD  192  #define MV16_THRESHOLD  192
55  #define MV8_THRESHOLD   56  #define MV8_THRESHOLD   56
56    
57    #define NEIGH_MOVE_THRESH 0
58    // how much a block's MV must differ from his neighbour
59    // to be search for INTER4V. The more, the faster...
60    
61  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
62  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
63  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
64    #define MV8_00_BIAS     (0)
65    
66  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
67  #define INTER_BIAS      512  #define MV16_INTER_BIAS 512
68    
69  /* Parameters which control inter/inter4v decision */  /* Parameters which control inter/inter4v decision */
70  #define IMV16X16                        5  #define IMV16X16                        5
# Line 63  Line 73 
73  #define NEIGH_TEND_16X16        2  #define NEIGH_TEND_16X16        2
74  #define NEIGH_TEND_8X8          2  #define NEIGH_TEND_8X8          2
75    
   
76  // fast ((A)/2)*2  // fast ((A)/2)*2
77  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
78    
79    #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )
80  #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)  
81    
82  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
83                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
# Line 81  Line 87 
87                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
88                                          const int x, const int y,                                          const int x, const int y,
89                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
90                                            const uint32_t iQuant,
91                                            const uint32_t iFcode,
92                                          const MBParam * const pParam,                                          const MBParam * const pParam,
93                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
94                                            const MACROBLOCK * const prevMBs,
95                                          VECTOR * const currMV,                                          VECTOR * const currMV,
96                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
97    
# Line 94  Line 103 
103                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
104                                          const int x, const int y,                                          const int x, const int y,
105                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
106                                            const uint32_t iQuant,
107                                            const uint32_t iFcode,
108                                          const MBParam * const pParam,                                          const MBParam * const pParam,
109                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
110                                            const MACROBLOCK * const prevMBs,
111                                          VECTOR * const currMV,                                          VECTOR * const currMV,
112                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
113    
# Line 107  Line 119 
119                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
120                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
121                                          const int x, const int y,                                          const int x, const int y,
122                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
123                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
124                                            const uint32_t iQuant,
125                                            const uint32_t iFcode,
126                                          const MBParam * const pParam,                                          const MBParam * const pParam,
127                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
128                                            const MACROBLOCK * const prevMBs,
129                                          VECTOR * const currMV,                                          VECTOR * const currMV,
130                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
131    
# Line 121  Line 136 
136                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
137                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
138                                          const int x, const int y,                                          const int x, const int y,
139                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
140                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
141                                            const uint32_t iQuant,
142                                            const uint32_t iFcode,
143                                          const MBParam * const pParam,                                          const MBParam * const pParam,
144                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
145                                            const MACROBLOCK * const prevMBs,
146                                          VECTOR * const currMV,                                          VECTOR * const currMV,
147                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
148    
# Line 172  Line 190 
190    
191  typedef MainSearch8Func* MainSearch8FuncPtr;  typedef MainSearch8Func* MainSearch8FuncPtr;
192    
193    static int32_t lambda_vec16[32] =  /* rounded values for lambda param for weight of motion bits as in modified H.26L */
194            {     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),
195            (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),
196            (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),
197            (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),
198            (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),
199            (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),
200            (int)(36.4949+0.5)      };
201    
202    static int32_t *lambda_vec8 = lambda_vec16;     /* same table for INTER and INTER4V for now*/
203    
204    
205    
206  // mv.length table  // mv.length table
207  static const uint32_t mvtab[33] = {  static const uint32_t mvtab[33] = {
208      1,  2,  3,  4,  6,  7,  7,  7,      1,  2,  3,  4,  6,  7,  7,  7,
# Line 207  Line 238 
238  }  }
239    
240    
241  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)  
   
242  {  {
243      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));
244  }  }
245    
246    static __inline uint32_t calc_delta_8(const int32_t dx, const int32_t dy, const uint32_t iFcode, const uint32_t iQuant)
247    
   
   
 /* 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)  
248  {  {
249        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;  
         }  
   
250  }  }
251    
252    
 /* 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)  
 {  
253    
         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;  
         }  
254    
 }  
255    
256  #ifndef SEARCH16  #ifndef SEARCH16
257  #define SEARCH16        PMVfastSearch16  #define SEARCH16        PMVfastSearch16
# Line 318  Line 265 
265  #endif  #endif
266    
267  bool MotionEstimation(  bool MotionEstimation(
         MACROBLOCK * const pMBs,  
268          MBParam * const pParam,          MBParam * const pParam,
269          const IMAGE * const pRef,          FRAMEINFO * const current,
270            FRAMEINFO * const reference,
271          const IMAGE * const pRefH,          const IMAGE * const pRefH,
272          const IMAGE * const pRefV,          const IMAGE * const pRefV,
273          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
274          const uint32_t iLimit)          const uint32_t iLimit)
275    
276  {  {
277          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
278          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
279            MACROBLOCK * const pMBs = current->mbs;
280            MACROBLOCK * const prevMBs = reference->mbs;    // previous frame
281    
282          uint32_t i, j, iIntra = 0;          const IMAGE * const pCurrent = &current->image;
283            const IMAGE * const pRef = &reference->image;
284    
285          VECTOR mv16;          const VECTOR zeroMV = {0,0};
         VECTOR pmv16;  
286    
287          int32_t sad8 = 0;          int32_t x, y;
288          int32_t sad16;          int32_t iIntra = 0;
289          int32_t deviation;          VECTOR pmv;
290    
291          if (sadInit)          if (sadInit)
292                  (*sadInit)();                  (*sadInit)();
293    
294          // note: i==horizontal, j==vertical          for (y = 0; y < iHcount; y++)
295          for (i = 0; i < iHcount; i++)                  for (x = 0; x < iWcount; x++)
                 for (j = 0; j < iWcount; j++)  
296                  {                  {
297                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
298    
299                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                          pMB->sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
300                                           j, i, pParam->motion_flags,                                           x, y, current->motion_flags, current->quant, current->fcode,
301                                           pParam, pMBs, &mv16, &pmv16);                                           pParam, pMBs, prevMBs, &pMB->mv16, &pMB->pmvs[0]);
                         pMB->sad16=sad16;  
302    
303    
304                          /* decide: MODE_INTER or MODE_INTRA                          if (0 < (pMB->sad16 - MV16_INTER_BIAS))
305                             if (dev_intra < sad_inter - 2 * nb) use_intra                          {
306                          */                                  int32_t deviation;
307                                    deviation = dev16(pCurrent->y + x*16 + y*16*pParam->edged_width,
308                          deviation = dev16(pCurrent->y + j*16 + i*16*pParam->edged_width, pParam->edged_width);                                                           pParam->edged_width);
309    
310                          if (deviation < (sad16 - INTER_BIAS))                                  if (deviation < (pMB->sad16 - MV16_INTER_BIAS))
311                          {                          {
312                                  pMB->mode = MODE_INTRA;                                  pMB->mode = MODE_INTRA;
313                                  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]
314                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                                                   = pMB->mvs[2] = pMB->mvs[3] = zeroMV;
315                                            pMB->sad16 = pMB->sad8[0] = pMB->sad8[1]
316                                                                 = pMB->sad8[2] = pMB->sad8[3] = 0;
317    
318                                  iIntra++;                                  iIntra++;
319                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
# Line 373  Line 321 
321    
322                                  continue;                                  continue;
323                          }                          }
324                            }
325                            pMB->mode = MODE_INTER;
326                            pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
327               pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = pMB->sad16;
328                    }
329    
330                          if (pParam->global_flags & XVID_INTER4V)          // we try to do as few INTER4V-searches as possible. So we split ME in two parts, normal
331                          {          // SEARCH16 and only for special blocks SEARCH8. May this should be modified for quality
332                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,          // levels.
                                                        2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,  
                                                        pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);  
333    
                                 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]);  
334    
                                 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]);  
335    
336                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,          if (current->global_flags & XVID_INTER4V)
337                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                  for (y = 0; y < iHcount; y++)
338                                                         pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);                          for (x = 0; x < iWcount; x++)
339                            {
340                                    MACROBLOCK* const pMB = &pMBs[x + y * iWcount];
341    
342                                  sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];                                  if (pMB->mode == MODE_INTRA)
343                          }                                          continue;
344    
345    
346                                    if ( (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE) )
347                                    {
348                                    int32_t neigh=0;
349    
350                                    if (x>0)
351                                    {       neigh += abs((pMB->mv16.x)-((pMB-1)->mv16.x));
352                                            neigh += abs((pMB->mv16.y)-((pMB-1)->mv16.y));
353                                    }
354                                    if (y>0)
355                                    {       neigh += abs((pMB->mv16.x)-((pMB-iWcount)->mv16.x));
356                                            neigh += abs((pMB->mv16.y)-((pMB-iWcount)->mv16.y));
357                                    }
358                                    if (x<(iWcount-1))
359                                    {       neigh += abs((pMB->mv16.x)-((pMB+1)->mv16.x));
360                                            neigh += abs((pMB->mv16.y)-((pMB+1)->mv16.y));
361                                    }
362                                    if (y<(iHcount-1))
363                                    {       neigh += abs((pMB->mv16.x)-((pMB+iHcount)->mv16.x));
364                                            neigh += abs((pMB->mv16.y)-((pMB+iHcount)->mv16.y));
365                                    }
366    
367                                    if (neigh > NEIGH_MOVE_THRESH)
368                                    {
369                                            int32_t sad8 = IMV16X16 * current->quant;
370    
371                                            if (sad8 < pMB->sad16)
372                                            sad8 += pMB->sad8[0]
373                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
374                                                                   2*x, 2*y, pMB->mv16.x, pMB->mv16.y,
375                                                                       current->motion_flags, current->quant, current->fcode,
376                                                                   pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
377    
378                                            if (sad8 < pMB->sad16)
379                                            sad8 += pMB->sad8[1]
380                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
381                                           2*x+1, 2*y, pMB->mv16.x, pMB->mv16.y,
382                                                            current->motion_flags, current->quant, current->fcode,
383                                                            pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
384    
385                                            if (sad8 < pMB->sad16)
386                                            sad8 += pMB->sad8[2]
387                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
388                                                            2*x, 2*y+1, pMB->mv16.x, pMB->mv16.y,
389                                                            current->motion_flags, current->quant, current->fcode,
390                                                            pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
391    
392                                            if (sad8 < pMB->sad16)
393                                            sad8 += pMB->sad8[3]
394                                                    = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
395                                                            2*x+1, 2*y+1, pMB->mv16.x, pMB->mv16.y,
396                                                            current->motion_flags, current->quant, current->fcode,
397                                                            pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
398    
399                          /* decide: MODE_INTER or MODE_INTER4V                          /* decide: MODE_INTER or MODE_INTER4V
400                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < pMB->sad16 - nb/2+1) use_inter4v
401                          */                          */
402    
403                          if (pMB->dquant == NO_CHANGE) {                                          if (sad8 < pMB->sad16)
                                 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  
                                         pMB->mode = MODE_INTER4V;  
                         }  
                         else  
404                          {                          {
405                                  sad8 = sad16;                                                  pMB->mode = MODE_INTER4V;
406                                  pMB->mode = MODE_INTER;                        pMB->sad8[0] *= 4;
407                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = mv16.x;                                                  pMB->sad8[1] *= 4;
408                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = mv16.y;                                                  pMB->sad8[2] *= 4;
409                                  pMB->pmvs[0].x = pmv16.x;                                                  pMB->sad8[3] *= 4;
410                                  pMB->pmvs[0].y = pmv16.y;                                                  continue;
411                          }                          }
412    
413                                            pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->mv16;
414                  }                  }
415    
         return 0;  
416  }  }
417    
418  #define MVzero(A) ( ((A).x)==(0) && ((A).y)==(0) )                  // get_pmv has to be called again, because inter4v changes predictors
419    
420  #define MVequal(A,B) ( ((A).x)==((B).x) && ((A).y)==((B).y) )                          pmv = get_pmv(pMBs, x, y, pParam->mb_width, 0);
421                            pMB->pmvs[0].x = pMB->mv16.x - pmv.x;   /* the other pmvs are only needed in INTER4V-mode */
422                            pMB->pmvs[0].y = pMB->mv16.y - pmv.y;
423    
424                            }
425    
426            return 0;
427    }
428    
429  #define CHECK_MV16_ZERO {\  #define CHECK_MV16_ZERO {\
430    if ( (0 <= max_dx) && (0 >= min_dx) \    if ( (0 <= max_dx) && (0 >= min_dx) \
431      && (0 <= max_dy) && (0 >= min_dy) ) \      && (0 <= max_dy) && (0 >= min_dy) ) \
432    { \    { \
433      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); \
434      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; \  
435      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
436      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \      {  iMinSAD=iSAD; currMV->x=0; currMV->y=0; }  }     \
437  }  }
438    
439  #define NOCHECK_MV16_CANDIDATE(X,Y) { \  #define NOCHECK_MV16_CANDIDATE(X,Y) { \
440      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); \
441      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);\
442      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
443      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
444  }  }
# Line 457  Line 448 
448      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
449    { \    { \
450      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); \
451      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);\
452      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
453      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
454  }  }
# Line 467  Line 458 
458      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
459    { \    { \
460      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); \
461      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);\
462      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
463      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
464  }  }
# Line 477  Line 468 
468      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
469    { \    { \
470      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); \
471      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);\
472      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
473      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
474  }  }
# Line 485  Line 476 
476    
477  #define CHECK_MV8_ZERO {\  #define CHECK_MV8_ZERO {\
478    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); \
479    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);\
480    if (iSAD < iMinSAD) \    if (iSAD < iMinSAD) \
481    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \    { iMinSAD=iSAD; currMV->x=0; currMV->y=0; } \
482  }  }
# Line 493  Line 484 
484  #define NOCHECK_MV8_CANDIDATE(X,Y) \  #define NOCHECK_MV8_CANDIDATE(X,Y) \
485    { \    { \
486      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); \
487      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);\
488      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
489      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } \
490  }  }
# Line 503  Line 494 
494      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
495    { \    { \
496      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); \
497      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);\
498      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
499      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); } } \
500  }  }
# Line 513  Line 504 
504      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
505    { \    { \
506      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); \
507      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);\
508      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
509      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); } } \
510  }  }
# Line 523  Line 514 
514      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \      && ((Y) <= max_dy) && ((Y) >= min_dy) ) \
515    { \    { \
516      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); \
517      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);\
518      if (iSAD < iMinSAD) \      if (iSAD < iMinSAD) \
519      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \      {  iMinSAD=iSAD; currMV->x=(X); currMV->y=(Y); iDirection=(D); iFound=0; } } \
520  }  }
# Line 538  Line 529 
529                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
530                                          const int x, const int y,                                          const int x, const int y,
531                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
532                                            const uint32_t iQuant,
533                                            const uint32_t iFcode,
534                                          MBParam * const pParam,                                          MBParam * const pParam,
535                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
536                                            const MACROBLOCK * const prevMBs,
537                                          VECTOR * const currMV,                                          VECTOR * const currMV,
538                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
539  {  {
540          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
         const int32_t iQuant = pParam->quant;  
541          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;          const uint8_t * cur = pCur->y + x*16 + y*16*iEdgedWidth;
542          int32_t iSAD;          int32_t iSAD;
543          int32_t pred_x,pred_y;          int32_t pred_x,pred_y;
# Line 866  Line 859 
859                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
860                                          const int x, const int y,                                          const int x, const int y,
861                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
862                                            const uint32_t iQuant,
863                                            const uint32_t iFcode,
864                                          const MBParam * const pParam,                                          const MBParam * const pParam,
865                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
866                                            const MACROBLOCK * const prevMBs,
867                                          VECTOR * const currMV,                                          VECTOR * const currMV,
868                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
869  {  {
870          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;  
871          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
872          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
873          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 895  Line 889 
889          VECTOR pmv[4];          VECTOR pmv[4];
890          int32_t psad[4];          int32_t psad[4];
891    
892          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
893            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
894    
895          static int32_t threshA,threshB;          static int32_t threshA,threshB;
896          int32_t bPredEq;          int32_t bPredEq;
# Line 934  Line 929 
929    
930          iFound=0;          iFound=0;
931    
 /* 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;  
   
932  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
933     MinSAD=SAD     MinSAD=SAD
934     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 961  Line 936 
936     If SAD<=256 goto Step 10.     If SAD<=256 goto Step 10.
937  */  */
938    
   
 // Prepare for main loop  
   
939          *currMV=pmv[0];         /* current best := prediction */          *currMV=pmv[0];         /* current best := prediction */
940          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
941          {       /* This should NOT be necessary! */          {       /* This should NOT be necessary! */
# Line 991  Line 963 
963          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
964                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                           get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
965                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
966          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);
967    
968          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
969            {
970                    if (iMinSAD < 2*iQuant) // high chances for SKIP-mode
971          {          {
972                            if (!MVzero(*currMV))
973                            {
974                                    iMinSAD += MV16_00_BIAS;
975                                    CHECK_MV16_ZERO;                // (0,0) saves space for letterboxed pictures
976                                    iMinSAD -= MV16_00_BIAS;
977                            }
978                    }
979    
980                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
981                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1002  Line 983 
983                          goto PMVfast16_Terminate_with_Refine;                          goto PMVfast16_Terminate_with_Refine;
984          }          }
985    
986    
987    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
988       vector of the median.
989       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
990    */
991    
992            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
993                    iFound=2;
994    
995    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
996       Otherwise select large Diamond Search.
997    */
998    
999            if ( (!MVzero(pmv[0])) || (threshB<1536) || (bPredEq) )
1000                    iDiamondSize=1; // halfpel!
1001            else
1002                    iDiamondSize=2; // halfpel!
1003    
1004            if (!(MotionFlags & PMV_HALFPELDIAMOND16) )
1005                    iDiamondSize*=2;
1006    
1007  /*  /*
1008     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.
1009     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1010     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1011     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1012  */  */
1013    
1014  // (0,0) is always possible  // (0,0) is always possible
1015    
1016            if (!MVzero(pmv[0]))
1017          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1018    
1019  // previous frame MV is always possible  // previous frame MV is always possible
1020          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1021            if (!MVzero(prevMB->mvs[0]))
1022            if (!MVequal(prevMB->mvs[0],pmv[0]))
1023                    CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1024    
1025  // left neighbour, if allowed  // left neighbour, if allowed
1026          if (x != 0)  
1027            if (!MVzero(pmv[1]))
1028            if (!MVequal(pmv[1],prevMB->mvs[0]))
1029            if (!MVequal(pmv[1],pmv[0]))
1030          {          {
1031                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1032                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
1033                  pmv[1].y = EVEN(pmv[1].y);                  pmv[1].y = EVEN(pmv[1].y);
1034                  }                  }
1035    
1036                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV16_CANDIDATE(pmv[1].x,pmv[1].y);
1037          }          }
1038    
1039  // top neighbour, if allowed  // top neighbour, if allowed
1040          if (y != 0)          if (!MVzero(pmv[2]))
1041            if (!MVequal(pmv[2],prevMB->mvs[0]))
1042            if (!MVequal(pmv[2],pmv[0]))
1043            if (!MVequal(pmv[2],pmv[1]))
1044          {          {
1045                  if (!(MotionFlags & PMV_HALFPEL16 ))                  if (!(MotionFlags & PMV_HALFPEL16 ))
1046                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1036  Line 1049 
1049                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1050    
1051  // top right neighbour, if allowed  // top right neighbour, if allowed
1052                  if (x != (iWcount-1))                  if (!MVzero(pmv[3]))
1053                    if (!MVequal(pmv[3],prevMB->mvs[0]))
1054                    if (!MVequal(pmv[3],pmv[0]))
1055                    if (!MVequal(pmv[3],pmv[1]))
1056                    if (!MVequal(pmv[3],pmv[2]))
1057                  {                  {
1058                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1059                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1046  Line 1063 
1063                  }                  }
1064          }          }
1065    
1066            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96)*/ )
1067                    iMinSAD -= MV16_00_BIAS;
1068    
1069    
1070  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1071     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.
1072  */  */
1073    
1074          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1075          {          {
1076                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1077                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1236  Line 1257 
1257                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1258                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1259                                          const int x, const int y,                                          const int x, const int y,
1260                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1261                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1262                                            const uint32_t iQuant,
1263                                            const uint32_t iFcode,
1264                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1265                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1266                                            const MACROBLOCK * const prevMBs,
1267                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1268                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1269  {  {
1270          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;  
1271          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1272          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1273          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1264  Line 1285 
1285          int32_t psad[4];          int32_t psad[4];
1286          VECTOR newMV;          VECTOR newMV;
1287          VECTOR backupMV;          VECTOR backupMV;
1288            VECTOR startMV;
1289    
1290          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1291            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1292    
1293          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1294          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
1295          int32_t iMinSAD,iSAD;          int32_t iMinSAD,iSAD;
1296    
1297          int32_t iSubBlock = ((y&1)<<1) + (x&1);          int32_t iSubBlock = (y&1)+(y&1) + (x&1);
1298    
1299            /* Init variables */
1300            startMV.x = start_x;
1301            startMV.y = start_y;
1302    
1303  /* Get maximum range */  /* Get maximum range */
1304          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1305                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1306    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1307          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1308          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1309          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1306  Line 1331 
1331    
1332          iFound=0;          iFound=0;
1333    
 /* 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;  
   
1334  /* Step 4: Calculate SAD around the Median prediction.  /* Step 4: Calculate SAD around the Median prediction.
1335     MinSAD=SAD     MinSAD=SAD
1336     If Motion Vector equal to Previous frame motion vector     If Motion Vector equal to Previous frame motion vector
# Line 1336  Line 1341 
1341    
1342  // Prepare for main loop  // Prepare for main loop
1343    
1344          currMV->x=start_x;              /* start with mv16 */          *currMV = startMV;
         currMV->y=start_y;  
1345    
1346          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1347                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                          get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1348                          iEdgedWidth);                          iEdgedWidth);
1349          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);
1350    
1351          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock]))
1352                                    && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1353          {          {
1354                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1355                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1352  Line 1357 
1357                          goto PMVfast8_Terminate_with_Refine;                          goto PMVfast8_Terminate_with_Refine;
1358          }          }
1359    
1360    /* Step 2 (lazy eval): Calculate Distance= |MedianMVX| + |MedianMVY| where MedianMV is the motion
1361       vector of the median.
1362       If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1363    */
1364    
1365            if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1366                    iFound=2;
1367    
1368    /* Step 3 (lazy eval): If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
1369       Otherwise select large Diamond Search.
1370    */
1371    
1372            if ( (!MVzero(pmv[0])) || (threshB<1536/4) || (bPredEq) )
1373                    iDiamondSize=1; // 1 halfpel!
1374            else
1375                    iDiamondSize=2; // 2 halfpel = 1 full pixel!
1376    
1377            if (!(MotionFlags & PMV_HALFPELDIAMOND8) )
1378                    iDiamondSize*=2;
1379    
1380    
1381  /*  /*
1382     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.
1383     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1384     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1385     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1386  */  */
1387    
1388  // the prediction might be even better than mv16  // the median prediction might be even better than mv16
1389    
1390            if (!MVequal(pmv[0],startMV))
1391          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);          CHECK_MV8_CANDIDATE(pmv[0].x,pmv[0].y);
1392    
1393  // (0,0) is always possible  // (0,0) if needed
1394            if (!MVzero(pmv[0]))
1395            if (!MVzero(startMV))
1396          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1397    
1398  // previous frame MV is always possible  // previous frame MV if needed
1399          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          if (!MVzero(prevMB->mvs[iSubBlock]))
1400            if (!MVequal(prevMB->mvs[iSubBlock],startMV))
1401            if (!MVequal(prevMB->mvs[iSubBlock],pmv[0]))
1402            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1403    
1404  // left neighbour, if allowed          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1405          if (psad[1] != MV_MAX_ERROR)          {
1406                    if (MotionFlags & PMV_QUICKSTOP16)
1407                            goto PMVfast8_Terminate_without_Refine;
1408                    if (MotionFlags & PMV_EARLYSTOP16)
1409                            goto PMVfast8_Terminate_with_Refine;
1410            }
1411    
1412    
1413    // left neighbour, if allowed and needed
1414            if (!MVzero(pmv[1]))
1415            if (!MVequal(pmv[1],startMV))
1416            if (!MVequal(pmv[1],prevMB->mvs[iSubBlock]))
1417            if (!MVequal(pmv[1],pmv[0]))
1418          {          {
1419                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1420                  {       pmv[1].x = EVEN(pmv[1].x);                  {       pmv[1].x = EVEN(pmv[1].x);
# Line 1379  Line 1423 
1423                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);                  CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1424          }          }
1425    
1426  // top neighbour, if allowed  // top neighbour, if allowed and needed
1427          if (psad[2] != MV_MAX_ERROR)          if (!MVzero(pmv[2]))
1428            if (!MVequal(pmv[2],startMV))
1429            if (!MVequal(pmv[2],prevMB->mvs[iSubBlock]))
1430            if (!MVequal(pmv[2],pmv[0]))
1431            if (!MVequal(pmv[2],pmv[1]))
1432          {          {
1433                  if (!(MotionFlags & PMV_HALFPEL8 ))                  if (!(MotionFlags & PMV_HALFPEL8 ))
1434                  {       pmv[2].x = EVEN(pmv[2].x);                  {       pmv[2].x = EVEN(pmv[2].x);
# Line 1388  Line 1436 
1436                  }                  }
1437                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1438    
1439  // top right neighbour, if allowed  // top right neighbour, if allowed and needed
1440                  if (psad[3] != MV_MAX_ERROR)          if (!MVzero(pmv[3]))
1441            if (!MVequal(pmv[3],startMV))
1442            if (!MVequal(pmv[3],prevMB->mvs[iSubBlock]))
1443            if (!MVequal(pmv[3],pmv[0]))
1444            if (!MVequal(pmv[3],pmv[1]))
1445            if (!MVequal(pmv[3],pmv[2]))
1446                  {                  {
1447                          if (!(MotionFlags & PMV_HALFPEL8 ))                          if (!(MotionFlags & PMV_HALFPEL8 ))
1448                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1399  Line 1452 
1452                  }                  }
1453          }          }
1454    
1455            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) /* && (iMinSAD <= iQuant * 96) */ )
1456                    iMinSAD -= MV8_00_BIAS;
1457    
1458    
1459  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1460     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.
1461  */  */
1462    
1463          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]) ) )
1464          {          {
1465                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1466                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1493  Line 1550 
1550                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1551                                          const int x, const int y,                                          const int x, const int y,
1552                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1553                                            const uint32_t iQuant,
1554                                            const uint32_t iFcode,
1555                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1556                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1557                                            const MACROBLOCK * const prevMBs,
1558                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1559                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1560  {  {
1561          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
1562          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;  
1563    
1564          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1565          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1521  Line 1579 
1579          int32_t psad[8];          int32_t psad[8];
1580    
1581          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1582          MACROBLOCK * const pMB = pMBs + x + y * iWcount;  //      const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1583            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1584          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1585    
1586          static int32_t thresh2;          static int32_t thresh2;
# Line 1531  Line 1590 
1590          MainSearch16FuncPtr EPZSMainSearchPtr;          MainSearch16FuncPtr EPZSMainSearchPtr;
1591    
1592          if (oldMBs == NULL)          if (oldMBs == NULL)
1593          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(iWcount*iHcount,sizeof(MACROBLOCK));
1594                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1595          }          }
1596          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1597    
# Line 1540  Line 1599 
1599          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1600                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1601    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1602          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1603          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1604            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1581  Line 1638 
1638          iMinSAD = sad16( cur,          iMinSAD = sad16( cur,
1639                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV, iEdgedWidth),
1640                  iEdgedWidth, MV_MAX_ERROR);                  iEdgedWidth, MV_MAX_ERROR);
1641          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);
1642    
1643  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1644          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV, prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1645                  {                  {
1646                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1647                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1595  Line 1652 
1652  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1653    
1654  // previous frame MV  // previous frame MV
1655          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1656    
1657  // set threshhold based on Min of Prediction and SAD of collocated block  // set threshhold based on Min of Prediction and SAD of collocated block
1658  // 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 1693 
1693                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1694    
1695  // top right neighbour, if allowed  // top right neighbour, if allowed
1696                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1697                  {                  {
1698                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1699                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1651  Line 1708 
1708  */  */
1709    
1710          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1711                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1712                  {                  {
1713                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1714                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1661  Line 1718 
1718    
1719  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/  /***** predictor SET C: acceleration MV (new!), neighbours in prev. frame(new!) ****/
1720    
1721          backupMV = pMB->mvs[0];                 // last MV          backupMV = prevMB->mvs[0];              // collocated MV
1722          backupMV.x += (pMB->mvs[0].x - oldMB->mvs[0].x );       // acceleration X          backupMV.x += (prevMB->mvs[0].x - oldMB->mvs[0].x );    // acceleration X
1723          backupMV.y += (pMB->mvs[0].y - oldMB->mvs[0].y );       // acceleration Y          backupMV.y += (prevMB->mvs[0].y - oldMB->mvs[0].y );    // acceleration Y
1724    
1725          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);          CHECK_MV16_CANDIDATE(backupMV.x,backupMV.y);
1726    
1727  // left neighbour  // left neighbour
1728          if (x != 0)          if (x != 0)
1729                  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);
1730    
1731  // top neighbour  // top neighbour
1732          if (y != 0)          if (y != 0)
1733                  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);
1734    
1735  // 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
1736    
1737          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1738                  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);
1739    
1740  // bottom neighbour, dito  // bottom neighbour, dito
1741          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1742                  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);
1743    
1744  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
1745          if (iMinSAD <= thresh2)          if (iMinSAD <= thresh2)
# Line 1739  Line 1796 
1796                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,                          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
1797                                  x, y,                                  x, y,
1798                          0, 0, iMinSAD, &newMV,                          0, 0, iMinSAD, &newMV,
1799                          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);
1800    
1801                          if (iSAD < iMinSAD)                          if (iSAD < iMinSAD)
1802                          {                          {
# Line 1760  Line 1817 
1817    
1818  EPZS16_Terminate_without_Refine:  EPZS16_Terminate_without_Refine:
1819    
1820          *oldMB = *pMB;          *oldMB = *prevMB;
1821    
1822          currPMV->x = currMV->x - pmv[0].x;          currPMV->x = currMV->x - pmv[0].x;
1823          currPMV->y = currMV->y - pmv[0].y;          currPMV->y = currMV->y - pmv[0].y;
# Line 1777  Line 1834 
1834                                          const int x, const int y,                                          const int x, const int y,
1835                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1836                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1837                                            const uint32_t iQuant,
1838                                            const uint32_t iFcode,
1839                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1840                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1841                                            const MACROBLOCK * const prevMBs,
1842                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1843                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1844  {  {
1845          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;  
1846    
1847            const uint32_t iWcount = pParam->mb_width;
1848          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1849          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1850          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1807  Line 1866 
1866    
1867          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1868    
1869          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;  //      const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1870            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1871    
1872          int32_t bPredEq;          int32_t bPredEq;
1873          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1861  Line 1921 
1921          iMinSAD = sad8( cur,          iMinSAD = sad8( cur,
1922                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),                  get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 8, currMV, iEdgedWidth),
1923                  iEdgedWidth);                  iEdgedWidth);
1924          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);
1925    
1926    
1927  // thresh1 is fixed to 256  // thresh1 is fixed to 256
# Line 1875  Line 1935 
1935    
1936  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/  /************** This is predictor SET B: (0,0), prev.frame MV, neighbours **************/
1937    
 // previous frame MV  
         CHECK_MV8_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);  
1938    
1939  // MV=(0,0) is often a good choice  // MV=(0,0) is often a good choice
   
1940          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1941    
1942    // previous frame MV
1943            CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1944    
1945    // left neighbour, if allowed
1946            if (psad[1] != MV_MAX_ERROR)
1947            {
1948                    if (!(MotionFlags & PMV_HALFPEL8 ))
1949                    {       pmv[1].x = EVEN(pmv[1].x);
1950                            pmv[1].y = EVEN(pmv[1].y);
1951                    }
1952                    CHECK_MV8_CANDIDATE(pmv[1].x,pmv[1].y);
1953            }
1954    
1955    // top neighbour, if allowed
1956            if (psad[2] != MV_MAX_ERROR)
1957            {
1958                    if (!(MotionFlags & PMV_HALFPEL8 ))
1959                    {       pmv[2].x = EVEN(pmv[2].x);
1960                            pmv[2].y = EVEN(pmv[2].y);
1961                    }
1962                    CHECK_MV8_CANDIDATE(pmv[2].x,pmv[2].y);
1963    
1964    // top right neighbour, if allowed
1965                    if (psad[3] != MV_MAX_ERROR)
1966                    {
1967                            if (!(MotionFlags & PMV_HALFPEL8 ))
1968                            {       pmv[3].x = EVEN(pmv[3].x);
1969                                    pmv[3].y = EVEN(pmv[3].y);
1970                            }
1971                            CHECK_MV8_CANDIDATE(pmv[3].x,pmv[3].y);
1972                    }
1973            }
1974    
1975    /*  // this bias is zero anyway, at the moment!
1976    
1977            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) ) // && (iMinSAD <= iQuant * 96)
1978                    iMinSAD -= MV8_00_BIAS;
1979    
1980    */
1981    
1982  /* Terminate if MinSAD <= T_2  /* Terminate if MinSAD <= T_2
1983     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]
1984  */  */
# Line 1894  Line 1991 
1991                                  goto EPZS8_Terminate_with_Refine;                                  goto EPZS8_Terminate_with_Refine;
1992                  }                  }
1993    
1994  /************ (if Diamond Search)  **************/  /************ (Diamond Search)  **************/
1995    
1996          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */          backupMV = *currMV; /* save best prediction, actually only for EXTSEARCH */
1997    
1998          if (!(MotionFlags & PMV_HALFPELDIAMOND8))          if (!(MotionFlags & PMV_HALFPELDIAMOND8))
1999                  iDiamondSize *= 2;                  iDiamondSize *= 2;
2000    
2001  /* 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 */
2002    
2003    /* // there is no EPZS^2 for inter4v at the moment
2004    
2005            if (MotionFlags & PMV_USESQUARES8)
2006                    EPZSMainSearchPtr = Square8_MainSearch;
2007            else
2008    */
2009    
 //      if (MotionFlags & PMV_USESQUARES8)  
 //              EPZSMainSearchPtr = Square8_MainSearch;  
 //      else  
2010                  EPZSMainSearchPtr = Diamond8_MainSearch;                  EPZSMainSearchPtr = Diamond8_MainSearch;
2011    
2012          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,          iSAD = (*EPZSMainSearchPtr)(pRef, pRefH, pRefV, pRefHV, cur,
2013                  x, y,                  x, y,
2014                  currMV->x, currMV->y, iMinSAD, &newMV,                  currMV->x, currMV->y, iMinSAD, &newMV,
2015                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,                  pmv, min_dx, max_dx, min_dy, max_dy, iEdgedWidth,
2016                  iDiamondSize, iFcode, iQuant, 00);                  iDiamondSize, iFcode, iQuant, 0);
2017    
2018    
2019          if (iSAD < iMinSAD)          if (iSAD < iMinSAD)
# Line 1970  Line 2071 
2071          return iMinSAD;          return iMinSAD;
2072  }  }
2073    
2074    
2075    
2076    
2077    
2078    /* ***********************************************************
2079            bvop motion estimation
2080    // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
2081    ***************************************************************/
2082    
2083    
2084    void MotionEstimationBVOP(
2085                            MBParam * const pParam,
2086                            FRAMEINFO * const frame,
2087    
2088                            // forward (past) reference
2089                            const MACROBLOCK * const f_mbs,
2090                        const IMAGE * const f_ref,
2091                            const IMAGE * const f_refH,
2092                        const IMAGE * const f_refV,
2093                            const IMAGE * const f_refHV,
2094                            // backward (future) reference
2095                            const MACROBLOCK * const b_mbs,
2096                        const IMAGE * const b_ref,
2097                            const IMAGE * const b_refH,
2098                        const IMAGE * const b_refV,
2099                            const IMAGE * const b_refHV)
2100    {
2101        const uint32_t mb_width = pParam->mb_width;
2102        const uint32_t mb_height = pParam->mb_height;
2103            const int32_t edged_width = pParam->edged_width;
2104    
2105            uint32_t i,j;
2106    
2107            int32_t f_sad16;
2108            int32_t b_sad16;
2109            int32_t i_sad16;
2110            int32_t d_sad16;
2111            int32_t best_sad;
2112    
2113            VECTOR pmv_dontcare;
2114    
2115            // note: i==horizontal, j==vertical
2116        for (j = 0; j < mb_height; j++)
2117            {
2118                    for (i = 0; i < mb_width; i++)
2119                    {
2120                            MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2121                            const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2122                            const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2123    
2124                            if (b_mb->mode == MODE_INTER
2125                                    && b_mb->cbp == 0
2126                                    && b_mb->mvs[0].x == 0
2127                                    && b_mb->mvs[0].y == 0)
2128                            {
2129                                    mb->mode = MODE_NOT_CODED;
2130                                    mb->mvs[0].x = 0;
2131                                    mb->mvs[0].y = 0;
2132                                    mb->b_mvs[0].x = 0;
2133                                    mb->b_mvs[0].y = 0;
2134                                    continue;
2135                            }
2136    
2137    
2138                            // forward search
2139                            f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2140                                                    &frame->image,
2141                                                    i, j,
2142                                                    frame->motion_flags,  frame->quant, frame->fcode,
2143                                                    pParam,
2144                                                    f_mbs, f_mbs /* todo */,
2145                                                    &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2146    
2147                            // backward search
2148                            b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2149                                                    &frame->image,
2150                                                    i, j,
2151                                                    frame->motion_flags,  frame->quant, frame->bcode,
2152                                                    pParam,
2153                                                    b_mbs, b_mbs, /* todo */
2154                                                    &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2155    
2156                            // interpolate search (simple, but effective)
2157                            i_sad16 = sad16bi_c(
2158                                            frame->image.y + i*16 + j*16*edged_width,
2159                                            get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2160                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),
2161                                            get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2162                                                    i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),
2163                                            edged_width);
2164    
2165                            // TODO: direct search
2166                            // predictor + range of [-32,32]
2167                            d_sad16 = 65535;
2168    
2169    
2170                            if (f_sad16 < b_sad16)
2171                            {
2172                                    best_sad = f_sad16;
2173                                    mb->mode = MODE_FORWARD;
2174                            }
2175                            else
2176                            {
2177                                    best_sad = b_sad16;
2178                                    mb->mode = MODE_BACKWARD;
2179                            }
2180    
2181                            if (i_sad16 < best_sad)
2182                            {
2183                                    best_sad = i_sad16;
2184                                    mb->mode = MODE_INTERPOLATE;
2185                            }
2186    
2187                            if (d_sad16 < best_sad)
2188                            {
2189                                    best_sad = d_sad16;
2190                                    mb->mode = MODE_DIRECT;
2191                            }
2192    
2193                    }
2194            }
2195    }

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

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