[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 140, Thu Apr 25 21:32:05 2002 UTC
# Line 2  Line 2 
2   *   *
3   *  Modifications:   *  Modifications:
4   *   *
5     *      25.04.2002 partial prevMB conversion
6     *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>
7     *  14.04.2002 added MotionEstimationBVOP()
8   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between   *  02.04.2002 add EPZS(^2) as ME algorithm, use PMV_USESQUARES to choose between
9   *             EPZS and EPZS^2   *             EPZS and EPZS^2
10   *  08.02.2002 split up PMVfast into three routines: PMVFast, PMVFast_MainLoop   *  08.02.2002 split up PMVfast into three routines: PMVFast, PMVFast_MainLoop
# Line 40  Line 43 
43  #include "../prediction/mbprediction.h"  #include "../prediction/mbprediction.h"
44  #include "../global.h"  #include "../global.h"
45  #include "../utils/timer.h"  #include "../utils/timer.h"
46    #include "motion.h"
47  #include "sad.h"  #include "sad.h"
48    
49  // very large value  // very large value
# Line 52  Line 56 
56  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */  /* sad16(0,0) bias; mpeg4 spec suggests nb/2+1 */
57  /* nb  = vop pixels * 2^(bpp-8) */  /* nb  = vop pixels * 2^(bpp-8) */
58  #define MV16_00_BIAS    (128+1)  #define MV16_00_BIAS    (128+1)
59    #define MV8_00_BIAS     (0)
60    
61  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */  /* INTER bias for INTER/INTRA decision; mpeg4 spec suggests 2*nb */
62  #define INTER_BIAS      512  #define INTER_BIAS      512
# Line 68  Line 73 
73  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
74    
75    
 #define MIN(X, Y) ((X)<(Y)?(X):(Y))  
 #define MAX(X, Y) ((X)>(Y)?(X):(Y))  
 #define ABS(X)    (((X)>0)?(X):-(X))  
 #define SIGN(X)   (((X)>0)?1:-1)  
   
76  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
77                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
78                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 81  Line 81 
81                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
82                                          const int x, const int y,                                          const int x, const int y,
83                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
84                                            const uint32_t iQuant,
85                                            const uint32_t iFcode,
86                                          const MBParam * const pParam,                                          const MBParam * const pParam,
87                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
88                                            const MACROBLOCK * const prevMBs,
89                                          VECTOR * const currMV,                                          VECTOR * const currMV,
90                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
91    
# Line 94  Line 97 
97                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
98                                          const int x, const int y,                                          const int x, const int y,
99                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
100                                            const uint32_t iQuant,
101                                            const uint32_t iFcode,
102                                          const MBParam * const pParam,                                          const MBParam * const pParam,
103                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
104                                            const MACROBLOCK * const prevMBs,
105                                          VECTOR * const currMV,                                          VECTOR * const currMV,
106                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
107    
# Line 107  Line 113 
113                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
114                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
115                                          const int x, const int y,                                          const int x, const int y,
116                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
117                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
118                                            const uint32_t iQuant,
119                                            const uint32_t iFcode,
120                                          const MBParam * const pParam,                                          const MBParam * const pParam,
121                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
122                                            const MACROBLOCK * const prevMBs,
123                                          VECTOR * const currMV,                                          VECTOR * const currMV,
124                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
125    
# Line 121  Line 130 
130                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
131                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
132                                          const int x, const int y,                                          const int x, const int y,
133                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
134                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
135                                            const uint32_t iQuant,
136                                            const uint32_t iFcode,
137                                          const MBParam * const pParam,                                          const MBParam * const pParam,
138                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
139                                            const MACROBLOCK * const prevMBs,
140                                          VECTOR * const currMV,                                          VECTOR * const currMV,
141                                          VECTOR * const currPMV);                                          VECTOR * const currPMV);
142    
# Line 221  Line 233 
233    
234    
235    
 /* calculate the min/max range (in halfpixels)  
         relative to the _MACROBLOCK_ position  
 */  
   
 static void __inline get_range(  
         int32_t * const min_dx, int32_t * const max_dx,  
         int32_t * const min_dy, int32_t * const max_dy,  
         const uint32_t x, const uint32_t y,  
         const uint32_t block_sz,                                        // block dimension, 8 or 16  
         const uint32_t width, const uint32_t height,  
         const uint32_t fcode)  
 {  
   
         const int search_range = 32 << (fcode - 1);  
         const int high = search_range - 1;  
         const int low = -search_range;  
   
         // convert full-pixel measurements to half pixel  
         const int hp_width = 2 * width;  
         const int hp_height = 2 * height;  
         const int hp_edge = 2 * block_sz;  
         const int hp_x = 2 * (x) * block_sz;            // we need _right end_ of block, not x-coordinate  
         const int hp_y = 2 * (y) * block_sz;            // same for _bottom end_  
   
         *max_dx = MIN(high,     hp_width - hp_x);  
         *max_dy = MIN(high,     hp_height - hp_y);  
         *min_dx = MAX(low,      -(hp_edge + hp_x));  
         *min_dy = MAX(low,      -(hp_edge + hp_y));  
   
 }  
   
   
 /*  
  * getref: calculate reference image pointer  
  * the decision to use interpolation h/v/hv or the normal image is  
  * based on dx & dy.  
  */  
   
 static __inline const uint8_t * get_ref(  
         const uint8_t * const refn,  
         const uint8_t * const refh,  
         const uint8_t * const refv,  
         const uint8_t * const refhv,  
         const uint32_t x, const uint32_t y,  
         const uint32_t block,                                   // block dimension, 8 or 16  
         const int32_t dx, const int32_t dy,  
         const uint32_t stride)  
 {  
   
         switch ( ((dx&1)<<1) + (dy&1) )         // ((dx%2)?2:0)+((dy%2)?1:0)  
         {  
         case 0  : return refn + (x*block+dx/2) + (y*block+dy/2)*stride;  
         case 1  : return refv + (x*block+dx/2) + (y*block+(dy-1)/2)*stride;  
         case 2  : return refh + (x*block+(dx-1)/2) + (y*block+dy/2)*stride;  
         default :  
         case 3  : return refhv + (x*block+(dx-1)/2) + (y*block+(dy-1)/2)*stride;  
         }  
   
 }  
   
   
 /* This is somehow a copy of get_ref, but with MV instead of X,Y */  
   
 static __inline const uint8_t * get_ref_mv(  
         const uint8_t * const refn,  
         const uint8_t * const refh,  
         const uint8_t * const refv,  
         const uint8_t * const refhv,  
         const uint32_t x, const uint32_t y,  
         const uint32_t block,                   // block dimension, 8 or 16  
         const VECTOR* mv,       // measured in half-pel!  
         const uint32_t stride)  
 {  
   
         switch ( (((mv->x)&1)<<1) + ((mv->y)&1) )  
         {  
         case 0  : return refn + (x*block+(mv->x)/2) + (y*block+(mv->y)/2)*stride;  
         case 1  : return refv + (x*block+(mv->x)/2) + (y*block+((mv->y)-1)/2)*stride;  
         case 2  : return refh + (x*block+((mv->x)-1)/2) + (y*block+(mv->y)/2)*stride;  
         default :  
         case 3  : return refhv + (x*block+((mv->x)-1)/2) + (y*block+((mv->y)-1)/2)*stride;  
         }  
   
 }  
