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

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

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

revision 1134, Thu Aug 28 11:17:29 2003 UTC revision 1135, Fri Aug 29 13:47:21 2003 UTC
# Line 21  Line 21 
21   *  along with this program ; if not, write to the Free Software   *  along with this program ; if not, write to the Free Software
22   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23   *   *
24   * $Id: motion_est.c,v 1.58.2.31 2003-08-28 11:17:29 syskin Exp $   * $Id: motion_est.c,v 1.58.2.32 2003-08-29 13:47:21 syskin Exp $
25   *   *
26   ****************************************************************************/   ****************************************************************************/
27    
# Line 487  Line 487 
487          if ( (x > data->max_dx) || (x < data->min_dx)          if ( (x > data->max_dx) || (x < data->min_dx)
488                  || (y > data->max_dy) || (y < data->min_dy) ) return;                  || (y > data->max_dy) || (y < data->min_dy) ) return;
489    
490          sad = sad32v_c(data->Cur, data->RefP[0] + (x>>1) + (y>>1)*((int)data->iEdgedWidth),          sad = sad32v_c(data->Cur, data->RefP[0] + x + y*((int)data->iEdgedWidth),
491                                          data->iEdgedWidth, data->temp);                                          data->iEdgedWidth, data->temp);
492    
493          if (sad < *(data->iMinSAD)) {          if (sad < *(data->iMinSAD)) {
# Line 1671  Line 1671 
1671                          SearchData * const Data)                          SearchData * const Data)
1672  {  {
1673    
1674          int i, mask;          int i;
1675          VECTOR pmv[7];          VECTOR pmv[7];
1676          MainSearchFunc *MainSearchPtr;          MainSearchFunc *MainSearchPtr;
1677          *Data->iMinSAD = MV_MAX_ERROR;          *Data->iMinSAD = MV_MAX_ERROR;
# Line 1707  Line 1707 
1707          else if (MotionFlags & XVID_ME_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;          else if (MotionFlags & XVID_ME_ADVANCEDDIAMOND16) MainSearchPtr = AdvDiamondSearch;
1708                  else MainSearchPtr = DiamondSearch;                  else MainSearchPtr = DiamondSearch;
1709    
1710          mask = make_mask(pmv, 7, *Data->dir);          if (*Data->iMinSAD > 512) {
1711                    unsigned int mask = make_mask(pmv, 7, *Data->dir);
1712          MainSearchPtr(Data->currentMV->x, Data->currentMV->y, Data, mask, CheckCandidate16no4v);          MainSearchPtr(Data->currentMV->x, Data->currentMV->y, Data, mask, CheckCandidate16no4v);
1713            }
1714    
1715          SubpelRefine(Data, CheckCandidate16no4v);          SubpelRefine(Data, CheckCandidate16no4v);
1716    
# Line 1759  Line 1760 
1760  {  {
1761          int dx = 0, dy = 0, b_dx = 0, b_dy = 0;          int dx = 0, dy = 0, b_dx = 0, b_dy = 0;
1762          int32_t sum;          int32_t sum;
         const int div = 1 + Data->qpel;  
1763          int k;          int k;
1764          const uint32_t stride = Data->iEdgedWidth/2;          const uint32_t stride = Data->iEdgedWidth/2;
1765          /* 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 */
1766    
1767          for (k = 0; k < 4; k++) {          for (k = 0; k < 4; k++) {
1768                  dy += Data->directmvF[k].y / div;                  dy += Data->directmvF[k].y >> Data->qpel;
1769                  dx += Data->directmvF[k].x / div;                  dx += Data->directmvF[k].x >> Data->qpel;
1770                  b_dy += Data->directmvB[k].y / div;                  b_dy += Data->directmvB[k].y >> Data->qpel;
1771                  b_dx += Data->directmvB[k].x / div;                  b_dx += Data->directmvB[k].x >> Data->qpel;
1772          }          }
1773    
1774          dy = (dy >> 3) + roundtab_76[dy & 0xf];          dy = (dy >> 3) + roundtab_76[dy & 0xf];
# Line 1781  Line 1781 
1781                                          b_Ref->u + (y*8 + b_dy/2) * stride + x*8 + b_dx/2,                                          b_Ref->u + (y*8 + b_dy/2) * stride + x*8 + b_dx/2,
1782                                          stride);                                          stride);
1783    
1784          if (sum >= MAX_CHROMA_SAD_FOR_SKIP * pMB->quant) return; /* no skip */          if (sum >= MAX_CHROMA_SAD_FOR_SKIP * Data->iQuant) return; /* no skip */
1785    
1786          sum += sad8bi(pCur->v + 8*x + 8 * y * stride,          sum += sad8bi(pCur->v + 8*x + 8 * y * stride,
1787                                          f_Ref->v + (y*8 + dy/2) * stride + x*8 + dx/2,                                          f_Ref->v + (y*8 + dy/2) * stride + x*8 + dx/2,
1788                                          b_Ref->v + (y*8 + b_dy/2) * stride + x*8 + b_dx/2,                                          b_Ref->v + (y*8 + b_dy/2) * stride + x*8 + b_dx/2,
1789                                          stride);                                          stride);
1790    
1791          if (sum < MAX_CHROMA_SAD_FOR_SKIP * pMB->quant) {          if (sum < MAX_CHROMA_SAD_FOR_SKIP * Data->iQuant) {
1792                  pMB->mode = MODE_DIRECT_NONE_MV; /* skipped */                  pMB->mode = MODE_DIRECT_NONE_MV; /* skipped */
1793                  for (k = 0; k < 4; k++) {                  for (k = 0; k < 4; k++) {
1794                          pMB->qmvs[k] = pMB->mvs[k];                          pMB->qmvs[k] = pMB->mvs[k];
# Line 1873  Line 1873 
1873          CheckCandidate(0, 0, Data, 255);          CheckCandidate(0, 0, Data, 255);
1874    
1875          /* initial (fast) skip decision */          /* initial (fast) skip decision */
1876          if (*Data->iMinSAD < pMB->quant * INITIAL_SKIP_THRESH * (Data->chroma?3:2)) {          if (*Data->iMinSAD < Data->iQuant * INITIAL_SKIP_THRESH * (Data->chroma?3:2)) {
1877                  /* possible skip */                  /* possible skip */
1878                  if (Data->chroma) {                  if (Data->chroma) {
1879                          pMB->mode = MODE_DIRECT_NONE_MV;                          pMB->mode = MODE_DIRECT_NONE_MV;
# Line 2102  Line 2102 
2102          Data.iEdgedWidth = pParam->edged_width;          Data.iEdgedWidth = pParam->edged_width;
2103          Data.currentMV = currentMV; Data.currentQMV = currentQMV;          Data.currentMV = currentMV; Data.currentQMV = currentQMV;
2104          Data.iMinSAD = &iMinSAD;          Data.iMinSAD = &iMinSAD;
2105          Data.lambda16 = lambda_vec16[frame->quant];          Data.lambda16 = lambda_vec16[MAX(frame->quant-2, 2)];
2106          Data.qpel = pParam->vol_flags & XVID_VOL_QUARTERPEL ? 1 : 0;          Data.qpel = pParam->vol_flags & XVID_VOL_QUARTERPEL ? 1 : 0;
2107          Data.rounding = 0;          Data.rounding = 0;
2108          Data.chroma = frame->motion_flags & XVID_ME_CHROMA_BVOP;          Data.chroma = frame->motion_flags & XVID_ME_CHROMA_BVOP;
2109          Data.temp = temp;          Data.temp = temp;
2110          Data.dir = &dir;          Data.dir = &dir;
2111            Data.iQuant = frame->quant;
2112    
2113          Data.RefQ = f_refV->u; /* a good place, also used in MC (for similar purpose) */          Data.RefQ = f_refV->u; /* a good place, also used in MC (for similar purpose) */
2114    
# Line 2130  Line 2131 
2131                          Data.Cur = frame->image.y + (j * Data.iEdgedWidth + i) * 16;                          Data.Cur = frame->image.y + (j * Data.iEdgedWidth + i) * 16;
2132                          Data.CurU = frame->image.u + (j * Data.iEdgedWidth/2 + i) * 8;                          Data.CurU = frame->image.u + (j * Data.iEdgedWidth/2 + i) * 8;
2133                          Data.CurV = frame->image.v + (j * Data.iEdgedWidth/2 + i) * 8;                          Data.CurV = frame->image.v + (j * Data.iEdgedWidth/2 + i) * 8;
                         pMB->quant = frame->quant;  
2134    
2135  /* direct search comes first, because it (1) checks for SKIP-mode  /* direct search comes first, because it (1) checks for SKIP-mode
2136          and (2) sets very good predictions for forward and backward search */          and (2) sets very good predictions for forward and backward search */
# Line 2176  Line 2176 
2176                                                  &Data);                                                  &Data);
2177    
2178                          /* final skip decision */                          /* final skip decision */
2179                          if ( (skip_sad < frame->quant * MAX_SAD00_FOR_SKIP * 2)                          if ( (skip_sad < Data.iQuant * MAX_SAD00_FOR_SKIP * 2)
2180                                          && ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) )                                          && ((100*best_sad)/(skip_sad+1) > FINAL_SKIP_THRESH) )
2181                                  SkipDecisionB(&frame->image, f_ref, b_ref, pMB, i, j, &Data);                                  SkipDecisionB(&frame->image, f_ref, b_ref, pMB, i, j, &Data);
2182    
# Line 2218  Line 2218 
2218          VECTOR pmv[3];          VECTOR pmv[3];
2219          MACROBLOCK * const pMB = &pMBs[x + y * pParam->mb_width];          MACROBLOCK * const pMB = &pMBs[x + y * pParam->mb_width];
2220    
2221            unsigned int simplicity = 0;
2222    
2223          for (i = 0; i < 5; i++) Data->iMinSAD[i] = MV_MAX_ERROR;          for (i = 0; i < 5; i++) Data->iMinSAD[i] = MV_MAX_ERROR;
2224    
2225            get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,
2226                            pParam->width, pParam->height, Data->iFcode - Data->qpel - 1, 0, 0);
2227    
2228            Data->Cur = pCur + (x + y * pParam->edged_width) * 16;
2229            Data->RefP[0] = pRef + (x + y * pParam->edged_width) * 16;
2230    
2231            pmv[0].x = pMB->mvs[0].x;
2232            pmv[0].y = pMB->mvs[0].y;
2233    
2234            CheckCandidate32I(pmv[0].x, pmv[0].y, Data, 0);
2235    
2236            if (*Data->iMinSAD > 200) {
2237    
2238                    pmv[1].x = pmv[1].y = 0;
2239    
2240          /* median is only used as prediction. it doesn't have to be real */          /* median is only used as prediction. it doesn't have to be real */
2241          if (x == 1 && y == 1) Data->predMV.x = Data->predMV.y = 0;          if (x == 1 && y == 1) Data->predMV.x = Data->predMV.y = 0;
2242          else          else
# Line 2229  Line 2246 
2246                          Data->predMV = (pMB - 1)->mvs[0]; /* left instead of median */                          Data->predMV = (pMB - 1)->mvs[0]; /* left instead of median */
2247                          else Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0); /* else median */                          else Data->predMV = get_pmv2(pMBs, pParam->mb_width, 0, x, y, 0); /* else median */
2248    
2249          get_range(&Data->min_dx, &Data->max_dx, &Data->min_dy, &Data->max_dy, x, y, 4,                  pmv[2].x = Data->predMV.x;
2250                          pParam->width, pParam->height, Data->iFcode - Data->qpel, 1, 0);                  pmv[2].y = Data->predMV.y;
   
         Data->Cur = pCur + (x + y * pParam->edged_width) * 16;  
         Data->RefP[0] = pRef + (x + y * pParam->edged_width) * 16;  
   
         pmv[1].x = EVEN(pMB->mvs[0].x);  
         pmv[1].y = EVEN(pMB->mvs[0].y);  
         pmv[2].x = EVEN(Data->predMV.x);  
         pmv[2].y = EVEN(Data->predMV.y);  
         pmv[0].x = pmv[0].y = 0;  
   
         CheckCandidate32I(0, 0, Data, 0);  
   
         if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP) {  
2251    
2252                  if (!vector_repeats(pmv, 1))                  if (!vector_repeats(pmv, 1))
2253                          CheckCandidate32I(pmv[1].x, pmv[1].y, Data, 1);                          CheckCandidate32I(pmv[1].x, pmv[1].y, Data, 1);
2254                  if (!vector_repeats(pmv, 2))                  if (!vector_repeats(pmv, 2))
2255                          CheckCandidate32I(pmv[2].x, pmv[2].y, Data, 2);                          CheckCandidate32I(pmv[2].x, pmv[2].y, Data, 2);
2256    
2257                  if (*Data->iMinSAD > 4 * MAX_SAD00_FOR_SKIP) { /* diamond only if needed */                  if (*Data->iMinSAD > 500) { /* diamond only if needed */
2258                          unsigned int mask = make_mask(pmv, 3, *Data->dir);                          unsigned int mask = make_mask(pmv, 3, *Data->dir);
2259                          DiamondSearch(Data->currentMV->x, Data->currentMV->y, Data, mask, CheckCandidate32I);                          DiamondSearch(Data->currentMV->x, Data->currentMV->y, Data, mask, CheckCandidate32I);
2260                  }                  } else simplicity++;
2261          }  
2262                    if (*Data->iMinSAD > 500) /* refinement from 2-pixel to 1-pixel */
2263                            SubpelRefine(Data, CheckCandidate32I);
2264                    else simplicity++;
2265            } else simplicity++;
2266    
2267          for (i = 0; i < 4; i++) {          for (i = 0; i < 4; i++) {
2268                  MACROBLOCK * MB = &pMBs[x + (i&1) + (y+(i>>1)) * pParam->mb_width];                  MACROBLOCK * MB = &pMBs[x + (i&1) + (y+(i>>1)) * pParam->mb_width];
2269                  MB->mvs[0] = MB->mvs[1] = MB->mvs[2] = MB->mvs[3] = Data->currentMV[i];                  MB->mvs[0] = MB->mvs[1] = MB->mvs[2] = MB->mvs[3] = Data->currentMV[i];
2270                  MB->mode = MODE_INTER;                  MB->mode = MODE_INTER;
2271                  MB->sad16 = Data->iMinSAD[i+1];                  /* if we skipped some search steps, we have to assume that SAD would be lower with them */
2272                    MB->sad16 = Data->iMinSAD[i+1] - (simplicity<<7);
2273          }          }
2274  }  }
2275    
2276  #define INTRA_THRESH    2200  #define INTRA_THRESH    2200
2277  #define INTER_THRESH    50  #define INTER_THRESH    40
2278  #define INTRA_THRESH2   95  #define INTRA_THRESH2   95
2279    
2280  int  int
# Line 2296  Line 2305 
2305          Data.temp = temp;          Data.temp = temp;
2306          Data.dir = &dir;          Data.dir = &dir;
2307          Data.qpel = (pParam->vol_flags & XVID_VOL_QUARTERPEL)? 1: 0;          Data.qpel = (pParam->vol_flags & XVID_VOL_QUARTERPEL)? 1: 0;
2308            Data.qpel_precision = 0;
2309    
2310          if (intraCount != 0) {          if (intraCount != 0) {
2311                  if (intraCount < 10) // we're right after an I frame                  if (intraCount < 10) // we're right after an I frame
# Line 2305  Line 2315 
2315                                  IntraThresh -= (IntraThresh * (maxIntra - 8*(maxIntra - intraCount)))/maxIntra;                                  IntraThresh -= (IntraThresh * (maxIntra - 8*(maxIntra - intraCount)))/maxIntra;
2316          }          }
2317    
2318          InterThresh -= 12 * bCount;          InterThresh -= 20 * bCount;
2319          if (InterThresh < 15 + b_thresh) InterThresh = 15 + b_thresh;          if (InterThresh < 10 + b_thresh) InterThresh = 10 + b_thresh;
2320    
2321          if (sadInit) (*sadInit) ();          if (sadInit) (*sadInit) ();
2322    
# Line 2338  Line 2348 
2348                                  }                                  }
2349    
2350                                  if (pMB->mvs[0].x == 0 && pMB->mvs[0].y == 0)                                  if (pMB->mvs[0].x == 0 && pMB->mvs[0].y == 0)
2351                                          if (dev > 500 && pMB->sad16 < 1000)                                          if (dev > 1000 && pMB->sad16 < 1000)
2352                                                  sSAD += 1000;                                                  sSAD += 1000;
2353    
2354                                  sSAD += (dev < 3000) ? pMB->sad16 : pMB->sad16/2; /* blocks with big contrast differences usually have large SAD - while they look very good in b-frames */                                  sSAD += (dev < 4000) ? pMB->sad16 : pMB->sad16/2; /* blocks with big contrast differences usually have large SAD - while they look very good in b-frames */
2355                          }                          }
2356                  }                  }
2357          }          }

Legend:
Removed from v.1134  
changed lines
  Added in v.1135

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