[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 132, Tue Apr 23 00:04:51 2002 UTC
# Line 2  Line 2 
2   *   *
3   *  Modifications:   *  Modifications:
4   *   *
5     *  22.04.2002 remove some compile warning by chenm001 <chenm001@163.com>
6     *  14.04.2002 added MotionEstimationBVOP()
7   *  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
8   *             EPZS and EPZS^2   *             EPZS and EPZS^2
9   *  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 42 
42  #include "../prediction/mbprediction.h"  #include "../prediction/mbprediction.h"
43  #include "../global.h"  #include "../global.h"
44  #include "../utils/timer.h"  #include "../utils/timer.h"
45    #include "motion.h"
46  #include "sad.h"  #include "sad.h"
47    
48  // very large value  // very large value
# Line 68  Line 71 
71  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)  #define EVEN(A)         (((A)<0?(A)+1:(A)) & ~1)
72    
73    
 #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)  
   
74  int32_t PMVfastSearch16(  int32_t PMVfastSearch16(
75                                          const uint8_t * const pRef,                                          const uint8_t * const pRef,
76                                          const uint8_t * const pRefH,                                          const uint8_t * const pRefH,
# Line 221  Line 219 
219    
220    
221    
 /* 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;  
         }  
   
 }  
222    
223  #ifndef SEARCH16  #ifndef SEARCH16
224  #define SEARCH16        PMVfastSearch16  #define SEARCH16        PMVfastSearch16
# Line 340  Line 254 
254          int32_t sad16;          int32_t sad16;
255          int32_t deviation;          int32_t deviation;
256    
257          if (sadInit);          if (sadInit)
258                  (*sadInit)();                  (*sadInit)();
259    
260          // note: i==horizontal, j==vertical          // note: i==horizontal, j==vertical
# Line 993  Line 907 
907                           iEdgedWidth, MV_MAX_ERROR);                           iEdgedWidth, MV_MAX_ERROR);
908          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;
909    
910          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )
911          {          {
912    
913                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
# Line 1036  Line 950 
950                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
951    
952  // top right neighbour, if allowed  // top right neighbour, if allowed
953                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
954                  {                  {
955                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
956                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1050  Line 964 
964     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.
965  */  */
966    
967          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD < pMB->sad16) ) )
968          {          {
969                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
970                          goto PMVfast16_Terminate_without_Refine;                          goto PMVfast16_Terminate_without_Refine;
# Line 1344  Line 1258 
1258                          iEdgedWidth);                          iEdgedWidth);
1259          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;
1260    
1261          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD < 256/4 ) || ( (MVequal(*currMV,pMB->mvs[iSubBlock])) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )
1262          {          {
1263                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1264                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1403  Line 1317 
1317     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.
1318  */  */
1319    
1320          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && (iMinSAD < pMB->sad8[iSubBlock]) ) )          if ( (iMinSAD <= threshA) || ( MVequal(*currMV,pMB->mvs[iSubBlock]) && ((uint32_t)iMinSAD < pMB->sad8[iSubBlock]) ) )
1321          {          {
1322                  if (MotionFlags & PMV_QUICKSTOP16)                  if (MotionFlags & PMV_QUICKSTOP16)
1323                          goto PMVfast8_Terminate_without_Refine;                          goto PMVfast8_Terminate_without_Refine;
# Line 1584  Line 1498 
1498          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;
1499    
1500  // thresh1 is fixed to 256  // thresh1 is fixed to 256
1501          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && (iMinSAD < pMB->sad16) ) )          if ( (iMinSAD < 256 ) || ( (MVequal(*currMV,pMB->mvs[0])) && ((uint32_t)iMinSAD < pMB->sad16) ) )
1502                  {                  {
1503                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1504                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1636  Line 1550 
1550                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);                  CHECK_MV16_CANDIDATE(pmv[2].x,pmv[2].y);
1551    
1552  // top right neighbour, if allowed  // top right neighbour, if allowed
1553                  if (x != (iWcount-1))                  if ((uint32_t)x != (iWcount-1))
1554                  {                  {
1555                          if (!(MotionFlags & PMV_HALFPEL16 ))                          if (!(MotionFlags & PMV_HALFPEL16 ))
1556                          {       pmv[3].x = EVEN(pmv[3].x);                          {       pmv[3].x = EVEN(pmv[3].x);
# Line 1651  Line 1565 
1565  */  */
1566    
1567          if ( (iMinSAD <= thresh2)          if ( (iMinSAD <= thresh2)
1568                  || ( MVequal(*currMV,pMB->mvs[0]) && (iMinSAD <= pMB->sad16) ) )                  || ( MVequal(*currMV,pMB->mvs[0]) && ((uint32_t)iMinSAD <= pMB->sad16) ) )
1569                  {                  {
1570                          if (MotionFlags & PMV_QUICKSTOP16)                          if (MotionFlags & PMV_QUICKSTOP16)
1571                                  goto EPZS16_Terminate_without_Refine;                                  goto EPZS16_Terminate_without_Refine;
# Line 1677  Line 1591 
1591    
1592  // 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
1593    
1594          if (x != iWcount-1)          if ((uint32_t)x != iWcount-1)
1595                  CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((pMB+1)->mvs[0].x,oldMB->mvs[0].y);
1596    
1597  // bottom neighbour, dito  // bottom neighbour, dito
1598          if (y != iHcount-1)          if ((uint32_t)y != iHcount-1)
1599                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);                  CHECK_MV16_CANDIDATE((pMB+iWcount)->mvs[0].x,oldMB->mvs[0].y);
1600    
1601  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */  /* Terminate if MinSAD <= T_3 (here T_3 = T_2)  */
# Line 1970  Line 1884 
1884          return iMinSAD;          return iMinSAD;
1885  }  }
1886    
1887    
1888    
1889    
1890    
1891    /* ***********************************************************
1892            bvop motion estimation
1893    // TODO: need to incorporate prediction here (eg. sad += calc_delta_16)
1894    ***************************************************************/
1895    
1896    /*
1897    void MotionEstimationBVOP(
1898                            MBParam * const pParam,
1899                            FRAMEINFO * const frame,
1900    
1901                            // forward (past) reference
1902                            const MACROBLOCK * const f_mbs,
1903                        const IMAGE * const f_ref,
1904                            const IMAGE * const f_refH,
1905                        const IMAGE * const f_refV,
1906                            const IMAGE * const f_refHV,
1907                            // backward (future) reference
1908                            const MACROBLOCK * const b_mbs,
1909                        const IMAGE * const b_ref,
1910                            const IMAGE * const b_refH,
1911                        const IMAGE * const b_refV,
1912                            const IMAGE * const b_refHV)
1913    {
1914        const uint32_t mb_width = pParam->mb_width;
1915        const uint32_t mb_height = pParam->mb_height;
1916            const int32_t edged_width = pParam->edged_width;
1917    
1918            int32_t i,j;
1919    
1920            int32_t f_sad16;
1921            int32_t b_sad16;
1922            int32_t i_sad16;
1923            int32_t d_sad16;
1924            int32_t best_sad;
1925    
1926            VECTOR pmv_dontcare;
1927    
1928            // note: i==horizontal, j==vertical
1929        for (j = 0; j < mb_height; j++)
1930            {
1931                    for (i = 0; i < mb_width; i++)
1932                    {
1933                            MACROBLOCK *mb = &frame->mbs[i + j*mb_width];
1934                            const MACROBLOCK *f_mb = &f_mbs[i + j*mb_width];
1935                            const MACROBLOCK *b_mb = &b_mbs[i + j*mb_width];
1936    
1937                            if (b_mb->mode == MODE_INTER
1938                                    && b_mb->cbp == 0
1939                                    && b_mb->mvs[0].x == 0
1940                                    && b_mb->mvs[0].y == 0)
1941                            {
1942                                    mb->mode = MB_IGNORE;
1943                                    mb->mvs[0].x = 0;
1944                                    mb->mvs[0].y = 0;
1945                                    mb->b_mvs[0].x = 0;
1946                                    mb->b_mvs[0].y = 0;
1947                                    continue;
1948                            }
1949    
1950    
1951                            // forward search
1952                            f_sad16 = SEARCH16(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
1953                                                    &frame->image,
1954                                                    i, j,
1955                                                    frame->motion_flags,  frame->quant, frame->fcode,
1956                                                    pParam,
1957                                                    f_mbs,
1958                                                    &mb->mvs[0], &pmv_dontcare);    // ignore pmv
1959    
1960                            // backward search
1961                            b_sad16 = SEARCH16(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
1962                                                    &frame->image,
1963                                                    i, j,
1964                                                    frame->motion_flags,  frame->quant, frame->bcode,
1965                                                    pParam,
1966                                                    b_mbs,
1967                                                    &mb->b_mvs[0], &pmv_dontcare);  // ignore pmv
1968    
1969                            // interpolate search (simple, but effective)
1970                            i_sad16 = sad16bi_c(
1971                                            frame->image.y + i*16 + j*16*edged_width,
1972                                            get_ref(f_ref->y, f_refH->y, f_refV->y, f_refHV->y,
1973                                                    i, j, 16, mb->mvs[0].x, mb->mvs[0].y, edged_width),
1974                                            get_ref(b_ref->y, b_refH->y, b_refV->y, b_refHV->y,
1975                                                    i, j, 16, mb->b_mvs[0].x, mb->b_mvs[0].x, edged_width),
1976                                            edged_width);
1977    
1978                            // TODO: direct search
1979                            // predictor + range of [-32,32]
1980                            d_sad16 = 65535;
1981    
1982    
1983                            if (f_sad16 < b_sad16)
1984                            {
1985                                    best_sad = f_sad16;
1986                                    mb->mode = MB_FORWARD;
1987                            }
1988                            else
1989                            {
1990                                    best_sad = b_sad16;
1991                                    mb->mode = MB_BACKWARD;
1992                            }
1993    
1994                            if (i_sad16 < best_sad)
1995                            {
1996                                    best_sad = i_sad16;
1997                                    mb->mode = MB_INTERPOLATE;
1998                            }
1999    
2000                            if (d_sad16 < best_sad)
2001                            {
2002                                    best_sad = d_sad16;
2003                                    mb->mode = MB_DIRECT;
2004                            }
2005    
2006                    }
2007            }
2008    }
2009    
2010    */

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

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