236    
237  #ifndef SEARCH16  #ifndef SEARCH16
238  #define SEARCH16        PMVfastSearch16  #define SEARCH16        PMVfastSearch16
# Line 318  Line 246 
246  #endif  #endif
247    
248  bool MotionEstimation(  bool MotionEstimation(
         MACROBLOCK * const pMBs,  
249          MBParam * const pParam,          MBParam * const pParam,
250          const IMAGE * const pRef,          FRAMEINFO * const current,
251            FRAMEINFO * const reference,
252          const IMAGE * const pRefH,          const IMAGE * const pRefH,
253          const IMAGE * const pRefV,          const IMAGE * const pRefV,
254          const IMAGE * const pRefHV,          const IMAGE * const pRefHV,
         IMAGE * const pCurrent,  
255          const uint32_t iLimit)          const uint32_t iLimit)
256    
257  {  {
258          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
259          const uint32_t iHcount = pParam->mb_height;          const uint32_t iHcount = pParam->mb_height;
260            MACROBLOCK * pMBs = current->mbs;
261            IMAGE * pCurrent = &current->image;
262    
263            MACROBLOCK * prevMBs = reference->mbs;  // previous frame
264            IMAGE * pRef = &reference->image;
265    
266    
267          uint32_t i, j, iIntra = 0;          uint32_t i, j, iIntra = 0;
268    
# Line 340  Line 273 
273          int32_t sad16;          int32_t sad16;
274          int32_t deviation;          int32_t deviation;
275    
276          if (sadInit);          if (sadInit)
277                  (*sadInit)();                  (*sadInit)();
278    
279    
280            /* eventhough we have a seperate prevMBs,
281               pmvfast/epsz does something "funny" with the previous frames data */
282    
283    /*      for (i = 0; i < iHcount; i++)
284                    for (j = 0; j < iWcount; j++)
285                    {
286                            pMBs[j + i * iWcount].mvs[0] = prevMBs[j + i * iWcount].mvs[0];
287                            pMBs[j + i * iWcount].mvs[1] = prevMBs[j + i * iWcount].mvs[1];
288                            pMBs[j + i * iWcount].mvs[2] = prevMBs[j + i * iWcount].mvs[2];
289                            pMBs[j + i * iWcount].mvs[3] = prevMBs[j + i * iWcount].mvs[3];
290                    }
291    */
292            /*dprintf("*** BEFORE ***");
293            for (i = 0; i < iHcount; i++)
294                    for (j = 0; j < iWcount; j++)
295                    {
296                            dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,
297                                    pMBs[j + i * iWcount].mode,
298                                    pMBs[j + i * iWcount].dquant,
299                                    pMBs[j + i * iWcount].mvs[0],
300                                    pMBs[j + i * iWcount].mvs[1],
301                                    pMBs[j + i * iWcount].mvs[2],
302                                    pMBs[j + i * iWcount].mvs[3],
303                                    prevMBs[j + i * iWcount].sad8[0],
304                                    prevMBs[j + i * iWcount].sad8[1],
305                                    prevMBs[j + i * iWcount].sad8[2],
306                                    prevMBs[j + i * iWcount].sad8[3],
307                                    prevMBs[j + i * iWcount].sad16);
308                    }
309            */
310    
311          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
312          for (i = 0; i < iHcount; i++)          for (i = 0; i < iHcount; i++)
313                  for (j = 0; j < iWcount; j++)                  for (j = 0; j < iWcount; j++)
314                  {                  {
315                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];                          MACROBLOCK *pMB = &pMBs[j + i * iWcount];
316                            MACROBLOCK *prevMB = &prevMBs[j + i * iWcount];
317    
318                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                          sad16 = SEARCH16(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
319                                           j, i, pParam->motion_flags,                                           j, i, current->motion_flags, current->quant, current->fcode,
320                                           pParam, pMBs, &mv16, &pmv16);                                           pParam, pMBs, prevMBs, &mv16, &pmv16);
321                          pMB->sad16=sad16;                          pMB->sad16=sad16;
322    
323    
# Line 367  Line 333 
333                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;                                  pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
334                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;                                  pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
335    
336                                    pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
337    
338                                  iIntra++;                                  iIntra++;
339                                  if(iIntra >= iLimit)                                  if(iIntra >= iLimit)
340                                          return 1;                                          return 1;
# Line 374  Line 342 
342                                  continue;                                  continue;
343                          }                          }
344    
345                          if (pParam->global_flags & XVID_INTER4V)                          if (current->global_flags & XVID_INTER4V)
346                          {                          {
347                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[0] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
348                                                         2 * j, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i, mv16.x, mv16.y,
349                                                         pParam, pMBs, &pMB->mvs[0], &pMB->pmvs[0]);                                                             current->motion_flags, current->quant, current->fcode,
350                                                           pParam, pMBs, prevMBs, &pMB->mvs[0], &pMB->pmvs[0]);
351    
352                                  pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[1] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
353                                                         2 * j + 1, 2 * i, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i, mv16.x, mv16.y,
354                                                         pParam, pMBs, &pMB->mvs[1], &pMB->pmvs[1]);                                                             current->motion_flags, current->quant, current->fcode,
355                                                           pParam, pMBs, prevMBs, &pMB->mvs[1], &pMB->pmvs[1]);
356    
357                                  pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[2] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
358                                                         2 * j, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j, 2 * i + 1, mv16.x, mv16.y,
359                                                         pParam, pMBs, &pMB->mvs[2], &pMB->pmvs[2]);                                                             current->motion_flags, current->quant, current->fcode,
360                                                           pParam, pMBs, prevMBs, &pMB->mvs[2], &pMB->pmvs[2]);
361    
362                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,                                  pMB->sad8[3] = SEARCH8(pRef->y, pRefH->y, pRefV->y, pRefHV->y, pCurrent,
363                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y, pParam->motion_flags,                                                         2 * j + 1, 2 * i + 1, mv16.x, mv16.y,
364                                                         pParam, pMBs, &pMB->mvs[3], &pMB->pmvs[3]);                                                             current->motion_flags, current->quant, current->fcode,
365                                                           pParam, pMBs, prevMBs, &pMB->mvs[3], &pMB->pmvs[3]);
366    
367                                  sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];                                  sad8 = pMB->sad8[0] + pMB->sad8[1] + pMB->sad8[2] + pMB->sad8[3];
368                          }                          }
# Line 400  Line 372 
372                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v                             mpeg4:   if (sad8 < sad16 - nb/2+1) use_inter4v
373                          */                          */
374    
375                          if (pMB->dquant == NO_CHANGE) {                          if (!(current->global_flags & XVID_LUMIMASKING) || pMB->dquant == NO_CHANGE)
376                                  if (((pParam->global_flags & XVID_INTER4V)==0) ||                          {
377                                      (sad16 < (sad8 + (int32_t)(IMV16X16 * pParam->quant)))) {                                  if (((current->global_flags & XVID_INTER4V)==0) ||
378                                        (sad16 < (sad8 + (int32_t)(IMV16X16 * current->quant))))
379                                    {
380    
381                                          sad8 = sad16;                                          sad8 = sad16;
382                                          pMB->mode = MODE_INTER;                                          pMB->mode = MODE_INTER;
# Line 425  Line 399 
399                          }                          }
400                  }                  }
401    
402    /*      dprintf("*** AFTER ***", pMBs[0].b_mvs[0].x);
403            for (i = 0; i < iHcount; i++)
404                    for (j = 0; j < iWcount; j++)
405                    {
406                            dprintf("   [%i,%i] mode=%i dquant=%i mvs=(%i %i %i %i) sad8=(%i %i %i %i) sad16=(%i)", j,i,
407                                    pMBs[j + i * iWcount].mode,
408                                    pMBs[j + i * iWcount].dquant,
409                                    pMBs[j + i * iWcount].mvs[0],
410                                    pMBs[j + i * iWcount].mvs[1],
411                                    pMBs[j + i * iWcount].mvs[2],
412                                    pMBs[j + i * iWcount].mvs[3],
413                                    pMBs[j + i * iWcount].sad8[0],
414                                    pMBs[j + i * iWcount].sad8[1],
415                                    pMBs[j + i * iWcount].sad8[2],
416                                    pMBs[j + i * iWcount].sad8[3],
417                                    pMBs[j + i * iWcount].sad16);
418                    }
419            */
420    
421          return 0;          return 0;
422  }  }
423    
# Line 439  Line 432 
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  }  }
# 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 939  Line 934 
934     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
935  */  */
936    
937          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[0]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[0]) ) )
938                  iFound=2;                  iFound=2;
939    
940  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
# Line 993  Line 988 
988                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
989          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;
990    
991          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,prevMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
992          {          {
993    
994                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
# Line 1006  Line 1001 
1001     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.
1002     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1003     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1004     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1005  */  */
1006    
1007  // (0,0) is always possible  // (0,0) is always possible
# Line 1014  Line 1009 
1009          CHECK_MV16_ZERO;          CHECK_MV16_ZERO;
1010    
1011  // previous frame MV is always possible  // previous frame MV is always possible
1012          CHECK_MV16_CANDIDATE(pMB->mvs[0].x,pMB->mvs[0].y);          CHECK_MV16_CANDIDATE(prevMB->mvs[0].x,prevMB->mvs[0].y);
1013    
1014  // left neighbour, if allowed  // left neighbour, if allowed
1015          if (x != 0)          if (x != 0)
# Line 1036  Line 1031 
1031                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1032    
1033  // top right neighbour, if allowed  // top right neighbour, if allowed
1034                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1035                  {                  {
1036                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1037                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1046  Line 1041 
1041                  }                  }
1042          }          }
1043    
1044            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) && (iSAD <= iQuant * 96) )
1045                    iMinSAD -= MV16_00_BIAS;
1046    
1047    
1048  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1049     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.
1050  */  */
1051    
1052          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,prevMB->mvs[0]) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1053          {          {
1054                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1055                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1236  Line 1235 
1235                                          const uint8_t * const pRefHV,                                          const uint8_t * const pRefHV,
1236                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1237                                          const int x, const int y,                                          const int x, const int y,
1238                                          const int start_x, int start_y,                                          const int start_x, const int start_y,
1239                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1240                                            const uint32_t iQuant,
1241                                            const uint32_t iFcode,
1242                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1243                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1244                                            const MACROBLOCK * const prevMBs,
1245                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1246                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1247  {  {
1248          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;  
1249          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1250          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1251          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1265  Line 1264 
1264          VECTOR newMV;          VECTOR newMV;
1265          VECTOR backupMV;          VECTOR backupMV;
1266    
1267          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1268            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1269    
1270          static int32_t threshA,threshB;          static int32_t threshA,threshB;
1271          int32_t iFound,bPredEq;          int32_t iFound,bPredEq;
# Line 1277  Line 1277 
1277          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1278                    x, y, 8, iWidth, iHeight, iFcode);                    x, y, 8, iWidth, iHeight, iFcode);
1279    
 /* we work with abs. MVs, not relative to prediction, so range is relative to 0,0 */  
   
1280          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))          if (!(MotionFlags & PMV_HALFPELDIAMOND8 ))
1281          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1282          max_dx = EVEN(max_dx);          max_dx = EVEN(max_dx);
# Line 1311  Line 1309 
1309     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2     If PredEq=1 and MVpredicted = Previous Frame MV, set Found=2
1310  */  */
1311    
1312          if ((bPredEq) && (MVequal(pmv[0],pMB->mvs[iSubBlock]) ) )          if ((bPredEq) && (MVequal(pmv[0],prevMB->mvs[iSubBlock]) ) )
1313                  iFound=2;                  iFound=2;
1314    
1315  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.  /* Step 3: If Distance>0 or thresb<1536 or PredEq=1 Select small Diamond Search.
# Line 1344  Line 1342 
1342                          iEdgedWidth);                          iEdgedWidth);
1343          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;
1344    
1345          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,prevMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < prevMB->sad8[iSubBlock]) ) )
1346          {          {
1347                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1348                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1357  Line 1355 
1355     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.
1356     Also calculate (0,0) but do not subtract offset.     Also calculate (0,0) but do not subtract offset.
1357     Let MinSAD be the smallest SAD up to this point.     Let MinSAD be the smallest SAD up to this point.
1358     If MV is (0,0) subtract offset. ******** WHAT'S THIS 'OFFSET' ??? ***********     If MV is (0,0) subtract offset.
1359  */  */
1360    
1361  // the prediction might be even better than mv16  // the prediction might be even better than mv16
# Line 1367  Line 1365 
1365          CHECK_MV8_ZERO;          CHECK_MV8_ZERO;
1366    
1367  // previous frame MV is always possible  // previous frame MV is always possible
1368          CHECK_MV8_CANDIDATE(pMB->mvs[iSubBlock].x,pMB->mvs[iSubBlock].y);          CHECK_MV8_CANDIDATE(prevMB->mvs[iSubBlock].x,prevMB->mvs[iSubBlock].y);
1369    
1370  // left neighbour, if allowed  // left neighbour, if allowed
1371          if (psad[1] != MV_MAX_ERROR)          if (psad[1] != MV_MAX_ERROR)
# Line 1399  Line 1397 
1397                  }                  }
1398          }          }
1399    
1400            if ( (MVzero(*currMV)) && (!MVzero(pmv[0])) && (iSAD <= iQuant * 96) )
1401                    iMinSAD -= MV8_00_BIAS;
1402    
1403    
1404  /* Step 6: If MinSAD <= thresa goto Step 10.  /* Step 6: If MinSAD <= thresa goto Step 10.
1405     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.
1406  */  */
1407    
1408          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]) ) )
1409          {          {
1410                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1411                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1493  Line 1495 
1495                                          const IMAGE * const pCur,                                          const IMAGE * const pCur,
1496                                          const int x, const int y,                                          const int x, const int y,
1497                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1498                                            const uint32_t iQuant,
1499                                            const uint32_t iFcode,
1500                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1501                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1502                                            const MACROBLOCK * const prevMBs,
1503                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1504                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1505  {  {
1506          const uint32_t iWcount = pParam->mb_width;          const uint32_t iWcount = pParam->mb_width;
1507          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;  
1508    
1509          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1510          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
# Line 1521  Line 1524 
1524          int32_t psad[8];          int32_t psad[8];
1525    
1526          static MACROBLOCK * oldMBs = NULL;          static MACROBLOCK * oldMBs = NULL;
1527          MACROBLOCK * const pMB = pMBs + x + y * iWcount;          const MACROBLOCK * const pMB = pMBs + x + y * iWcount;
1528            const MACROBLOCK * const prevMB = prevMBs + x + y * iWcount;
1529          MACROBLOCK * oldMB = NULL;          MACROBLOCK * oldMB = NULL;
1530    
1531          static int32_t thresh2;          static int32_t thresh2;
# Line 1532  Line 1536 
1536    
1537          if (oldMBs == NULL)          if (oldMBs == NULL)
1538          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));          {       oldMBs = (MACROBLOCK*) calloc(1,iWcount*iHcount*sizeof(MACROBLOCK));
1539                  fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));  //              fprintf(stderr,"allocated %d bytes for oldMBs\n",iWcount*iHcount*sizeof(MACROBLOCK));
1540          }          }
1541          oldMB = oldMBs + x + y * iWcount;          oldMB = oldMBs + x + y * iWcount;
1542    
# Line 1540  Line 1544 
1544          get_range(&min_dx, &max_dx, &min_dy, &max_dy,          get_range(&min_dx, &max_dx, &min_dy, &max_dy,
1545                          x, y, 16, iWidth, iHeight, iFcode);                          x, y, 16, iWidth, iHeight, iFcode);
1546    
 /* we work with abs. MVs, not relative to prediction, so get_range is called relative to 0,0 */  
   
