[svn] / branches / dev-api-3 / xvidcore / src / motion / motion_est.c Repository:
ViewVC logotype

Diff of /branches/dev-api-3/xvidcore/src/motion/motion_est.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 580, Sat Oct 5 21:39:39 2002 UTC revision 594, Sat Oct 12 13:56:16 2002 UTC
# Line 95  Line 95 
95  static void  static void
96  CheckCandidate16(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)  CheckCandidate16(const int x, const int y, const int Direction, int * const dir, const SearchData * const data)
97  {  {
         int32_t * const sad = data->temp;  
98          int t;          int t;
99          const uint8_t * Reference;          const uint8_t * Reference;
100    
# Line 109  Line 108 
108                  default : Reference = data->RefHV + (x-1)/2 + ((y-1)/2)*(data->iEdgedWidth); break;                  default : Reference = data->RefHV + (x-1)/2 + ((y-1)/2)*(data->iEdgedWidth); break;
109          }          }
110    
111          data->temp[0] = sad16v(data->Cur, Reference, data->iEdgedWidth, sad+1);          data->temp[0] = sad16v(data->Cur, Reference, data->iEdgedWidth, data->temp + 1);
112    
113          t = d_mv_bits(x - data->predMV.x, y - data->predMV.y, data->iFcode);          t = d_mv_bits(x - data->predMV.x, y - data->predMV.y, data->iFcode);
114          data->temp[0] += lambda_vec16[data->iQuant] * t;          data->temp[0] += lambda_vec16[data->iQuant] * t;
# Line 165  Line 164 
164  // Important: This is no general usable routine! x and y must be +/-1 (qpel resolution!)  // Important: This is no general usable routine! x and y must be +/-1 (qpel resolution!)
165  // around currentMV!  // around currentMV!
166  {  {
         int32_t * const sad = data->temp;  
167          int t;          int t;
168          uint8_t * Reference = (uint8_t *) data->RefQ;          uint8_t * Reference = (uint8_t *) data->RefQ;
169          const uint8_t *ref1, *ref2, *ref3, *ref4;          const uint8_t *ref1, *ref2, *ref3, *ref4;
# Line 217  Line 215 
215                  break;                  break;
216          }          }
217    
218          data->temp[0] = sad16v(data->Cur, Reference, data->iEdgedWidth, sad+1);          data->temp[0] = sad16v(data->Cur, Reference, data->iEdgedWidth, data->temp+1);
219    
220          t = d_mv_bits(x - data->predQMV.x, y - data->predQMV.y, data->iFcode);          t = d_mv_bits(x - data->predQMV.x, y - data->predQMV.y, data->iFcode);
221          data->temp[0] += lambda_vec16[data->iQuant] * t;          data->temp[0] += lambda_vec16[data->iQuant] * t;
# Line 226  Line 224 
224          if (data->temp[0] < data->iMinSAD[0]) {          if (data->temp[0] < data->iMinSAD[0]) {
225                  data->iMinSAD[0] = data->temp[0];                  data->iMinSAD[0] = data->temp[0];
226                  data->currentQMV[0].x = x; data->currentQMV[0].y = y;                  data->currentQMV[0].x = x; data->currentQMV[0].y = y;
227                  *dir = Direction; }          /*      *dir = Direction;*/ }
228    
229          if (data->temp[1] < data->iMinSAD[1]) {          if (data->temp[1] < data->iMinSAD[1]) {
230                  data->iMinSAD[1] = data->temp[1]; data->currentQMV[1].x = x; data->currentQMV[1].y = y; }                  data->iMinSAD[1] = data->temp[1]; data->currentQMV[1].x = x; data->currentQMV[1].y = y; }
# Line 303  Line 301 
301          if (sad < *(data->iMinSAD)) {          if (sad < *(data->iMinSAD)) {
302                  *(data->iMinSAD) = sad;                  *(data->iMinSAD) = sad;
303                  data->currentQMV[0].x = x; data->currentQMV[0].y = y;                  data->currentQMV[0].x = x; data->currentQMV[0].y = y;
304                  *dir = Direction;  //              *dir = Direction;
305          }          }
306  }  }
307    
# Line 812  Line 810 
810          Data.rounding = pParam->m_rounding_type;          Data.rounding = pParam->m_rounding_type;
811    
812          if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL)          if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL)
813                  return 0; // allocate some mem for qpel interpolated blocks                  return 1; // allocate some mem for qpel interpolated blocks
814                                    // somehow this is dirty since I think we shouldn't use malloc outside                                    // somehow this is dirty since I think we shouldn't use malloc outside
815                                    // encoder_create() - so please fix me!                                    // encoder_create() - so please fix me!
816    
# Line 1085  Line 1083 
1083                  else                  else
1084                          CheckCandidate = CheckCandidate16no4v_qpel;                          CheckCandidate = CheckCandidate16no4v_qpel;
1085    
1086                            Data->iMinSAD[0] -= lambda_vec16[iQuant] *
1087                                    d_mv_bits(Data->predMV.x - Data->currentMV[0].x, Data->predMV.y - Data->currentMV[0].y, Data->iFcode);
1088                            Data->iMinSAD[1] -= lambda_vec8[iQuant] *
1089                                    d_mv_bits(Data->predMV.x - Data->currentMV[1].x, Data->predMV.y - Data->currentMV[1].y, Data->iFcode);
1090    
1091                            Data->iMinSAD[0] += lambda_vec16[iQuant] *
1092                                    d_mv_bits(Data->predQMV.x - Data->currentQMV[0].x, Data->predMV.y - Data->currentQMV[0].y, Data->iFcode);
1093                            Data->iMinSAD[1] += lambda_vec8[iQuant] *
1094                                    d_mv_bits(Data->predQMV.x - Data->currentQMV[1].x, Data->predMV.y - Data->currentQMV[1].y, Data->iFcode);
1095    
1096                            get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 16,
1097                                    pParam->width, pParam->height, Data->iFcode, 0);
1098    
1099                  QuarterpelRefine(Data);                  QuarterpelRefine(Data);
1100          }          }
1101    
# Line 1145  Line 1156 
1156          Data->currentMV = OldData->currentMV + 1 + block;          Data->currentMV = OldData->currentMV + 1 + block;
1157          Data->currentQMV = OldData->currentQMV + 1 + block;          Data->currentQMV = OldData->currentQMV + 1 + block;
1158    
         if (block != 0) {  
1159                  if(pParam->m_quarterpel) {                  if(pParam->m_quarterpel) {
1160                          *(Data->iMinSAD) += lambda_vec8[Data->iQuant] *                  //it is qpel. substract d_mv_bits[qpel] from 0, add d_mv_bits[hpel] everywhere
1161                    if (block == 0)
1162                            *(Data->iMinSAD) -= lambda_vec8[Data->iQuant] *
1163                                                                          d_mv_bits(      Data->currentQMV->x - Data->predQMV.x,                                                                          d_mv_bits(      Data->currentQMV->x - Data->predQMV.x,
1164                                                                                                  Data->currentQMV->y - Data->predQMV.y,                                                                                                  Data->currentQMV->y - Data->predQMV.y,
1165                                                                                                  Data->iFcode);                                                                                                  Data->iFcode);
1166                  }  
                 else {  
1167                          *(Data->iMinSAD) += lambda_vec8[Data->iQuant] *                          *(Data->iMinSAD) += lambda_vec8[Data->iQuant] *
1168                                                                          d_mv_bits(      Data->currentMV->x - Data->predMV.x,                                                                          d_mv_bits(      Data->currentMV->x - Data->predMV.x,
1169                                                                                                  Data->currentMV->y - Data->predMV.y,                                                                                                  Data->currentMV->y - Data->predMV.y,
1170                                                                                                  Data->iFcode);                                                                                                  Data->iFcode);
1171                  }          } else //it is not qpel. add d_mv_bits[hpel] everywhere but not in 0 (it's already there)
1172          }                  if (block != 0) *(Data->iMinSAD) += lambda_vec8[Data->iQuant] *
1173                                                                            d_mv_bits(      Data->currentMV->x - Data->predMV.x,
1174                                                                                                    Data->currentMV->y - Data->predMV.y,
1175                                                                                                    Data->iFcode);
1176    
1177    
1178          if (MotionFlags & (PMV_EXTSEARCH8|PMV_HALFPELREFINE8)) {          if (MotionFlags & (PMV_EXTSEARCH8|PMV_HALFPELREFINE8)) {
# Line 1208  Line 1222 
1222                                  (MotionFlags & PMV_QUARTERPELREFINE8)) {                                  (MotionFlags & PMV_QUARTERPELREFINE8)) {
1223    
1224                                  CheckCandidate = CheckCandidate8_qpel;                                  CheckCandidate = CheckCandidate8_qpel;
1225                            Data->iMinSAD[0] -= lambda_vec8[Data->iQuant] *
1226                                    d_mv_bits(Data->predMV.x - Data->currentMV[0].x, Data->predMV.y - Data->currentMV[0].y, Data->iFcode);
1227    
1228                            Data->iMinSAD[0] += lambda_vec8[Data->iQuant] *
1229                                    d_mv_bits(Data->predQMV.x - Data->currentQMV[0].x, Data->predQMV.y - Data->currentQMV[0].y, Data->iFcode);
1230    
1231                                  QuarterpelRefine(Data);                                  QuarterpelRefine(Data);
1232                          }                          }
1233                  }                  }
# Line 1426  Line 1446 
1446    
1447  // skip decision  // skip decision
1448          if (*Data->iMinSAD - 2 * lambda_vec16[Data->iQuant] < (int32_t)Data->iQuant * SKIP_THRESH_B) {          if (*Data->iMinSAD - 2 * lambda_vec16[Data->iQuant] < (int32_t)Data->iQuant * SKIP_THRESH_B) {
1449                  //checking chroma. everything copied from MC                  //possible skip - checking chroma. everything copied from MC
1450                  //this is not full chroma compensation, only it's fullpel approximation. should work though                  //this is not full chroma compensation, only it's fullpel approximation. should work though
1451                  int sum, dx, dy, b_dx, b_dy;                  int sum, dx, dy, b_dx, b_dy;
1452    
# Line 1736  Line 1756 
1756    
1757  /* Hinted ME starts here */  /* Hinted ME starts here */
1758    
1759  static __inline void  static void
1760  Search8hinted(  const SearchData * const OldData,  Search8hinted(  const SearchData * const OldData,
1761                                  const int x, const int y,                                  const int x, const int y,
1762                                  const uint32_t MotionFlags,                                  const uint32_t MotionFlags,
1763                                  const MBParam * const pParam,                                  const MBParam * const pParam,
1764                                  MACROBLOCK * const pMB,                                  MACROBLOCK * const pMB,
1765                                  const MACROBLOCK * const pMBs,                                  const MACROBLOCK * const pMBs,
1766                                  const int block)                  const int block,
1767                    SearchData * const Data)
1768  {  {
1769          SearchData Data;          int32_t temp_sad;
1770          MainSearchFunc *MainSearchPtr;          MainSearchFunc *MainSearchPtr;
1771            Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x/2 , y/2, block);
1772            Data->predQMV = get_qpmv2(pMBs, pParam->mb_width, 0, x/2 , y/2, block);
1773            Data->iMinSAD = OldData->iMinSAD + 1 + block;
1774            Data->currentMV = OldData->currentMV + 1 + block;
1775            Data->currentQMV = OldData->currentQMV + 1 + block;
1776    
1777          Data.predMV = get_pmv2(pMBs, pParam->mb_width, 0, x/2 , y/2, block);          if (block != 0) {
1778          Data.iMinSAD = OldData->iMinSAD + 1 + block;                  if(pParam->m_quarterpel) {
1779          Data.currentMV = OldData->currentMV+1+block;                          *(Data->iMinSAD) += lambda_vec8[Data->iQuant] *
1780          Data.iFcode = OldData->iFcode;                                                                          d_mv_bits(      Data->currentQMV->x - Data->predQMV.x,
1781          Data.iQuant = OldData->iQuant;                                                                                                  Data->currentQMV->y - Data->predQMV.y,
1782                                                                                                    Data->iFcode);
1783          Data.Ref = OldData->Ref + 8 * ((block&1) + pParam->edged_width*(block>>1));                  }
1784          Data.RefH = OldData->RefH + 8 * ((block&1) + pParam->edged_width*(block>>1));                  else {
1785          Data.RefV = OldData->RefV + 8 * ((block&1) + pParam->edged_width*(block>>1));                          *(Data->iMinSAD) += lambda_vec8[Data->iQuant] *
1786          Data.RefHV = OldData->RefHV + 8 * ((block&1) + pParam->edged_width*(block>>1));                                                                          d_mv_bits(      Data->currentMV->x - Data->predMV.x,
1787          Data.iEdgedWidth = pParam->edged_width;                                                                                                  Data->currentMV->y - Data->predMV.y,
1788          Data.Cur = OldData->Cur + 8 * ((block&1) + pParam->edged_width*(block>>1));                                                                                                  Data->iFcode);
1789                    }
1790            }
1791    
         CheckCandidate = CheckCandidate8;  
1792    
1793          if (block != 0)          Data->Ref = OldData->Ref + 8 * ((block&1) + pParam->edged_width*(block>>1));
1794                  *(Data.iMinSAD) += lambda_vec8[Data.iQuant] *          Data->RefH = OldData->RefH + 8 * ((block&1) + pParam->edged_width*(block>>1));
1795                                                                  d_mv_bits(      Data.currentMV->x - Data.predMV.x,          Data->RefV = OldData->RefV + 8 * ((block&1) + pParam->edged_width*(block>>1));
1796                                                                                          Data.currentMV->y - Data.predMV.y,          Data->RefHV = OldData->RefHV + 8 * ((block&1) + pParam->edged_width*(block>>1));
1797                                                                                          Data.iFcode);          Data->RefQ = OldData->RefQ;
1798    
1799            Data->Cur = OldData->Cur + 8 * ((block&1) + pParam->edged_width*(block>>1));
1800    
1801          get_range(&Data.min_dx, &Data.max_dx, &Data.min_dy, &Data.max_dy, x, y, 8,          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 8,
1802                                  pParam->width, pParam->height, OldData->iFcode, pParam->m_quarterpel);                                  pParam->width, pParam->height, OldData->iFcode, pParam->m_quarterpel);
1803    
1804          if (pMB->mode == MODE_INTER4V) {          CheckCandidate = CheckCandidate8;
1805                  int dummy;  
1806                  CheckCandidate8(pMB->mvs[block].x, pMB->mvs[block].y, 0, &dummy, &Data); }          temp_sad = *(Data->iMinSAD); // store current MinSAD
1807    
1808          if (MotionFlags & PMV_USESQUARES8) MainSearchPtr = SquareSearch;          if (MotionFlags & PMV_USESQUARES8) MainSearchPtr = SquareSearch;
1809                  else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamondSearch;                  else if (MotionFlags & PMV_ADVANCEDDIAMOND8) MainSearchPtr = AdvDiamondSearch;
1810                          else MainSearchPtr = DiamondSearch;                          else MainSearchPtr = DiamondSearch;
1811    
1812          (*MainSearchPtr)(Data.currentMV->x, Data.currentMV->y, &Data, 255);          (*MainSearchPtr)(Data->currentMV->x, Data->currentMV->y, Data, 255);
1813    
1814          if (MotionFlags & PMV_HALFPELREFINE8) HalfpelRefine(&Data);          if(*(Data->iMinSAD) < temp_sad) {
1815                    Data->currentQMV->x = 2 * Data->currentMV->x; // update our qpel vector
1816                    Data->currentQMV->y = 2 * Data->currentMV->y;
1817            }
1818    
1819            if (MotionFlags & PMV_HALFPELREFINE8) {
1820                    temp_sad = *(Data->iMinSAD); // store current MinSAD
1821    
1822          pMB->pmvs[block].x = Data.currentMV->x - Data.predMV.x;                  HalfpelRefine(Data); // perform halfpel refine of current best vector
1823          pMB->pmvs[block].y = Data.currentMV->y - Data.predMV.y;  
1824          pMB->mvs[block] = *(Data.currentMV);                  if(*(Data->iMinSAD) < temp_sad) { // we have found a better match
1825          pMB->sad8[block] =  4 * (*(Data.iMinSAD));                          Data->currentQMV->x = 2 * Data->currentMV->x; // update our qpel vector
1826                            Data->currentQMV->y = 2 * Data->currentMV->y;
1827                    }
1828            }
1829    
1830            if(pParam->m_quarterpel) {
1831                    if((!(Data->currentQMV->x & 1)) && (!(Data->currentQMV->y & 1)) &&
1832                            (MotionFlags & PMV_QUARTERPELREFINE8)) {
1833                                    CheckCandidate = CheckCandidate8_qpel;
1834                                    QuarterpelRefine(Data);
1835                    }
1836            }
1837    
1838            if(pParam->m_quarterpel) {
1839                    pMB->pmvs[block].x = Data->currentQMV->x - Data->predQMV.x;
1840                    pMB->pmvs[block].y = Data->currentQMV->y - Data->predQMV.y;
1841            }
1842            else {
1843                    pMB->pmvs[block].x = Data->currentMV->x - Data->predMV.x;
1844                    pMB->pmvs[block].y = Data->currentMV->y - Data->predMV.y;
1845            }
1846    
1847            pMB->mvs[block] = *(Data->currentMV);
1848            pMB->qmvs[block] = *(Data->currentQMV);
1849    
1850            pMB->sad8[block] =  4 * (*Data->iMinSAD);
1851  }  }
1852    
1853    
# Line 1868  Line 1927 
1927    
1928          if (MotionFlags & PMV_HALFPELREFINE16) HalfpelRefine(Data);          if (MotionFlags & PMV_HALFPELREFINE16) HalfpelRefine(Data);
1929    
1930            for(i = 0; i < 5; i++) {
1931                    Data->currentQMV[i].x = 2 * Data->currentMV[i].x; // initialize qpel vectors
1932                    Data->currentQMV[i].y = 2 * Data->currentMV[i].y;
1933            }
1934    
1935            if((pParam->m_quarterpel) && (MotionFlags & PMV_QUARTERPELREFINE16)) {
1936    
1937          if (inter4v)          if (inter4v)
1938                  for(i = 0; i < 4; i++)                          CheckCandidate = CheckCandidate16_qpel;
1939                          Search8hinted(Data, 2*x+(i&1), 2*y+(i>>1), MotionFlags, pParam, pMB, pMBs, i);                  else
1940                            CheckCandidate = CheckCandidate16no4v_qpel;
1941    
1942                    QuarterpelRefine(Data);
1943            }
1944    
1945    
1946            if (inter4v) {
1947                    SearchData Data8;
1948                    Data8.iFcode = Data->iFcode;
1949                    Data8.iQuant = Data->iQuant;
1950                    Data8.iEdgedWidth = Data->iEdgedWidth;
1951                    Search8hinted(Data, 2*x, 2*y, MotionFlags, pParam, pMB, pMBs, 0, &Data8);
1952                    Search8hinted(Data, 2*x + 1, 2*y, MotionFlags, pParam, pMB, pMBs, 1, &Data8);
1953                    Search8hinted(Data, 2*x, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 2, &Data8);
1954                    Search8hinted(Data, 2*x + 1, 2*y + 1, MotionFlags, pParam, pMB, pMBs, 3, &Data8);
1955            }
1956    
1957          if (!(inter4v) ||          if (!(inter4v) ||
1958                  (Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] + Data->iMinSAD[3] +                  (Data->iMinSAD[0] < Data->iMinSAD[1] + Data->iMinSAD[2] + Data->iMinSAD[3] +
# Line 1908  Line 1990 
1990          const IMAGE *const pRef = &reference->image;          const IMAGE *const pRef = &reference->image;
1991    
1992          uint32_t x, y;          uint32_t x, y;
1993            int8_t * qimage;
1994          int32_t temp[5], quant = current->quant;          int32_t temp[5], quant = current->quant;
1995          int32_t iMinSAD[5];          int32_t iMinSAD[5];
1996          VECTOR currentMV[5];          VECTOR currentMV[5];
# Line 1917  Line 2000 
2000          Data.iMinSAD = iMinSAD;          Data.iMinSAD = iMinSAD;
2001          Data.temp = temp;          Data.temp = temp;
2002          Data.iFcode = current->fcode;          Data.iFcode = current->fcode;
2003            Data.rounding = pParam->m_rounding_type;
2004    
2005            if((qimage = (uint8_t *) malloc(32 * pParam->edged_width)) == NULL)
2006                    return; // allocate some mem for qpel interpolated blocks
2007                                      // somehow this is dirty since I think we shouldn't use malloc outside
2008                                      // encoder_create() - so please fix me!
2009    
2010            Data.RefQ = qimage;
2011    
2012          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
2013    
# Line 1947  Line 2038 
2038    
2039                  }                  }
2040          }          }
2041            free(qimage);
2042  }  }
2043    
2044  static __inline int  static __inline int

Legend:
Removed from v.580  
changed lines
  Added in v.594

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