1547          if (!(MotionFlags & PMV_HALFPEL16 ))          if (!(MotionFlags & PMV_HALFPEL16 ))
1548          { min_dx = EVEN(min_dx);          { min_dx = EVEN(min_dx);
1549            max_dx = EVEN(max_dx);            max_dx = EVEN(max_dx);
# Line 1584  Line 1586 
1586          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;
1587    
1588  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1589          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < prevMB->sad16) ) )
1590                  {                  {
1591                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1592                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1636  Line 1638 
1638                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1639    
1640  // top right neighbour, if allowed  // top right neighbour, if allowed
1641                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1642                  {                  {
1643                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1644                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1651  Line 1653 
1653  */  */
1654    
1655          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1656                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= prevMB->sad16) ) )
1657                  {                  {
1658                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1659                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1677  Line 1679 
1679    
1680  // 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
1681    
1682          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1683                  CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);
1684    
1685  // bottom neighbour, dito  // bottom neighbour, dito
1686          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1687                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);
1688    
1689  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
# Line 1777  Line 1779 
1779                                          const int x, const int y,                                          const int x, const int y,
1780                                          const int start_x, const int start_y,                                          const int start_x, const int start_y,
1781                                          const uint32_t MotionFlags,                                          const uint32_t MotionFlags,
1782                                            const uint32_t iQuant,
1783                                            const uint32_t iFcode,
1784                                          const MBParam * const pParam,                                          const MBParam * const pParam,
1785                                          MACROBLOCK * const pMBs,                                          const MACROBLOCK * const pMBs,
1786                                            const MACROBLOCK * const prevMBs,
1787                                          VECTOR * const currMV,                                          VECTOR * const currMV,
1788                                          VECTOR * const currPMV)                                          VECTOR * const currPMV)
1789  {  {
1790          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;  
   
1791          const int32_t iWidth = pParam->width;          const int32_t iWidth = pParam->width;
1792          const int32_t iHeight = pParam->height;          const int32_t iHeight = pParam->height;
1793          const int32_t iEdgedWidth = pParam->edged_width;          const int32_t iEdgedWidth = pParam->edged_width;
# Line 1807  Line 1809 
1809    
1810          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);          const   int32_t iSubBlock = ((y&1)<<1) + (x&1);
1811    
1812          MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;          const MACROBLOCK * const pMB = pMBs + (x>>1) + (y>>1) * iWcount;
1813            const MACROBLOCK * const prevMB = prevMBs + (x>>1) + (y>>1) * iWcount;
1814    
1815          int32_t bPredEq;          int32_t bPredEq;
1816          int32_t iMinSAD,iSAD=9999;          int32_t iMinSAD,iSAD=9999;
# Line 1970  Line 1973 
1973          return iMinSAD;          return iMinSAD;
1974  }  }
1975    
1976    
1977    
1978    
1979    
1980    /* ***********************************************************
1981            bvop motion estimation
1982    // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
1983    ***************************************************************/
1984    
1985    /*
1986    void MotionEstimationBVOP(
1987                            MBParam * const pParam,
1988                            FRAMEINFO * const frame,
1989    
1990                            // forward (past) reference
1991                            const MACROBLOCK * const f_mbs,
1992                        const IMAGE * const f_ref,
1993                            const IMAGE * const f_refH,
1994                        const IMAGE * const f_refV,
1995                            const IMAGE * const f_refHV,
1996                            // backward (future) reference
1997                            const MACROBLOCK * const b_mbs,
1998                        const IMAGE * const b_ref,
1999                            const IMAGE * const b_refH,
2000                        const IMAGE * const b_refV,
2001                            const IMAGE * const b_refHV)
2002    {
2003        const uint32_t mb_width = pParam->mb_width;
2004        const uint32_t mb_height = pParam->mb_height;
2005            const int32_t edged_width = pParam->edged_width;
2006    
2007            int32_t i,j;
2008    
2009            int32_t f_sad16;
2010            int32_t b_sad16;
2011            int32_t i_sad16;
2012            int32_t d_sad16;
2013            int32_t best_sad;
2014    
2015            VECTOR pmv_dontcare;
2016    
2017            // note: i==horizontal, j==vertical
2018        for (j = 0; j < mb_height; j++)
2019            {
2020                    for (i = 0; i < mb_width; i++)
2021                    {
2022                            MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
2023                            const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
2024                            const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
2025    
2026                            if (b_mb->mode == MODE_INTER
2027                                    && b_mb->cbp == 0
2028                                    && b_mb->mvs[0].x == 0
2029                                    && b_mb->mvs[0].y == 0)
2030                            {
2031                                    mb->mode = MB_IGNORE;
2032                                    mb->mvs[0].x = 0;
2033                                    mb->mvs[0].y = 0;
2034                                    mb->b_mvs[0].x = 0;
2035                                    mb->b_mvs[0].y = 0;
2036                                    continue;
2037                            }
2038    
2039    
2040                            // forward search
2041                            f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2042                                                    &frame->image,
2043                                                    i, j,
2044                                                    frame->motion_flags,  frame->quant, frame->fcode,
2045                                                    pParam,
2046                                                    f_mbs,
2047                                                    &mb->mvs[0], &pmv_dontcare);    // ignore pmv
2048    
2049                            // backward search
2050                            b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2051                                                    &frame->image,
2052                                                    i, j,
2053                                                    frame->motion_flags,  frame->quant, frame->bcode,
2054                                                    pParam,
2055                                                    b_mbs,
2056                                                    &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
2057    
2058                            // interpolate search (simple, but effective)
2059                            i_sad16 = sad16bi_c(
2060                                            frame->image.y + i*16 + j*16*edged_width,
2061                                            get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
2062                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),
2063                                            get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
2064                                                    i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),
2065                                            edged_width);
2066    
2067                            // TODO: direct search
2068                            // predictor + range of [-32,32]
2069                            d_sad16 = 65535;
2070    
2071    
2072                            if (f_sad16 < b_sad16)
2073                            {
2074                                    best_sad = f_sad16;
2075                                    mb->mode = MB_FORWARD;
2076                            }
2077                            else
2078                            {
2079                                    best_sad = b_sad16;
2080                                    mb->mode = MB_BACKWARD;
2081                            }
2082    
2083                            if (i_sad16 < best_sad)
2084                            {
2085                                    best_sad = i_sad16;
2086                                    mb->mode = MB_INTERPOLATE;
2087                            }
2088    
2089                            if (d_sad16 < best_sad)
2090                            {
2091                                    best_sad = d_sad16;
2092                                    mb->mode = MB_DIRECT;
2093                            }
2094    
2095                    }
2096            }
2097    }
2098    
2099    */

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

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